Un bon truc quand on a des contai­ners

Avoir des contai­ners, c’est cool et c’est plus sécu­risé qu’une instal­la­tion tout en un, mais quand on a une mise à jour sur un des contai­ners, on doit souvent la faire sur chacun. Et ça, ça peut prendre du temps si on n’a pas beau­coup de bande passante (chez soi par exemple).

Même si mon serveur est en data­cen­ter, je ne vois pas bien l’in­té­rêt de gaspiller des ressources pour faire la même chose une dizaine de fois.

C’est donc là qu’in­ter­vient apt-cacher-ng qui cachera les paquets pour l’en­semble des clients : une fois qu’un client a demandé un paquet Debian, celui-ci ne sera pas télé­chargé de nouveau pour les autres clients, il sera servi direc­te­ment par apt-cacher-ng.

Après l’avoir installé grâce à apt-get sur le contai­ner que vous voulez ou sur le dom0, ou une autre machine de votre appar­te­ment, il suffit d’écrire ceci dans le fichier /etc/apt/apt.conf.d/01proxy des machines qui doivent profi­ter d’apt-cacher-ng (dont celle où il est installé):

Acquire::http { Proxy "http://IP_du_serveur_choisi:3142"; };

Bon, l’IP ou le nom de la machine, pourvu que la machine qui contient ça puisse s’y retrou­ver et contac­ter le serveur en ques­tion.

Sécu­rité

Comme ça, apt-cacher-ng est ouvert à tout vent. Si vous avez installé ça sur un serveur, c’est pas cool. Donc le fire­wall est de rigueur (port 3142, vous vous en doutez) ou, si vous avez utilisé ça dans un réseau de contai­ners, vous pouvez forcer l’IP d’écoute d’apt-cacher pour que seul le réseau local soit à même de le contac­ter (l’IPv6 n’a pas que des avan­tages).

Pour ça, il faut modi­fier /etc/apt-cacher-ng/acng.conf et mettre un truc comme ça (à adap­ter à votre cas bien sûr):

BindAddress: 192.168.1.12

À noter qu’il existe aussi apt-cacher qui permet (au niveau sécu­rité) de défi­nir des hôtes à servir et d’autres à refu­ser, mais celui-ci a plus de dépen­dances et apt-cacher-ng est une réécri­ture de celui-ci pour consom­mer le moins de ressources possibles. À vous de voir.

IPv6 ready !

World_IPv6_launch_banner
World IPv6 launch !

Et ouais, j’ai profité de la migra­tion de serveur pour m’in­té­res­ser à IPv6, vu que c’est l’ave­nir et que ça permet quelques trucs bien cool (déjà déga­ger le NAT). Pis ça permet d’avoir la classe en s’ins­cri­vant sur http://www.worl­dipv6­launch.org/.

Et en fait, c’est pas si compliqué que ça à mettre en place (en tout cas, sur mon serveur qui, il est vrai, ne fait rien de bien compliqué).

Voyons voir comment mettre ça en place sur un serveur avec des contai­ners lxc dedans.

Situa­tion de départ

On va reprendre la situa­tion où elle en était à la fin de mon article sur la créa­tion de lxc :

  • un dom0 avec une inter­face eth0 qui donne sur inter­net et une inter­face bridge, br0 qui émule un réseau local.
  • des contai­ners, qui possèdent tous une inter­face eth0. On ne trai­tera qu’un contai­ner, la copie des mani­pu­la­tions étant sans piège.
  • un champ d’ip publiques IPv6, mettons 2001:B0E:42:42::/64, fourni par mon héber­geur/FAI/la nasa…
  • la commande ip, four­nie par le paquet iproute sous Debian

Choi­sir les ip

L’ip de la passe­relle, chez Ovh (chez qui je loue mon serveur), se déduit de votre champ d’ip. Dans le cas fictif qui nous occupe, ce sera 2001:B0E:42:ff:ff:ff:ff:ff/128 => on prend l’ip de son sous-réseau et on s’ar­range pour caler 5 « FF » à la fin. Voir ici pour plus de détails.

L’ip de l’in­ter­face eth0 du dom0 : 2001:B0E:42:42::1

L’ip de l’in­ter­face br0 du dom0 : 2001:B0E:42:42::2

L’ip de l’in­ter­face eth0 du contai­ner : 2001:B0E:42:42::3

J’ai pris 3 ip consé­cu­tives parce c’est plus simple à rete­nir mais vous faites comme vous voulez.

Quelques fichiers de conf

