V posledním dílu seriálu o OpenVZ se podíváme na síťování. Defaultním síťovým rozhraním OpenVZ je venet (Virtual NETwork). Pracuje na třetí vrstvě síťového modelu a funguje jako point-to-point linka mezi VE0 a containerem. Potřebujete-li, aby rozhraní mělo MAC adresu, bylo použitelné pro bridge a fungoval na něm broadcast, je nutné použít rozhraní veth (Virtual ETHernet), pracující na druhé vrstvě.
Rozhraní venet
Virtuální server, jehož vytvoření jsem demonstroval v prvním dílu seriálu, používá síťové rozhraní venet. Uvnitř containeru je rozhraní vidět takto:
root@deb6:/# ifconfig ... venet0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:127.0.0.1 P-t-P:127.0.0.1 Bcast:0.0.0.0 Mask:255.255.255.255 UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1 RX packets:2 errors:0 dropped:0 overruns:0 frame:0 TX packets:11 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:168 (168.0 B) TX bytes:840 (840.0 B) venet0:0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:172.16.206.100 P-t-P:172.16.206.100 Bcast:0.0.0.0 Mask:255.255.255.255 UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1
Každá další IP adresa se ve výpisu objeví jako další alias k rozhraní venet0. Uživatel containeru si IP adresu nemůže sám změnit. IP adresy a některé další síťové parametry jsou nastavovány pomocí skriptů umístěných v adresáři /etc/vz/dists/scripts. Je jich tam celá řada pro všechny prováděné operace a různé operační systémy. To, co se provádí, najdete zapsáno v konfiguračním souboru umístěném o úroveň výš, tedy v /etc/vz/dists. Název konfiguračního souboru je dostatečně návodný, např. debian-6.0.conf.
Na hostiteli virtuálních serverů je vidět pouze jediné rozhraní venet0; ve výpisu routovací tabulky je pak vidět, že všechny IP adresy jednotlivých virtuálních serverů jsou směrovány do tohoto jediného venet0 rozhraní. O roztřídění provozu do správného virtuálního serveru se stará kernelový modul vznetdev.
root@ve0:~# ifconfig ... venet0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 UP BROADCAST POINTOPOINT RUNNING NOARP MTU:1500 Metric:1 RX packets:345 errors:0 dropped:0 overruns:0 frame:0 TX packets:3 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:22997 (22.4 KiB) TX bytes:271 (271.0 B) root@ve0:~# ip route 172.16.206.100 dev venet0 scope link 172.16.206.101 dev venet0 scope link 172.16.28.0/24 dev eth0 proto kernel scope link src 172.16.28.133 default via 172.16.28.2 dev eth0
Pokud má virtuální server IP adresu veřejně dostupnou na síti, je ve výstupu programu traceroute vidět jak IP adresa virtuálního serveru, tak předchozí IP adresa konkrétního hostitele virtuálních serverů. To se vám může hodit, když budete hledat, kde ten který virtuál běží.
IP adresu containeru můžete přidělit hned při vytváření parametrem –ipadd <addr>, anebo kdykoliv později pomocí volání vzctl:
vzctl set <CTID> --ipadd <IPv4addr|IPv6addr> --save
Potřebujete-li odebrat IP adresu z virtuálního serveru, použijte přepínač –ipdel <addr>. Při stěhování virtuálních serverů (anebo jen IP adres z virtuálního serveru na server) se vám může hodit program arpsend. Ten slouží k rozeslání ARP požadavku na okolní počítače v síti, aby si upravily ARP tabulku - neuděláte-li to, budete čekat poměrně dlouho, než začne přestěhovaná IP adresa fungovat.
IPv6
Abyste uvnitř containeru mohli použít IPv6, musíte nejprve protokol zapnout v konfiguračním souboru /etc/vz/vz.conf, hledejte proměnou IPV6 a nastavte na „yes“ (nebude-li tak již nastavena). Defaultně je podpora IPv6 vypnutá a změna vyžaduje restart.
Dokumentace OpenVZ k IPv6 říká, že "… venet devices are not fully IPv6 compliant… ". Moje praktická zkušenost je, že to funguje zcela spolehlivě. Používám statickou konfiguraci jak na hostitelích, tak na virtuálních serverech, a jediné, co je třeba po startu virtuálního serveru provést, je:
/sbin/ip -6 route replace default dev venet0
Příkaz mám nastavený v souboru /etc/rc.local.
Containery s veřejnou IPv4 adresou
Typickou instalací OpenVZ jsou containery používající veřejnou IP adresu. V případě, že je hostitel containerů nainstalován v té samé síti, jako mají být containery, je kromě výše uvedeného ještě nutný zapnutý IPv4 forwarding.
echo 1 > /proc/sys/net/ipv4/ip_forward
Firewall lze nastavovat buď na hostiteli, anebo v containeru tak, jako by to byl fyzický server. První možnost, tedy nastavovat ho přímo na hostiteli, je vhodná pouze pro speciální případy. V běžné praxi si budou chtít správci containerů nastavovat firewall sami. V takovém případě je třeba dbát, aby UBC parametr numiptent byl dostatečně vysoký, aby se všechna potřebná pravidla vešla OpenVZ do paměti.
Aby iptables firewall fungoval správně, potřebuje moduly v kernelu; zdaleka ne všechny dostupné jsou dostupné uvnitř containeru. Dostupnost modulů je řízena globální konfigurací OpenVZ umístěnou v konfiguračním souboru /etc/vz/vz.conf, moduly pro IPv4 firewall jsou exportovány prostřednictvím proměnné IPTABLES a moduly pro IPv6 firewall prostřednictvím proměnné IP6TABLES. Změna globálního konfiguračním souboru vyžaduje restart všech CT prostřednictvím příkazu /etc/init.d/vz restart.
Budete-li chtít upravit dostupné moduly jen pro nějaký konkrétní container, je to možné pomocí příkazu:
vzctl set <CTID> --iptables 'module1 module2 ...'
kde module1 module2 představuje kompletní seznam modulů, které mají být danému containeru k dispozici.
Ne všechny moduly, které iptables umí, jsou k dispozici. Zkusíte-li použít nějaký, který k dispozici není, vzctl vás na to upozorní:
root@ve0:~# vzctl set 1000 --iptables 'ipt_REJECT ipt_tos ipt_limit ipt_multiport iptable_filter iptable_mangle ipt_TCPMSS ipt_tcpmss ipt_ttl ipt_length ipt_LOG ipt_state ipt_conntrack ip_conntrack ip_conntrack_ftp ipt_MASQUERADE' --save Warning: Unknown iptable module: ipt_MASQUERADE, skipped
Výše uvedený příklad představuje seznam modulů, které mám otestované, že fungují, tedy až na ipt_MASQUERADE. Kompletní seznam podporovaných modulů se mi nepodařilo najít. Na OpenVZ wiki je článek Setting up an iptables firewall, který by se vám mohl hodit, budete-li potřebovat firewallování na OpenVZ prozkoumat detailněji.
Containery s privátní IPv4 adresou (NAT)
Možná si teď ťukáte na čelo a myslíte si něco nepěkného o bláznech provozujících servery na nedostupných privátních adresách. Zadržte. Existují aplikace, které potřebují jeden či dva TCP/UDP porty a jinak nic jiného. Z mé praxe je to například kombinace LDAP, TACACS+ a RADIUS serveru. Rozdělení jednotlivých služeb na různé virtuální servery mi umožnilo zpřístupnit virtuální servery poskytující jednotlivé služby administrátorům, kteří ty služby využívají, aniž bych jim musel poskytovat přístup k ostatním službám.
Všichni uživatelé služeb využívají společnou IP adresu, řekněme 195.113.aaa.bbb, a obvyklý port dané služby. Firewall hostitele těchto služeb potom obsahuje konfiguraci, která zajistí předání paketů do patřičného virtuálního serveru. Jednotlivé virtuální servery mají pouze privátní adresu 192.168.1.b. SSH těchto virtuálních serverů je potom dostupné na portech 9722–24.
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE # LDAP iptables -A PREROUTING -t nat -i eth0 -p tcp -d 195.113.aaa.bbb --dport 389 -j DNAT --to 192.168.1.3:389 iptables -A PREROUTING -t nat -i eth0 -p tcp -d 195.113.aaa.bbb --dport 636 -j DNAT --to 192.168.1.3:636 iptables -A PREROUTING -t nat -i eth0 -p tcp -d 195.113.aaa.bbb --dport 9722 -j DNAT --to 192.168.1.3:22 # TACACS+ iptables -A PREROUTING -t nat -i eth0 -p tcp -d 195.113.aaa.bbb --dport 49 -j DNAT --to 192.168.1.4:49 iptables -A PREROUTING -t nat -i eth0 -p tcp -d 195.113.aaa.bbb --dport 9723 -j DNAT --to 192.168.1.4:22 # RADIUS iptables -A PREROUTING -t nat -i eth0 -p udp -d 195.113.aaa.bbb --dport 1812 -j DNAT --to 192.168.1.5:1812 iptables -A PREROUTING -t nat -i eth0 -p udp -d 195.113.aaa.bbb --dport 1813 -j DNAT --to 192.168.1.5:1813 iptables -A PREROUTING -t nat -i eth0 -p udp -d 195.113.aaa.bbb --dport 1645 -j DNAT --to 192.168.1.5:1645 iptables -A PREROUTING -t nat -i eth0 -p udp -d 195.113.aaa.bbb --dport 1646 -j DNAT --to 192.168.1.5:1646 iptables -A PREROUTING -t nat -i eth0 -p tcp -d 195.113.aaa.bbb --dport 9724 -j DNAT --to 192.168.1.5:22
Umístění virtuálního serveru na privátní adresu také znamená, že veškerý provoz, který není přeložen, je firewallem hostitele zahozen, tudíž není nutné se dalším firewallem uvnitř virtuálního serveru zabývat.
Rozhraní veth
Potřebujete-li uvnitř virtuálního serveru provozovat služby vyžadující broadcast nebo provozovat síťovou kartu v promiskuitním režimu, musíte použít rozhraní veth. To pracuje na druhé síťové vrstvě a má tak blíže ke skutečnému síťovému rozhraní, byť se stále jedná o emulované zařízení. Konfigurace je o něco složitější než v případě rozhraní typu venet, předvedeme si ji na příkladu.
Cointaineru 1000 přidělím rozhraní eth0. Označení eth0 je z pohledu containeru, na hostiteli pak bude automaticky vytvořeno rozhraní veth1000.0. Pokud bych v containeru vytvořil eth1, pak by se rozhraní na hostiteli jmenovalo veth1000.1.
root@ve0:~# vzctl set 1000 --netif_add eth0 --save Configure veth devices: veth1000.0 Saved parameters for CT 1000 root@ve0:~# ifconfig veth1000.0 veth1000.0 Link encap:Ethernet HWaddr 00:18:51:69:43:26 inet6 addr: fe80::218:51ff:fe69:4326/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0 B) TX bytes:0 (0 B)
Vstoupím do containeru 1000, na rozhraní eth0 nastavím veřejnou IP adresu 195.113.aaa.bbb a defaultní routu. Toto nastavení je pochopitelně žádoucí zanést do patřičného konfiguračního souboru uvnitř virtuálního serveru.
root@ve0:~# vzctl enter 1000 root@deb6:/# ifconfig eth0 195.113.aaa.bbb root@deb6:/# ip route add default dev eth0 root@deb6:/# exit
Poslední konfigurační krok se sestává ze zapnutí IP forwardingu (to už asi budete mít zapnuté kvůli rozhraním typu venet). Dále je třeba zapnout ARP proxy a nastavit routování provozu IP adresy 195.113.aaa.bbb do virtuálního rozhraní veth1000.0. Tím je konfigurace dokončena.
root@ve0:~# echo 1 > /proc/sys/net/ipv4/conf/veth1000.0/forwarding root@ve0:~# echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding root@ve0:~# echo 1 > /proc/sys/net/ipv4/conf/veth1000.0/proxy_arp root@ve0:~# echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp root@ve0:~# ip route add 195.113.aaa.bbb dev veth1000.0
Aby byla konfigurace permanentní, je třeba zapnutí forwardingu a ARP proxy uvést v souboru /etc/sysctl.conf. Nastavení routingu potom provádějte pomocí start skriptu, viz předchozí díl seriálu.
Tento díl seriálu o síťování v OpenVZ je současně posledním dílem celého seriálu. Děkuji za pozornost a doufám, že se mi povedlo alespoň někoho zaujmout. OpenVZ není mrtvé!