2011-05-14 18:48

FreeBSD : jail et client VPN

monopoly_icon_small.gif

Les jails sous FreeBSD sont souvent qualifiées de "chroot sous steroïdes". Elle permettent de confiner des processus, mais également des systèmes FreeBSD complets.

On se rapproche alors des possibilités de la para-virtualisation : la jail possède sa propre IP, et sa propre liste d'utilisateurs.

La configuration du réseau est cependant plus complexe qu'avec une solution de types xen. Par exemple, la jail partage la table de routage de la machine "hôte". Il est également impossible de changer d'IP ou de créer une interface virtuelle depuis la jail.


Le problème


Je souhaite mettre en place la configuration suivante :

- Une jail, configurée et démarrée par ezjail. Elle devra router router le trafic à destination de l'extérieur par un serveur VPN, ce qui me permettra de télécharger des ISO Linux en toute tranquillité.

- La machine "hôte", qui me sert entre autre de serveur mail. Pour continuer à bénéficier du reverse-DNS, elle devra conserver l'IP publique attribuée par mon FAI.

Il est impossible de créer une interface virtuelle tun/tap depuis la jail. Il est possible d'en créer une depuis la machine "hôte", puis de l’attribuer à la jail, mais cette procédure est complexe. Il est plus simple d'installer le client VPN sur la machine "hôte".


Le plan


On procédera de la manière suivante :

- Installer et configurer OpenVPN :
configurer la machine hôte pour qu'elle soit connectée au VPN.

- Activer le support des tables de routage multiples :
recompiler le noyau afin de pouvoir configurer plusieurs tables de routage.

- Attribuer l'une des tables de routage à la jail et la remplir :
une des tables de routage, comportant le serveur VPN comme passerelle par défaut, permettra à la jail de joindre l'extérieur via le VPN.

- Créer un script afin de remplir la table de routage au démarrage :
pour ne pas avoir à le faire à la main à chaque reboot.


Toutes les manipulations seront effectuées sur la machine "hôte".


Installer et configurer OpenVPN


Installons OpenVPN :

#cd /usr/ports/security/openvpn
#make config-recursive
#make install clean

Il faut configurer OpenVPN afin de se connecter au serveur. Le fichier par défaut se trouve dans /usr/local/etc/openvpn/openvpn.conf. Créons le fichier :

#mkdir /usr/local/etc/openvpn
#touch /usr/local/etc/openvpn/openvpn.conf

Il faut maintenant le remplir. Son contenu dépend du serveur VPN. Le fichier d'exemple est un bon point de départ si vous ne pouvez pas vous en procurer un "tout fait".

Dans ma configuration, la machine est connectée au serveur VPN mais continue de router le traffic normalement. Il faut donc empêcher OpenVPN de changer la passerelle par défaut, en commentant le ligne suivante si elle est présente (toujours dans /usr/local/etc/openvpn/openvpn.conf) :

# redirect-gateway def1 bypass-dhcp

Ajoutons ensuite la ligne suivante à /etc/rc.conf afin de lancer OpenVPN au démarrage :

openvpn_enable="YES"

Lançons openVPN afin de vérifier qu'il n'y a pas d'erreur :

#openvpn /usr/local/etc/openvpn/openvpn.conf &

Si tout se passe bien, vous verrez normalement une ligne de ce types au démarrage :

May 14 15:19:00 kirby openvpn[1492]: Initialization Sequence Completed

Notez également la présence d'une ligne ressemblant à :

openvpn[1492]: /sbin/route add -net 10.13.3.0 10.13.3.61 255.255.255.0

On voit ici que l'IP de la passerelle permettant de passer par le VPN est 10.13.3.61. Retenez-la, elle servira bientôt.

Activer le support des tables de routage multiples


Le problème qui se pose dans cette partie est le suivant :

- La machine "hôte" est connectée au serveur VPN, mais celui-ci n'est pas défini comme passerelle par défaut. Le trafic est donc toujours routé par la box.

- La machine "hôte" et la jail partagent la même table de routage.