Dans le fichier /etc/sysctl.conf du dom0 (merci à Pierre-Philippe d’avoir remarqué cet oubli) :

net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.eth0.proxy_ndp = 1

Dans le fichier /etc/network/interfaces du dom0 :

iface eth0 inet6 static
    address 2001:B0E:42:42::1
    netmask 128
iface br0 inet6 static
    address 2001:B0E:42:42::2
    netmask 64

On ne s’oc­cupe pas de mettre la passe­relle (instruc­tion gateway) car… ça ne marche pas ! Je ne sais pas pourquoi, sans doute un bug passa­ger.

Dans celui du contai­ner :

iface eth0 inet6 static
    address 2001:B0E:42:42::3
    netmask 64

Dans le fichier de config du lxc (/var/lib/lxc/lxchostname/config) :

lxc.network.ipv6 = 2001:41d0:2:9c::3/64

 Mettre en place la passe­relle

À cause du bug mentionné au-dessus, j’ai du placer la confi­gu­ra­tion de la passe­relle dans le fichier /etc/rc.local.

C’est à ce moment que la commande ip devient utile. Faites des tests en ligne de commande avant d’écrire dans /etc/rc.local, c’est plus simple.

Quelques commande de bases :

ip -6 r(oute) l(ist)
=> affiche les routes ipv6 exis­tantes

ip -6 r(oute) a(dd) 2001:B0E:42:ff:ff:ff:ff:ff dev eth0
=> ajoute une route ipv6 sur eth0

ip -6 r(oute) d(elete) 2001:B0E:42:ff:ff:ff:ff:ff dev eth0
=> supprime la route ipv6

ip -6 neigh add proxy 2001:B0E:42:42::3 dev eth0
=> indique que eth0 doit trans­mettre (forwar­der) les requêtes adp à l’adresse suivante. On utili­sera cette commande pour chacune des ip des contai­ners.

Pour le dom0

ip -6 route add default via 2001:B0E:42:ff:ff:ff:ff:ff dev eth0
ip -6 neigh add proxy 2001:B0E:42:42::2 dev eth0
ip -6 neigh add proxy 2001:B0E:42:42::3 dev eth0

La première ligne est assez normale : par où faut-t’il passer pour aller vers le net.

La deuxième sert à assu­rer que la recherche de la machine ayant l’ip 2001:B0E:42:42::2 (br0 du dom0) sera bien trans­mise et que le contai­ner pourra bien répondre à cette solli­ci­ta­tion. Pareil pour la troi­sième ligne (eth0 du contai­ner).

On pourra voir avec ip –6 r l que les routes

2001:B0E:42:42::1 dev eth0  proto kernel  metric 256
2001:B0E:42:42::/64 dev br0  proto kernel  metric 256

ont été créées toutes seules comme des grandes (nécés­site peut-être un redé­mar­rage et pas juste une acti­va­tion des IPv6 sur les diffé­rentes inter­faces).

Pour le contai­ner

ip -6 route add 2001:B0E:42:42::1 via 2001:B0E:42:42::2 dev eth0
ip -6 route add default via 2001:B0E:42:42::2 dev eth0

Voilà qui peut sembler étrange de spéci­fier la route de 2001:B0E:42:42::1 (eth0 du dom0) en passant par 2001:B0E:42:42::2 (br0 du dom0). En fait, pas du tout. Comme l’in­ter­face eth0 du contai­ner fait partie du réseau 2001:B0E:42:42/64, le serveur pense qu’il peut accé­der à 2001:B0E:42:42::1 direc­te­ment, or il lui faut passer par br0.

Ce problème est évitable en mettant les inter­faces des contai­ners, ainsi que br0 dans un /65 (ou un réseau encore plus petit) distinct de celui de l’in­ter­face eth0 du dom0. Je ne l’ai pas fait au début et ensuite ça m’em­bê­tait de chan­ger toute ma confi­gu­ra­tion.

Fini

Voilà, norma­le­ment, c’est tout bon. Vous pouvez tester votre confi­gu­ra­tion à grands coups de

ping6 ipv6.google.com

ou n’im­porte quel autre serveur dont vous savez qu’il répond aux pings IPv6 (fiat-tux.fr ne répon­dra pas : je bloque le ping des ip que je ne connais pas, désolé) . Pensez à le faire depuis tous les contai­ners, on ne sait jamais.

Vous pouvez tester que le serveur choi­sit est bien censé répondre aux ping6 sur cette page.

Et si j’ai dit une bêtise ou que vous avez une ques­tion, je suis à votre dispo­si­tion !