Mes premiers pas avec le poisson qui pique Introduction à OpenBSD et installation d’une passerelle ADSL
Vous voulez épater vos amis dans un diner mondain ? Vous voulez à tout prix sécuriser vos transactions parce que vous savez qu’ILS sont là et qu’ILS vous cherchent ? Vous voulez découvrir un autre OS et une certaine vision de l’informatique ?
Cet article va vous présenter OpenBSD, à travers son installation et quelques exemples d’utilisations.
Sommaire
L'Auteur
Benjamin Leroux
contact - ben AT minet DOT netWho are you ? Who, who, who, who ? (The Who)
OpenBSD est un système d’exploitation appartenant à l’intriguante famille des BSD. Pour ceux qui débarquent, BSD c’est l’unix qui a été dévelopé par la faculté de Berkeley. Cet unix est l’un des premiers à avoir vu le jour, après le premier, écrit au sein d’AT&T. Pour diverses raisons, liées de près ou de loin à l’argent et à la libre diffusion (du savoir et du code source), l’université de Berkeley a créé la licence BSD, un peu différente de la "traditionnelle" GPL, qui est dans un sens encore plus libre (en gros, elle stipule que l’auteur d’un logiciel reste le propriétaire du code, mais n’impose aucune restriction à l’utilisateur quant aux modifications qu’il pourrait y apporter).
Libérés par cette licence, quelques rejetons de la famille BSD se sont émancipés pour former le groupe des "BSD libres", descendant de la version 4.4 de BSD. On trouve trois OS, que sont FreeBSD, OpenBSD et NetBSD. Le but de cet article n’est pas une description ou une comparaison de ces OS... d’ailleurs je n’ai jamais essayé NetBSD.
Ici il est question d’OpenBSD. Pour reprendre les termes du site officiel, ce système fournit "un système d’exploitation de type UNIX LIBRE, multi plates-formes et basé sur 4.4BSD". Les valeurs de cet OS sont parmi les suivantes :
- portabilité
- standardisation
- exactitude
- sécurité proactive
- cryptographie intégrée
Non, non, ce ne sont pas quelques managers du service marketing qui ont écrit ça... Ca donne vraiment envie de tester. Alors, allons y !
Here we go ! (The Chemical Brothers)
OpenBSD supporte l’émulation des binaires SVR4 (Solaris), FreeBSD, Linux, BSD/OS, SunOS et HP-UX. De plus, il est disponible pour diverses architectures, du traditionnel i386 au sparc en passant par les power pc... Ici on va s’intéresser à un PC, "tout ce qu’il y a de plus classique" (pour tout vous dire, il s’agit d’un vieux dell, à base de pentium II).
On dispose de plusieurs possibilités d’installation. On peut le faire par le réseau, comme il sera expliqué dans cet article, ou par CD, que l’on peut commander sur le site. Dans le cas présent, l’install s’est faite par FTP, avec un PC dont la carte réseau est assez classique (chipset realtek, "Accton Technology MPX 5030/5038").
Il faut télécharger quelques fichiers afin de préparer les disquettes de boot pour l’installation (liste des miroirs). Selon la nature de votre machine et de son matériel, il vous faudra les bons fichiers [1]. Ici il suffit juste d’un seul fichier, et donc d’une seule disquette pour booter et commencer à s’amuser. Il s’agit du fichier floppy33.fs, que l’on peut trouver sur le ftp à l’emplacement logique suivant (par exemple sur le ftp de club internet), ftp://ftp.club-internet.fr/pub/OpenBSD/{version}/i386. A l’heure actuelle, la version stable est la 3.3 ; en novembre paraîtra la 3.4. Ensuite il faut créer une disquette ; sous Linux ça donne ça (si vous êtes sous un autre OS, soit vous savez le faire, soit cherchez du côté de rawrite, soit cliquez sur la pomme)
dd if=floppy33.fs of=/dev/fd0 bs=32k
Vous pouvez maintenant booter votre machine (n’oubliez pas de dire au bios de booter sur la disquette). Comme d’habitude avant d’installer un OS, il est bon d’avoir sous la main les informations vitales, comme la configuration matérielle, la configuration du réseau ; de plus ici il est utile de savoir si vous allez utiliser X.
La FAQ 4 du site officiel étant tout à fait remarquable, je ne vais pas la paraphraser. Sachez que l’installation se déroule assez rapidement et qu’elle ne présente pas de difficultés majeures :
- la traditionnelle étape des partitions se fait avec disklabel, un utilitaire assez peu user-friendly (il manquerait plus que ça...) mais plutôt intuitif. D’abord on choisit quelle partie du disque va accueillir OpenBSD puis on la divise en différentes partitions, auxquelles on assigne des points de montage.
- la configuration du hostname (choisissez en un original tout de même) et du réseau. Il faut savoir que sous OpenBSD les interfaces réseau sont dénommés non pas par un identifiant du type ethN mais par un identifiant composé du type de carte (sa "marque") et d’un numéro, comme par exemple rl0 pour une realtek. Là encore la procédure d’install est plutôt claire et intuitive. Dans le cas d’un réseau utilisant dhcp, la configuration sera faite en quelques secondes.
- le choix du mot de passe root (moi je mets toujours "toto", je le retiens mieux)
- le choix du media d’installation (ftp dans notre cas) et d’un mirroir ftp
Ensuite vous devez choisir les "filesets", c’est à dire les briques de base de votre système. Par défaut, tout sauf X est sélectionné. Sélectionnez ce que vous voulez installer puis validez : le programme d’install va alors télécharger et installer ces filesets. Et pour finir, quelques questions vous seront posées comme l’activation ou non de X, la configuration du fuseau horaire et votre numéro de carte bleue pour faire avancer le projet....
Voilà. Votre nouveau système est installé... Il va falloir attendre le temps d’un reboot (n’oubliez pas la disquette...) et vous pourrez utiliser votre machine.
Et maintenant que vais-je faaaaiiiiiiiire ? (G. Bécaud)
L’une des premières choses à faire est de se faire un compte sur la machine. En effet, à quoi ça sert de s’installer un OS tout beau tout secure si c’est pour se loguer en root ! Alors un petit coup de adduser et ensuite donnez vous quelques droits grâce à la commande sudo. Le plus propre étant d’utiliser visudo pour éditer le fichier des sudoers et y ajouter la ligne suivante, qui signifie que l’utilisateur "luser" agit en tant que root quand il exécute une commande précédée de sudo :
luser ALL=(ALL) ALL
Par ailleurs, si vous avez configuré votre sendmail (cependant vous pouvez utiliser une autre machine pour envoyer le mail), pensez à envoyer votre dmesg à l’équipe d’OpenBSD (pour que l’équipe OpenBSD garde une trace du matos qui marche) dmesg | mail dmesg@openbsd.org
C’est pas tout ça mais avec l’install de base, on ne va pas très loin... Alors il va falloir trouver un moyen d’installer des logiciels et autres outils indispensables (oui je l’avoue je voulais bash [2] et vim). Pour ce faire, il y a deux méthodes :
- les ports, qui font partie de l’arbre des ports (que l’on retrouve chez les autres BSD)
- les packages
L’arbre des ports est une arborescence regroupant, pour chaque logiciel, un ensemble de Makefiles qui permettent d’installer des logiciels pour OpenBSD. Ces makefiles téléchargent, configurent et compilent les sources puis installent le logiciel. Les packages sont l’équivalent binaire des ports. D’après la documentation, OpenBSD recommande d’utiliser les packages qui sont la version "finalisée" des ports : "In general, you are HIGHLY advised to use packages over building an application from ports. The OpenBSD ports team considers packages to be the goal of their porting work, not the ports themselves."
Pour installer un package, c’est pas bien compliqué ; il vous faut utiliser les commandes de la forme pkg_* :
- pkg_add pour installer un programme
- pkg_create pour créer un package
- pkg_delete pour en supprimer un (étonnant, non ?)
- pkg_info pour afficher des informations au sujet d’un package
Par exemple, la commande d’installation s’utilise naturellement de la façon suivante : pkg_add package Où package désigne le package à installer : ça peut être un fichier présent localement ou une url vers un ftp par exemple.
Passons maintenant au port, une "spécialité BSD" pourrait-on dire. La première étape est de télécharger l’arbre des ports, sans lequel rien n’est possible. On télécharge et on installe ça de la manière suivante (exemple avec OpenBSD 3.3) :
$ sudo cp ports.tar.gz /usr
$ cd /usr;
$ sudo tar xzf ports.tar.gz
Maintenant on peut l’utiliser. Tout d’abord recherchons un port à installer. Prenons l’exemple de Vim. Pour faire une recherche dans l’arbre, il faut utiliser la directive make search :
$ cd /usr/ports
$ make search key=vim
S’affiche ensuite une liste (assez longue dans notre exemple) de ports, avec diverses informations, comme le nom du port, le nom de son mainteneur, les dépendances, etc... Une fois un candidat choisi, on peut passer à la procédure d’installation. Ici on choisit vim-6.1.350-gtk, le premier de la liste. On se place dans le répertoire editors/vim (sous répertoire de celui des ports). C’est maintenant qu’on va utiliser le jeu de makefiles disponibles pour compiler, configurer et installer notre programme. Pour ce faire, rien de plus simple. Une fois dans le bon répertoire, vous devez taper :
$ sudo make install
Et le système va travailler à votre place : télécharger les sources (en contrôlant les checksums, of course), gérer les dépendances (et installer des ports si besoin), configurer et compiler le programme. Cela va créer un package qui sera ensuite installé (automatiquement). Une fois le travail effectué, le programme sera disponible et utilisable.
Il vous sera possible de nettoyer les sources par make clean et vous retrouverez les packages correspondants aux ports que vous avez installés dans le répertoire /usr/ports/packages/i386/All (cas d’une architecture i386).
Sachez que vous pouvez configurer certaines options de compilation, par l’intermédiaire des "flavours". Dans la pratique, toujours pour l’exemple de vim :
$ cd /usr/ports/editors/vim
$ make show=FLAVORS
===> editors/vim/stable
huge gtk athena motif no_x11 perl python ruby
===> editors/vim/stable (no_x11)
huge gtk athena motif no_x11 perl python ruby
$ env_FLAVOR="no_x11" make install
Cette dernière commande permet d’installer vim en désactivant le support pour X.
Gaston y a le téléfon’ qui son’ (N. Ferrer)
Passons maintenant à un bel exemple d’utilisation : une "passerelle" pour partager un accès ADSL dans un réseau domestique. Ce petit serveur remplira les tâches suivantes :
- gestion de l’accès internet (modem ADSL usb dans notre cas)
- partage de cet accès (NAT)
- serveur DHCP (pour faciliter l’utilisation pour les clients du rézo)
- "petit" firewall
Commençons par l’accès au Net. Pour cela, on va installer un modem ADSL USB, le SpeedTouch de chez Alcatel. Il vous faudra 2 archives, l’un contennant le driver (écrit par Benoit Papillaut dans sa version Linux et porté sous *BSD par Francois Rogler et Richard Tobin) et l’autre contenant un fichier d’Alcatel nécessaire au bon fonctionnement du modem.
Le driver se trouve sur le site du projet. Il est censé fonctionner avec OpenBSD depuis la version 2.9 (testé sur le 3.3 dans notre cas). Le support usb est normalement activé par défaut dans le noyau ; il ne reste qu’à installer le driver :
$ tar xzf speedtouch-1.1.tar.gz
$ ./configure
$ make
$ sudo make install
Il faut aussi récupérer le fichier mgmt.o d’Alcatel. N’ayant pas réussi à la trouver sur le site d’Alcatel, je le joins à cet article. Normalement on peut trouver une archive speedmgmt.tar.gz contenant le précieux fichier, à utiliser de la sorte :
$ sudo cp mgmt.o /usr/local/libdata/
On peut passer à la configuration du démon ppp qui sera utilisé pour se connecter à Internet ; ppp est inclus dans l’installation de base d’OpenBSD. Vous pouvez copier le ppp.conf.sample, présent dans l’archive du driver, à la place du fichier /etc/ppp/ppp.conf. Prennez soin de remplacer <login> et <password> par les valeurs fournies par votre FAI. Et n’oubliez pas de définir les valeurs de <VPI> et de <VCI>. Pour la France, les valeurs sont 8 pour VPI et 35 pour VCI (le fichier vpivci de l’archive du driver contient les couples de valeur pour d’autres pays).
Maintenant on peut tester la connexion. Soit en utilisant le script fourni avec le driver, adsl.sh.sample, soit en le faisant à la main avec les commandes suivantes (si votre modem est relié au périphérique ugen0 et si dans votre ppp.conf, adsl correspond à votre accès ADSL).
$ sudo ppp -background adsl
Si tout se passe bien vous serez connecté, pour en savoir plus, vous pouvez regarder le daemon.log et le résultat de ifconfig -a (l’inteface tun0 a-t-elle une IP valide ?). En cas de problème, pensez à regarder les logs (le réflexe qui sauve) et éventuellement le résultat de dmesg (pour les problèmes plutôt d’ordre matériel).
Pour un serveur, il est pratique d’avoir une connexion permanente ou en tout cas "quasi permanente". Dans notre cas, nous allons configurer le démon ppp pour qu’il se reconnecte en cas de perte du lien ADSL et pour qu’il se lance au démarrage de l’ordinateur. On va donc écrire un script tout simple qui sera lancé au démarrage.
Le fichier /usr/local/sbin/adsl sera ce script :
ISP=adsl
MODE=ddial
PREFIX="/usr/local"
case $1 in
start)
"$PREFIX/sbin/modem_run" -d /dev/ugen0 -f "$PREFIX/libdata/mgmt.o"\
&& ppp -quiet -$MODE $ISP \
&& echo -n ' ppp'
;;
stop)
killall modem_run
killall ppp
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
On utilise ici le mode ddial du démon ppp, qui rétablira le lien en cas de déconnexion (merci FT...). Maintenant il faut s’arranger pour que ce script soit lancé à chaque boot. Il est alors temps de découvrir les fichiers "rc*", ce qui est assez intéressant pour comprendre le lancement des services sous OpenBSD. On va donc ajouter nos petits scripts à ceux de base du système.
- Première étape : dire au système qu’on a des jolis petits scripts à lancer au boot. On va faire ça en ajoutant un fichier rc.conf.local. On édite /etc/rc.conf pour ajouter (ou décommenter) les lignes suivantes : local_rcconf="/etc/rc.conf.local"
[ -f ${local_rcconf} ] && . ${local_rcconf} # Do not edit this line
- Ensuite on va ajouter un service local, sobremment appelé adsl. On ajoute à /etc/rc.local les lignes suivantes, qui seront les lignes exécutées lors du boot if [ X"${adsl}" != X"NO" -a -x /usr/local/sbin/adsl ]; then
echo -n ' adsl'; /usr/local/sbin/adsl start
fi
- Enfin on précise à notre cher système qu’on veut lancer le service adsl au boot. Dans /etc/rc.conf.local, on ajoute une ligne (si le fichier n’existe pas.... créez le !) adsl=YES
Pour un "confort d’utilisation accru", il est judicieux d’utiliser les services de DynDns pour avoir un DNS dynamique. On passe ici les procédures d’inscription pour s’intéresser à la configuration d’un client pour dyndns, qui nous permettra de mettre à jour notre IP à chaque reconnexion à l’ADSL.
L’arbre des ports contient divers clients. Ici on va se pencher sur ddclient<code>, un client léger écrit en Perl. Une fois le programme installé (<code>cd /usr/ports/net/ddclient/ ; sudo make install), il faut éditer son fichier de configuration, /etc/ddclient.conf. Pour mettre à jour openbsd-roxx.dyndns.org fourni par DynDNS, avec le compte login/password, en utilisant l’interface tun0, votre fichier doit contenir les lignes suivantes :
syslog=yes # log update msgs to syslog
mail=root@localhost.localdomain # mail update msgs to root
pid=/var/run/ddclient.pid # record PID in file.
use=if, if=tun0 # via interfaces
login=login # default login
password=password # default password
server=members.dyndns.org, \
protocol=dyndns2 \
openbsd-roxx.dyndns.org
Et enfin, on aimerait bien que la mise à jour se fasse automatiquement à chaque reconnexion. Ca serait pratique tout de même... Vous en avez rêvé, pppd l’a fait. Il suffit d’éditer (et/ou de créer) le fichier /etc/ppp/ppp.linkup qui contient les scripts à effectuer lors de l’obtention d’une adresse par le démon ppp. On peut lancer des scripts différents selon l’IP reçue. Dans notre cas, on fait au plus simple : on lance le client DynDns quelle que soit notre adresse. Le fichier contient donc :
! /usr/local/sbin/ddclient
Et voilà. On est connecté au net, et en plus, on "disait qu’on avait une IP fixe et une connec permanente".
You are not alone (M. Jackson)
C’est pas tout ça mais il faudrait penser à partager un petit peu. On va faire ça pour un petit réseau "domestique". Pour simplifier la configuration des clients, on va installer un petit serveur DHCP sur notre serveur [3] et ensuite on va découvir le monde merveilleux de paquet filter...
Le dhcpd est inclus dans l’install de base. Il faut cependant dire au système de le lancer (OpenBSD est livré avec beaucoup de services mais ils ne sont évidemment pas tous lancés par défaut...). On édite /etc/rc.conf et on change le flag du dhcpd à "-q" (pour ne pas afficher des tas d’informations au boot). Notre rc.conf doit donc contenir la ligne :
dhcpd_flags="-q"
Ensuite il faut préciser l’interface sur laquelle écoutera la petit démon. On édite pour cela le /etc/dhcpd.interfaces et on ajoute une ligne par interface. Enfin, il faut configurer le service. Le but de cet article n’étant pas la mise en place d’un serveur dhcp, je ne détaille pas cette opération. Voilà juste un fichier de configuration commenté (/etc/dhcpd.conf en toute logique).
# bail de durée infinie
deny unknown-clients;
# on ne donne pas d'adresse aux inconnus !
shared-network LOCAL-NET {
option domain-name "mydomain.net";
option domain-name-servers 193.252.19.3 , 192.252.19.4;
# on fournit l'adresse des DNS
# pour les inclure à la configuration des clients
# ici on a les ns de wanadoo
subnet 192.168.1.0 netmask 255.255.255.0 {
# on définit l'adresse du réseau, ou plutôt du sous rézo
# et son masque
option routers 192.168.1.1;
# passerelle par défaut
# pour les clients de ce sous rézo
# on fait ici une partie par client en
# spécifiant son @MAC et l'ip qu'il aura
host myhost1{
hardware ethernet xx:xx:xx:xx:xx:xx;
fixed-address 192.168.1.X;
}
}
}
Et voilà, le dhcpd sera lancé au prochain boot. Si casser l’uptime vous fait peur, lancez le dhcpd à la main.
On peut maintenant découvrir paquet filter, le formidable outil d’OpenBSD utilisé pour filtrer le traffic TCP/IP, gérer les translation de ports et d’adresses, contrôler la bande passante, etc... Dans notre cas, la configuration de paquet filter ("pf" pour les intimes) est très largement inspirée de la FAQ.
D’abord, on commence à s’y habituer, il faut que pf soit lancé comme service. Pour cela, on édite le désormais célèbre /etc/rc.conf et on s’assure d’y trouver, non commentées, les deux lignes suivantes :
pf_rules=/etc/pf.conf
De plus, il faut dire au noyau qu’on va forwarder les petits paquets pour partager la connexion au net à tous les clients du réseau. On édite donc le tout aussi célèbre /etc/sysctl.conf qui contient un ensemble de variables qui seront utilisées lors du boot pour activer ou non certaines options. Dans notre cas, on veut y voir :
net.inet.ip.forwarding=1 # 1=Permit forwarding (routing) of packets
Pour les plus motivés, on peut ajouter "net.inet.ip6.forwarding=1"... Il faut savoir que ces options sont activées lors du boot. Il faut donc nécessairement rebooter pour prendre en compte les changements. Maintenant ça devient amusant, on va configurer paquet filter. Pour résumer, on veut :
- Faire du NAT pour le réseau interne
- Fermer tout accès de l’extérieur vers notre passerelle à l’exception du ssh (port 22) et de l’identd (port 113) ; à noter qu’on répond au ping
- Permettre une utilisation "totale" du net aux clients du réseau
De plus, on va utiliser certaines options propres à pf, comme le "scrub" pour normaliser les paquets et la directive "antispoof" pour se protéger des truands.
Au final, on obtient le fichier de configuration suivant :
### ben at minet dot net
### 21/09/03
########### macros ################
int_if = "rl0" # interface intérieure
ext_if = "tun0" # interface reliée au net
tcp_services = "{ 22, 113 }" # ports ouverts sur le serveur
icmp_types = "echoreq" # type de signaux icmp acceptés
priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16}" # réseaux locaux
########### options ###############
set block-policy return
# en cas de "block", quand on refuse un paquet, on envoie
# - un TCP RST pour les paquets TCP bloqués
# - un ICMP UNREACHABLE pour les paquet UDP bloqués
set loginterface $ext_if
# on collecte les stats sur tun0
########### scrub #################
# scrub
scrub in all
# normalisation des paquets
# http://www.icir.org/vern/papers/norm-usenix-sec-01-html/index.html
########### nat - rdr #############
# nat
nat on $ext_if from $int_if:network to any -> ($ext_if)
# ftp proxy to avoid nat ftp issues
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
########### filter ################
# filter rules
block all
antispoof for $ext_if
pass quick on lo0 all
block drop in quick on $ext_if from $priv_nets to any
block drop out quick on $ext_if from any to $priv_nets
pass in quick proto tcp from any to any port 22 keep state
pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services flags S/SA keep state
pass in inet proto icmp all icmp-type $icmp_types keep state
pass in on $int_if from $int_if:network to any keep state
pass out on $int_if from any to $int_if:network keep state
pass out on $ext_if proto tcp all modulate state flags S/SA
pass out on $ext_if proto { udp, icmp } all keep state
Voilà une première version assez acceptable pour protéger son petit réseau à la maison. Il pourrait être intéressant d’ajouter une politique de gestion de la bande passante, pour ne pas trainer quand on utilise ssh, pour avoir des débits réservés à certaines applications...
Cet article est (enfin ?) terminé. Il reste des tas de choses à voir, notamment la gestion de la bande passante avec pf et les méthodes de mise à jour d’un système de type OpenBSD : "Tant de choses à voir, à voir et à z-entendre"...
J’espère vous avoir donné envie de découvrir OpenBSD et j’espère surtout ne pas avoir raconté trop de n’importe quoi... Si vous trouvez des erreurs ou si vous avez une envie incontrôlée de me féliciter, n’hésitez pas à me contacter.
Et pour finir, replaçons l'article dans son contexte. Il a été originalement rédigé pour l'Association MiNET (de l'INT).
[1] Cette page de la FAQ présente les fichiers existants
[2] A noter la commande chsh qui permet d’éditer sa section du fichier passwd afin notamment de changer son shell
[3] Pour ceux qui n’auraient pas configuré leur serveur pour utiliser un IP fixe, il suffit d’éditer le fichier /etc/hostname."interface" et d’y ajouter la ligne "qui va bien", par exemple : inet 192.168.1.1 255.255.255.0 192.168.1.255 media 100baseTX