Monter un point d'accès Wifi sécurisé via authpf

Cette documentation est le résultat d'une installation que j'ai réalisée chez moi afin d'avoir un point d'accès wifi fonctionnel. Elle représente le fruit de mes recherches sur le sujet condensé afin d'être le plus clair et le plus efficace possible.

Prérequis

Il vous faut déjà une OpenBSD installé (je me base sur une version 4.4) ainsi qu'un minimum de connaissance dans le fonctionnement de PF et du système en lui même. Les documentations sur ces sujets sont assez nombreuses pour que je n'aie pas à réinventer la roue ici.

Bien sûr il vous faut aussi une carte wifi qui supporte le mode hostap. J'ai opté pour cela une carte Linksys WMP54G v4.1 que l'on trouve facilement dans toutes les bonnes crèmeries, qui fonctionne à merveille grâce au driver ral(4) et qui dispose en plus d'un firmware libre.

Description de l'environnement

Ma passerelle OpenBSD est composée de trois interfaces réseaux :

  • rl0 = une carte ethernet realtek qui est reliée directement à internet
  • rl1 = une carte ethernet realtek qui est reliée à mon lan
  • ral0 = une carte wifi ralink qui est reliée a mon wlan

Comme un bon dessin vaut mieux qu'un long discours, voilà une représentation du réseau complet de chez moi qui me sert de référence.

Configuration de la carte wifi

Tout d'abord pour un point d'accès, il faut que la carte wifi soit correctement configurée. Nous allons simplement créer un fichier de configuration afin que lors de la procédure d'initialisation de la machine, notre carte se configure correctement. Pour cela je vous invite à créer un fichier /etc/hostname.if*if* est le nom de votre interface.

Pour ma carte j'ai donc créé un fichier /etc/hostname.ral0 où j'ai mis :

   inet 192.168.2.1 255.255.255.0 NONE media OFDM54 \
   mediaopt hostap nwid My_network_name chan 4

Voilà la description détaillé de mes options :

  • inet : configure l'adresse IPv4
  • 192.168.2.1 : attribut de l'adresse IP
  • 255.255.255.0 : masque de sous-réseau
  • NONE : défini l'adresse de broadcast. Dans le cas où NONE est utilisé, l'adresse est configuré automatiquement en fonction du masque de sous-réseau
  • media OFDM54 : défini le type de média utilisé. Ici je dis que je veux un réseau de type 802.11g. Les types de médias sont obtenus avec la commande suivante :

OpenBSD 4.4 et inférieur :

$ ifconfig -m interface

OpenBSD 4.5 et supérieur :

$ ifconfig interface media
  • mediaopt hostap : défini l'option du média. Ici je demande à ce que ma carte réseau se mette en mode point d'accès. Les types de médias sont obtenus avec la commande suivante :

OpenBSD 4.4 et inférieur :

$ ifconfig -m interface

OpenBSD 4.5 et supérieur :

$ ifconfig interface media
  • nwid My_network_name : défini le nom de mon réseau qui sera visible par tout le monde
  • chan 4 : défini le canal où sera mon réseau.

Bon, il faut avouer que devoir redémarrer pour que ça fonctionne n'est pas l'idéal donc nous allons taper la commande suivante qui lancera correctement l'interface :

$ ifconfig wlan0 inet 192.168.2.1 255.255.255.0 media OFDM54 mediaopt hostap nwid My_network_name chan 4

Voilà, vous avez un point d'accès fonctionnel maintenant bien qu'il ne permette pas encore l'accès à internet et ne soit pas encore protégé.

DHCP

Pour pouvoir se connecter au réseau, il est plus simple d'avoir un serveur DHCP fonctionnel. Je vous pose ici une configuration opérationnelle pour mettre en route ce service :

/etc/dhcpd.conf

shared-network LOCAL-NET {
        option  domain-name "your.domain";
        option  domain-name-servers 192.168.1.1, 212.27.40.240, 212.27.40.241;

        subnet 192.168.1.0 netmask 255.255.255.0 {
                option routers 192.168.1.1;
                
                range 192.168.1.100 192.168.1.150;
        }
}

shared-network WIFI {
        option  domain-name "your.domain";
        option  domain-name-servers 192.168.2.1, 212.27.40.240, 212.27.40.241;

        subnet 192.168.2.0 netmask 255.255.255.0 {
                option routers 192.168.2.1;

                range 192.168.2.100 192.168.2.150;
        }
}

