Installation et paramétrage d'un serveur avec conteneurs LXC chez Online.net/Dedibox
Nous allons décrire ici l'installation et la paramétrage d'un serveur dédié chez Online.net (offres Dedibox). La description de l'installation ne sera peut-être pas exhaustive et se concentrera sur les points clés, ceux qui par exemple ont été bloquants lors de notre déploiement.
Au niveau des technologies utilisées...
Nous allons déployer une version Debian stable (7.x à l'écriture de ces lignes) avec LVM2 (pour le découpage de l'espace disque) étant entendu que le RAID est géré matériellement et ne demande pas de paramétrage au niveau du système. La technologie LXC (LinuX Containers) sera utilisée pour séparer les servicse dans plusieurs conteneurs indépendants.
Pour le réseau, chaque conteneur disposera de sa propre IPv6 et sera donc accessible directement. En IPv4 en revanche, on déploiera un réseau local IPv4 avec un NAT pour répartir le trafic sur les différents conteneurs.
Paramétrage du réseau IPv6 chez Online.net
Chez Online.net, un bloc /48 est attribué avec chaque serveur dédié. Pour gérer l'IPv6 sur le serveur, il faudra installer le client Dibbler (un client DHCPv6) :
aptitude install dibbler-client
puis modifier la clé DUID dans le fichier /var/lib/dibbler/client-duid pour insérer celle attribuée par Online.net dans l'interface d'administration du système. Enfin, on modifiera le fichier de configuration /etc/dibbler/client.conf tel que suit :
log-level 7 iface br0 { pd option dns-server option domain }
On modifie alors le fichier /etc/network/interfaces pour contenir les éléments suivants :
auto br0 iface br0 inet static address 88.123.123.123 netmask 255.255.255.0 gateway 88.123.123.1 bridge_ports eth0 iface br0 inet6 static address 2001:abcd:abcd:abcd:: gateway fe80::123:1234:1234:1234 netmask 56
Vous aurez bien sûr pris le soin de remplacer 2001:abcd:abcd:abcd:: par l'adresse IPv6 correspondant au bloc /56 que vous avez décidé d'attribuer à votre serveur dédié et de spécifier la bonne passerelle (la passerelle par défaut est aussi l'adresse du routeur auquel est connecté votre Dedibox, vous pourrez trouver dans les logs de Dibbler l'adresse de ce routeur). Et remplacer 88.123.123.123 par l'adresse IPv4 qui vous a été attribuée (et spécifier la passerelle correspondante).
Ce paramétrage correspond à la mise en place d'un pont réseau (bridge) ce qui permettra à toutes les machines virtuelles de communiquer entre elles et de partager les communications réseau.
On redémarre alors le réseau :
/etc/init.d/networking restart
(si vous êtes connecté en SSH, il faudra peut-être se reconnecter en utiliser les nouvelles adresses spécifiées - pour forcer la connexion SSH en IPv6 il faudra utiliser ssh -6 et ssh -4 pour forcer l'IPv4)
puis on redémarre Dibbler par les commandes habituelles :
/etc/init.d/dibbler-client stop /etc/init.d/dibbler-client start
Une fois les conteneurs en place, nous reviendrons sur ce paramétrage pour y apporter quelques légères modifications.
Création de volumes virtuels avec LVM pour héberger les conteneurs
Chaque conteneur sera contenu dans un espace logique géré par LVM. Cela permettra notamment une manipulation aisée pour le redimensionnements, les sauvegardes...
Lors de l'installation initiale, nous avons donc pris le soin de garder une grosse partition /dev/sdaX non utilisée - c'est elle que nous allons déclarer comme volume physique pour LVM.
Il faut d'abord s'assurer que /dev/sdaX n'est pas mentionné dans /etc/fstab et le cas échéant commenter la ligne correspondante.
Puis on crée le volume physique :
pvcreate /dev/sdaX vgcreate vg /dev/sdaX
et 2 volumes logiques de 50 Go :
lvcreate -n Nom1 -L 50g vg lvcreate -n Nom2 -L 50g vg mkfs.ext4 /dev/vf/Nom1 mkfs.ext4 /dev/vf/Nom2
Installation de LXC et déploiement du premier conteneur
aptitude install lxc lxc lxctl bridge-utils debootstrap unzip
installera les éléments nécessaires. Puis on modifiera /etc/fstab pour contenir :
cgroup /sys/fs/cgroup cgroup defaults 0 0
La commande lxc-checkconfig permet de vérifier si tout est paré et donné des aides pour la résolution d'éventuels problèmes. Une fois que tous les paramètres de lxc-checkconfig sont au vert, on se lance pour de vrai !
A noter que le template Debian 7 inclus par défaut pour LXC dans Debian 7 est défectueux (cf. 'The Debian 7 template is broken' in [https://wiki.debian.org/LXC |https://wiki.debian.org/LXC] et la solution proposée ici par Rob van der Hoeven). Les lignes ci-dessous correspondent à la solution proposée par Rob.
On déploie un template fonctionnel :
cd /usr/share/lxc/templates/ wget http://freedomboxblog.nl/wp-content/uploads/lxc-debian-wheezy.gz gzip -d lxc-debian-wheezy.gz chmod u+x lxc-debian-wheezy
et on lance la création du premier conteneur :
lxc-create -n myfirstcontainer -t debian-wheezy
On déplace alors le conteneur dans le premier disque logique LVM que nous avions créé précédement :
cd /var/lib/lxc/ mv myfirstcontainer myfirstcontainer-tmp mkdir myfirstcontainer mount /dev/vg/Nom1 myfirstcontainer cd myfirstcontainer-tmp cp -R * ../myfirstcontainer/ cd .. rm -Rf myfirstcontainer-tmp
et on paramètre le conteneur comme suit dans /var/lib/lxc/myfirstcontainer/config :
lxc.utsname = container1 lxc.network.type = veth lxc.network.veth.pair = vethcontainer1 lxc.network.flags = up lxc.network.link = br0 lxc.network.ipv4 = 192.168.0.101/24 #on attribue une adresse IPv4 de réseau local lxc.network.ipv4.gateway = 192.168.0.1 #la passerelle, nous allons attribuer cette adresse ensuite à l'hôte physique lxc.network.hwaddr = 00:11:D0:14:84:BE #attention, à modifer par une valeur aléatoire si vous installez plusieurs machines pour qu'il n'y ait pas collision ! lxc.network.ipv6 = 2001:abcd:abcd:abcd::101/56 #une adresse appartenant au bloc /56 attribué au serveur dédié
et on modifie les paramétrages réseau au sein du conteneur dans /var/lib/lxc/myfirstcontainer/rootfs/etc/network/interfaces :
auto eth0 iface eth0 inet static address 192.168.0.101 iface eth0 inet6 static address 2001:abcd:abcd:abcd::101 netmask 56 post-up ip -6 route add default via 2001:abcd:abcd:abcd::
Sur la machine hôte, on modifie alors les paramètres tel que suit :
- on indique à Dibbler de ne pas chercher à paramétrer l'interface virtuelle vethcontainer1 en ajoutant dans la configuration de Dibbler :
iface vethcontainer1 no-config
- on met en place le réseau IPv4 par :
ip addr add 192.168.0.1 dev br0 ip route add 192.168.0.0/16 dev br0 iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE
- on met en place le réseau IPv6 par :
ip -6 route add 2001:abcd:abcd:abcd::101 dev br0
- on modifie les paramétrages réseau du système en modifiant /etc/sysctl.conf :
net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.forwarding = 1 net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 net.ipv6.conf.all.accept_ra = 2
et sysctl -p pour prendre en compte ces paramétrages.
Si la connectivité IPv6 disparaît, alors il faudra se reconnecter en IPv4 et lancer les commandes suivantes :
ip -6 route add aa:bb:cc:dd:ee::/64 dev br0 ip -6 route add default via aa:bb:cc:dd:ee::1 dev br0 /etc/init.d/dibbler-client stop /etc/init.d/dibbler-client start
en remplaçant aa:bb:cc:dd:ee::1 par l'adresse de la passerelle IPv6 (cette adresse est normalement communiquée par les Router Advertisements).
Tout semble alors prêt pour le démarrage du conteneur !
Lancement du conteneur
lxc-start -d -n myfirstcontainer
et on peut alors s'y connecter en console via :
lxc-console -n myfirstcontainer
Par défaut, le mot de passe root est root (c'est le paramétrage par défaut du template que nous avons utilisé - il va de soi que nous allons rapidement modifier ce paramétrage).
Pour quitter la console LXC, il faudra faire Ctrl+a puis d.
Dans le conteneur, on pourra vérifier que :
- ping 192.168.0.1 fonctionne (ping de la machine hôte physique)
- ping 8.8.8.8 fonctionne (ping vers l'extérieur, le web)
- ping -6 2001:abcd:abcd:abcd:: fonctionne (ping de la machine hôte physique en IPv6)
- ping -6 2001:4860:4860::8888 fonctionne (ping vers le web en IPv6)
Si tout fonctionne comme attendu, on peut alors poursuivre l'installation du système. On pourra par exemple :
- créer des conteneurs additionnels (en adaptant quelque peu le paramétrage réseau afférent)
- paramétrer iptables et ip6tables sur l'hôte physique et les conteneurs pour protéger les systèmes et rediriger le trafic IPv4 sur les conteneurs
- installer Pound comme reverse proxy pour diriger le trafic HTTP/HTTPS IPv4 vers les différents conteneurs sous-jacents
Exemple de configuration iptables sur l'hôte physique
#!/bin/bash IPTABLES='/sbin/iptables'; CT1_HOST="192.168.0.101"; CT2_HOST="192.168.0.102"; MONITORING_ONLINE="88.190.254.18"; LAN="192.168.0.0/24"; WAN_IFACE="br0"; WAN_IP="88.123.123.123"; # Flushing tables $IPTABLES -F $IPTABLES -X $IPTABLES -t nat -F # Define default policy $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P FORWARD ACCEPT $IPTABLES -A INPUT -j ACCEPT -d $LAN; $IPTABLES -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED # Temporary - SSH access open to all IPs on port 22 but Fail2ban is working.$ $IPTABLES -A INPUT -j ACCEPT -p tcp --dport 22 # Opens to ping from online monitoring $IPTABLES -A INPUT -j ACCEPT -p icmp -s $MONITORING_ONLINE # Accepts connection to ports 80 and 443 $IPTABLES -A INPUT -j ACCEPT -p tcp --dport 80 $IPTABLES -A INPUT -j ACCEPT -p tcp --dport 443 # Rediriger le port 123 vers le container 1 $IPTABLES -t nat -A PREROUTING -p tcp --dport 123 -d $WAN_IP -j DNAT --to-destination $CT2_HOST:123 # Rediriger un port 456 vers le container 2 $IPTABLES -t nat -A PREROUTING -p tcp --dport 456 -d $WAN_IP -j DNAT --to-destination $PAB2_HOST:456 # Activating masquerade FROM local network $IPTABLES -t nat -A POSTROUTING -o $WAN_IFACE -s $LAN -j MASQUERADE
Exemple de configuration de pound sur l'hôte physique
User "www-data" Group "www-data" RootJail "/chroot/pound" ## Logging: (goes to syslog by default) ## 0 no logging ## 1 normal ## 2 extended ## 3 Apache-style (common log format) LogFacility local0 LogLevel 1 ## check backend every X secs: Alive 180 ## use hardware-accelleration card supported by openssl(1): #SSLEngine "<hw>" # poundctl control socket Control "/var/run/pound/poundctl.socket" ListenHTTP Address 88.123.123.123 Port 80 ## allow PUT and DELETE also (by default only GET, POST and HEAD)?: xHTTP 2 #Les services à envoyer sur le premier conteneur Service HeadRequire "Host: .*(domaine1.fr|domaine2.fr|domaine3.fr).*" BackEnd Address 192.168.0.101 Port 8080 End End #Les services à envoyer sur le second conteneur Service HeadRequire "Host: .*(domaine4.fr|domaine5.fr).*" BackEnd Address 192.168.0.102 Port 8080 End End End ListenHTTPS Address 88.123.123.123 Port 443 Cert "/path/to/certificate/pound.pem" HeadRemove "X-Forwarded-Proto" AddHeader "X-Forwarded-Proto: https" ## allow PUT and DELETE also (by default only GET, POST and HEAD)?: xHTTP 2 #Les services à envoyer sur le premier conteneur Service HeadRequire "Host: .*(domaine1.fr|domaine2.fr|domaine3.fr).*" BackEnd Address 192.168.0.101 Port 8080 End End #Les services à envoyer sur le second conteneur Service HeadRequire "Host: .*(domaine4.fr|domaine5.fr).*" BackEnd Address 192.168.0.102 Port 8080 End End End