Donc le trafic de la jail est également routé par la box (ça ressemble à un sophisme, mais le raisonnement me semble bon :-) ).


Il faut donc attribuer des tables de routage différentes à la machine "hôte" et à la jail. Pour cela, nous allons recompiler le noyau en activant le support des tables de routage multiple.

Créons le fichier de configuration pour notre noyau :

#cd /usr/src/sys/<ARCHITECTURE_PROC>/conf
#cp GENERIC KIRBY

<ARCHITECTURE_PROC> devra être remplacé par le type d'architecture de votre micro-processeur, i386 dans mon cas.
Le nom du noyeau, ici KIRBY n'a pas d'importance. Vous pouvez l'appeler comme vous le souhaitez. Conventionnelement, il est écrit tout en majuscule.

Ajoutons la ligne suivante à notre fichier de configuration (toujours /usr/src/sys/<ARCHITECTURE_PROC>/conf/kirby) :

options         ROUTETABLES=4         # default is 1, max 16

On va maintenant compiler le noyau, et l'installer :

cd /usr/src
make buildkernel KERNCONF=KIRBY
make installkernel KERNCONF=KIRBY


Attribuer l'une des tables de routage à la jail et la remplir


Il faut maintenant attribuer la table de routage à notre jail. Avec ezjail, le fichier de configuration est :

/usr/local/etc/ezjail/<NOM_DE_LA_JAIL>

Il faut ajouter ou modifier la ligne suivante :
export jail_<NOM_DE_LA_JAIL>_fib="1"

<NOM_DE_LA_JAIL> correspond au nom que vous avez donné à votre jail.

Remplissons la table de routage afin de lui donner accès à l'extérieur:

setfib 1 route add default <IP_DE_LA_PASSERELLE>

<IP_DE_LA_PASSERELLE> correspond à l'adresse de la passerelle du VPN, chez moi 10.13.3.61.

Vous pouvez tester le fonctionnement, par exemple en vous rendant sur le site geoiptool depuis la machine "hôte" et depuis la jail. Vous devriez avoir deux IP publiques différentes.


Créer un script afin de remplir la table de routage au démarrage


Tout devrait fonctionner à cette étape. Mais dans la configuration actuelle il faut remplir la table de routage à chaque démarrage. Afin d'automatiser tout ça, j'ai crée un petit script. Au passage, merci à Smortex de m'avoir aidé à comprendre le système de démarrage de FreeBSD.

Créons le fichier /usr/local/etc/rc.d/fib, et insérons :

#!/bin/sh
#

# PROVIDE: fib
# REQUIRE: NETWORKING openvpn ezjail

. /etc/rc.subr

name="fib"
start_cmd="${name}_start"
stop_cmd="${name}_stop"
rcvar=`set_rcvar`

load_rc_config $name

: ${fib_enable="NO"}

command="/usr/sbin/setfib"

fib_start()
{
         :       ${fib_gw=$(cat /var/log/messages | grep -E '/sbin/route add' | awk '{print $10}' | sed -n ' $p')}
         ${command} ${fib_nb} route add default ${fib_gw}
}

fib_stop()
{
         ${command} ${fib_nb} route delete default
}

load_rc_config $name
run_rc_command "$1"

Modifions les droits pour le rendre exécutable :
#chown +x /usr/local/etc/rc.d/fib

Il faut aussi remplir /etc/rc.conf afin de lancer le script script au démarrage et de lui fournir les information dont il a besoin :
fib_enable="YES"
fib_nb="1"

Si l'IP de la passerelle est toujours identique, on peut ajouter dans /etc/rc.conf :
fib_gw="<IP_DE_LA_PASSERELLE>"

Tout est maintenant configuré. Il ne reste plus qu'à redémarrer pour en tester le fonctionnement.


sources :
http://www.freebsd.org/doc/handbook/kernelconfig-building.html
http://forums.freebsd.org/showthread.php?t=19607

source de l'image :
http://www.worldofmonopoly.com/fansite/index.php


Posted by St3rk | Permanent link | File under: freebsd