Il faut aussi ajouter dans le fichier /etc/rc.conf.local la ligne suivante :

dhcpd_flags=""

Maintenant, vous avez un serveur DHCP fonctionnel sur le réseau.

Configuration d'un faux serveur http

Cette section permettra aux personnes se connectant à notre point d'accès d'avoir un message d'avertissement. Il est tout à fait possible ici d'utiliser Apache pour afficher ce message mais comme je l'utilise déjà je préfère rediriger les connexions vers un faux serveur crée avec l'utilitaire nc.

Nous allons commencer par créer un fichier exécutable contenant notre faux serveur web :

/usr/local/bin/fake_www

#!/bin/sh
while true; do nc -l 8080 < /var/fake_www/index.html;done >> /var/log/nc-access.log

Et la commande pour le rendre exécutable :

$ chmod +x /usr/local/bin/fake_www

Afin que l'on puisse enregistrer le log de manière correct, sans pour autant rester root sur le processus nc qui n'a pas besoin de droit aussi élevé pour tourner, nous allons réutiliser un compte déjà présent sur le système avec des droits restreint, à savoir le compte www.

$ touch /var/log/nc-access.log
$ chown www:wheel /var/log/nc-access.log
$ chmod 644 /var/log/nc-access.log

Il nous faut aussi ajouter une page html pour nos visiteurs. Je vous mets en exemple de ce que j'ai mis chez moi si vous manquez d'inspiration :

$ mkdir /var/fake_www

/var/fake_www/index.html

<html>
<head>
<title>Acc&egrave;s interdit - Acces denied</title>
</head>
<body>
<h1>Bienvenue sur mon point d'acc&egrave;s ouvert</h1>
<p>Merci de vouloir utiliser mon point d'acc&egrave;s. Pour des raisons de s&eacute;curit&eacute; &eacute;vidente, je ne peux vous laisser aller sur internet sans que vous ne soyez enregistr&eacute; sur ce serveur au pr&eacute;alable.</p>
<p>Afin d'obtenir un code d'enregistrement pour ouvrir l'acc&egrave;s internet, merci le demander au propri&eacute;taire de la ligne.</p>
<p>Bien &eacute;videmment, toutes les connexions sont enregistr&eacute;s afin de garder des traces de vos activit&eacute;s</p>
<hr>
<h1>Welcome on my open acces point</h1>
<p>Thank you using my acces point. For security reason, I cannot permit you to have an internet acces whitout registering on my server before.</p>
<p>To obtain an acces code, please ask the owner of this connexion</p>
<p>All connexions will be registered for legal isues</p>
</body>
</html>

Je ne serai pas tenu responsable du manque de respect pour le W3C que procure cette page. 8-)

Il ne nous reste plus qu'a ajouter le lancement automatique au démarrage de la machine de ce faux serveur en ajoutant les lignes suivante dans /etc/rc.local :

if [ -s /usr/local/bin/fake_www ]; then
echo -n " fake_www"; sudo -u www /usr/local/bin/fake_www &
fi

Et maintenant on lance le serveur depuis la ligne de commande :

$ sudo -u www /usr/local/bin/fake_www &

Voilà notre faux serveur web est fonctionnel. Vous pouvez le tester en pointant votre navigateur sur le port 8080 de votre passerelle.

Authpf

Authentification

Nous allons commencer par la gestion de la création de compte dédié à authpf pour pouvoir nous authentifier correctement.

Il nous suffit simplement de créer un compte qui aura comme shell par default /usr/sbin/authpf. Pour cela, nous allons modifier les fichiers suivant afin d'ajouter le support d'authpf :

/etc/shells

#       $OpenBSD: shells,v 1.5 1997/05/28 21:42:20 deraadt Exp $
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.
/bin/sh
/bin/csh
/bin/ksh
/usr/sbin/authpf

/etc/login.conf

# $OpenBSD: login.conf.in,v 1.2 2007/01/09 10:20:12 millert Exp $

#
# Sample login.conf file.  See login.conf(5) for details.
#

#
# Standard authentication styles:
#
# krb5-or-pwd   First try Kerberos V password, then local password file
# passwd        Use only the local password file
# krb5          Use only the Kerberos V password
# chpass        Do not authenticate, but change users password (change
#               the YP password if the user has one, else change the
#               local password)
# lchpass       Do not login; change user's local password instead
# radius        Use radius authentication
# skey          Use S/Key authentication
# activ         ActivCard X9.9 token authentication
# crypto        CRYPTOCard X9.9 token authentication
# snk           Digital Pathways SecureNet Key authentication
# token         Generic X9.9 token authentication
#

# Default allowed authentication styles
auth-defaults:auth=passwd,skey:

# Default allowed authentication styles for authentication type ftp
auth-ftp-defaults:auth-ftp=passwd:

#
# The default values
# To alter the default authentication types change the line:
#       :tc=auth-defaults:\
# to be read something like: (enables passwd, "myauth", and activ)
#       :auth=passwd,myauth,activ:\
# Any value changed in the daemon class should be reset in default
# class.
#
default:\
        :path=/usr/bin /bin /usr/sbin /sbin /usr/X11R6/bin /usr/local/bin:\
        :umask=022:\
        :datasize-max=512M:\
        :datasize-cur=512M:\
        :maxproc-max=128:\
        :maxproc-cur=64:\
        :openfiles-cur=128:\
        :stacksize-cur=4M:\
        :localcipher=blowfish,6:\
        :ypcipher=old:\
        :tc=auth-defaults:\
        :tc=auth-ftp-defaults:

#
# Settings used by /etc/rc and root
# This must be set properly for daemons started as root by inetd as well.
# Be sure reset these values back to system defaults in the default class!
#
daemon:\
        :ignorenologin:\
        :datasize=infinity:\
        :maxproc=infinity:\
        :openfiles-cur=128:\
        :stacksize-cur=8M:\
        :localcipher=blowfish,8:\
        :tc=default:

#
# Staff have fewer restrictions and can login even when nologins are set.
#
staff:\
        :datasize-cur=512M:\
        :datasize-max=infinity:\
        :maxproc-max=256:\
        :maxproc-cur=128:\
        :ignorenologin:\
        :requirehome@:\
        :tc=default:

#
# Authpf accounts get a special motd and shell
#
authpf:\
        :welcome=/etc/motd.authpf:\
        :shell=/usr/sbin/authpf:\
        :tc=default:

Dans ce dernier fichier, il est évident que seule la section authpf se trouvant tout à la fin nous intéresse.

Maintenant, nous allons créer un compte pour se loguer sur authpf avec la commande suivante :

$ adduser

Je mets ensuite un exemple de ce que vous devez taper. Bien évidement vous pouvez utiliser un autre nom de compte utilisateur que acceswifi.

Use option ``-silent'' if you don't want to see all warnings and questions.

Reading /etc/shells
Check /etc/master.passwd
Check /etc/group

Ok, let's go.
Don't worry about mistakes. There will be a chance later to correct any input.
Enter username []: acceswifi
Enter full name []: acceswifi
Enter shell authpf csh ksh nologin sh [ksh]: authpf
Uid [1002]: 
Login group acceswifi [acceswifi]: authpf
Login group is ``authpf''. Invite acceswifi into other groups: guest no 
[no]: 
Login class authpf daemon default staff [default]: authpf
Enter password []: 
Enter password again []: 

Name:        acceswifi
Password:    ****
Fullname:    acceswifi
Uid:         1002
Gid:         72 (authpf)
Groups:      authpf 
Login Class: authpf
HOME:        /home/acceswifi
Shell:       /usr/sbin/authpf
OK? (y/n) [y]: 
Added user ``acceswifi''
Copy files from /etc/skel to /home/acceswifi
Add another user? (y/n) [y]: n
Goodbye!

Nous avons maintenant un compte acceswifi qui permet de se logguer sur authpf ce qui est complètement inutile pour le moment car authpf n'est pas encore configuré.

Configuration de l'environnement authpf

Nous allons commencer par créer le répertoire pour la configuration d'authpf si ce n'est pas déjà fait :

$ mkdir /etc/authpf

Nous allons maintenant créer le fichier de configuration d'authpf à savoir authpf.conf.

$ touch /etc/authpf/authpf.conf

Et oui, il suffit juste de créer le fichier de conf pour que authpf fonctionne parfaitement. Mais sans ce fichier, il ne pourra pas démarrer. Je vous invite à suivre la FAQ sur le sujet pour plus de détails.

Maintenant, nous allons autoriser le compte acceswifi à utiliser authpf :

$ echo acceswifi > /etc/authpf/authpf.allow

Enfin nous allons ajouter un joli message d'accueil, pour la connexion, dans le fichier /etc/authpf/authpf.message :

Bienvenue sur le point d'acces.

Vous avez maintenant un acces a internet.
-----------------------------------------
Welcome on the access point.

You have now access to the internet.

Il nous reste plus qu'a ajouter le répertoire qui va contenir les règles de filtrage spécifique à notre utilisateur. Pour ce la nous allons commencer par créer le répertoire /etc/authpf/users qui contiendra les répertoires spécifiques aux utilisateurs :

$ mkdir /etc/authpf/users

A l'intérieur de ce dernier répertoire, nous allons ajouter le répertoire qui contiendra la configuration PF de l'utilisateur acceswifi :

$ mkdir /etc/authpf/users/acceswifi

Voilà maintenant il ne nous reste plus qu'à configurer pf pour que tout marche correctement.

PF

Nous allons mettre maintenant les règles PF pour faire fonctionner le tout. Je vous livre ici un jeu de règle générique que vous pourrez facilement modifier et améliorer en fonction de vos besoins.

/etc/pf.conf

# macros
ext_if="rl0"
lan_if="rl1"
wlan_if="ral0"

gateway = 192.168.2.1
tcp_services = "{ 22, 25, 53, 80, 113, 3389 }"
icmp_types = "echoreq"

# options
set block-policy return
set loginterface $ext_if

set skip on lo
  
# scrub
scrub in

# nat/rdr
nat on $ext_if from !($ext_if) -> ($ext_if:0)

rdr-anchor "authpf/*"

rdr pass on $wlan_if proto tcp to port 80 -> 192.168.15.1 port 8080

# règles de filtrage
block in

pass out keep state

antispoof quick for { lo, $lan_if, wlan_if }

pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services flags S/SA keep state

pass in on $ext_if inet proto udp from any to ($ext_if) port 53 keep state

pass in on $wlan_if inet proto tcp from any to $wlan_if port { 22, 53 } flags S/SA keep state
pass in on $wlan_if inet proto udp from any to $wlan_if port 53 keep state

pass in on { $ext_if, $lan_if } inet proto icmp all icmp-type $icmp_types keep state
pass in on $wlan_if inet proto icmp from any to $gateway icmp-type $icmp_types keep state

pass in quick on $lan_if

anchor "authpf/*"

/etc/authpf/users/acceswifi/authpf.rules

wlan_if = "ral0"
ext_if = "rl0"

no rdr on $wlan_if proto tcp from $user_ip to any port 80

pass in quick on $wlan_if from $user_ip to any

S'authentifier

Unix/Linux

Il est bien beau d'avoir un point d'accès fonctionnel mais encore faut il savoir s'authentifier dessus. Pour cela il suffit de lancer son client ssh préféré, à savoir OpenSSH, et de lancer la commande suivante :

$ ssh -l wifiacces 192.168.2.1

Et nous voilà connecté maintenant.

Windows

Vous vous dites sûrement que vous êtes faible et que vous n'avez pas réussi à convaincre votre femme d'enlever le windows de son laptop tout neuf pour mettre un vrai OS d'hommes qui ont de la barbe ! Qu'à cela ne tienne, nous avons aussi une solution pour lui permettre de se connecter à la passerelle wifi sans risquer de mettre votre couple en danger (je parle bien sûr de vous et votre OpenBSD d'amour !).

Rendez vous sur la page de téléchargement de l'utilitaire putty afin d'y télécharger plink.exe. Une fois ceci fait, placez le dans un répertoire dédié à l'intérieur duquel vous ajouterez ce fichier :

authentification.bat

@echo off
plink.exe -l wifiaccess

Il ne restera plus qu'à double cliquer sur authentification.bat et à remplir le mot de passe.

ATTENTION : la fenêtre devra rester ouverte pendant toute la durée d'utilisation de la connexion sinon ça ne fonctionnera plus.

Conclusion

Je ne suis vraiment pas rentré dans les détails car la FAQ officiel du projet OpenBSD le fait déjà de manière optimale. Mais maintenant vous avez toute les clefs en mains pour monter les bases d'un point d'accès wifi fonctionnel et sécurisé.

Crédits

Auteur : Philippe BEAUMONT
Relecteur : Angeli Matthieu
Date de réalisation : 15/05/2009
Version d'OpenBSD : 4.5

documentations/reseau/monter_un_point_d_acces_wifi_securise_via_authpf.txt · Dernière modification: 2011/11/23 14:48 par rustybsd
OpenBSD Apache Driven by DokuWiki
CC Attribution-Noncommercial-Share Alike 3.0 Unported