Demo: Thick Jail with VNET
Problem — von ezjail
auf native Jails migrieren
(Hintergrund).
Mein Setup — Kind seiner Zeit und geht inzwischen besser.
Auf dieser Seite — wie kann ich (testweise) eine Thick Jail mit VNET
erstellen und diese (vorerst) parallel neben ezjail
laufen lassen?
Netzwerk (bisher)
Meine Jails haben das Netzwerk bisher so aufgesetzt:
/etc/rc.conf
vom Host:
cloned_interfaces="lo1"
ifconfig_lo1="inet 10.13.12.1/32"
ifconfig_lo1_ipv6="inet6 fd32:10:13:12::1 prefixlen 128"
In der /usr/local/etc/ezjail/some
:
export jail_some_hostname="some"
export jail_some_ip="lo1|10.13.12.3,lo1|fd32:10:13:12::3"
Und die /etc/pf.conf
(grob):
# public addresses
ip_em0_p4 = "1.2.3.4"
ip_em0_p6 = "1234:5678:90ab:cdef::1"
# jail addresses
ip_j_some4 = "10.13.12.3"
ip_j_some6 = "fd32:10:13:12::3"
…
# allow loopback traffic
set skip on { lo0, lo1 }
# outbound traffic from jails
nat pass on em0 inet from (lo1:network) to any -> $ip_em0_p4
nat pass on em0 inet6 from (lo1:network) to any -> $ip_em0_p6
# redirect traffic into jails
rdr pass log on em0 inet proto tcp from any to (em0:network) port http -> $ip_j_some4
rdr pass log on em0 inet6 proto tcp from any to (em0:network) port http -> $ip_j_some6
rdr pass log on em0 inet proto tcp from any to (em0:network) port https -> $ip_j_some4
rdr pass log on em0 inet6 proto tcp from any to (em0:network) port https -> $ip_j_some6
…
Funktioniert und tut was es soll.
Geht so, passt. Ist aber bisschen hämdsärmlig. vnet
soll jetzt modern sein.
Storage
Die Jails von ezjail
liegen unter /usr/jails
, der Pool heißt tank
.
Bei der Ordnerstruktur orientiere ich mich am Handbuch und erstelle mir Datasets:
zfs create tank/root/containers
zfs create tank/root/containers/classic
Schaut dann grob so aus:
…
tank 3.15T 3.69T 128K none
tank/root 3.15T 3.69T 151K /usr/jails
…
tank/root/containers 279K 3.69T 140K /usr/jails/containers
tank/root/containers/classic 140K 3.69T 140K /usr/jails/containers/classic
…
Thick Jail erstellen
Eigentlich geht es jetzt stumpf nach Handbuch…
Einmal das Userland bitte:
fetch https://download.freebsd.org/ftp/releases/amd64/amd64/`uname -r`/base.txz \
-o /usr/jails/containers/base.txz
Extrahieren:
tar -xf /usr/jails/containers/base.txz \
-C /usr/jails/containers/classic --unlink
Die timezone
setzen:
cp /usr/jails/containers/classic/usr/share/zoneinfo/Europe/Berlin \
/usr/jails/containers/classic/etc/localtime
Als resolv.conf
nutzen wir direkt die Server von Quad9:
cat << EOF > /usr/jails/containers/classic/etc/resolv.conf
nameserver 2620:fe::fe
nameserver 2620:fe::9
nameserver 149.112.112.112
nameserver 9.9.9.9
EOF
Haare schön machen:
freebsd-update -b /usr/jails/containers/classic fetch install
Netzwerk Config mit VNET
Die /etc/rc.conf
wird erweitert:
cloned_interfaces="lo1 bridge0"
ifconfig_lo1="inet 10.13.12.1/32"
ifconfig_lo1_ipv6="inet6 fd32:10:13:12::1 prefixlen 128"
ifconfig_bridge0="inet 10.13.37.1/24"
ifconfig_bridge0_ipv6="inet6 fd32:10:13:37::1 prefixlen 64"
autobridge_interfaces="bridge0"
autobridge_bridge0="epair*a em0"
Sollte dann auch hoch kommen:
service bridge restart
service netif cloneup
Dazu in der /etc/pf.conf
(grob):
…
# allow loopback traffic
set skip on { lo0, lo1, bridge0 }
# outbound traffic from jails
…
nat pass on em0 inet from (bridge0:network) to any -> $ip_em0_p4
nat pass on em0 inet6 from (bridge0:network) to any -> $ip_em0_p6
# redirect traffic into jails
…
rdr pass log on em0 inet proto tcp from any to (em0:network) port 4242 -> "10.13.37.23"
rdr pass log on em0 inet6 proto tcp from any to (em0:network) port 4242 -> "fd32:10:13:37:11::17"
…
Geht erstmal darum zu testen ob Trafic aus/in die Jail kommt. Deshalb fixe IP-Adressen und Ports… Wenn Test vorbei kommt das wieder weg!
pf
neustarten, sich dadurch aus der ssh Session werfen, fluchen,
Tastatur & Monitor anschließen (falls geht) oder ganzen Server neustarten.
Ist mir noch nie passiert…
Jail Config
Hackerman fängt schon mal hart mit Templating an.
Dies hilft immer einheitlich zu bleiben. Auch wage ich den Versuch
auf so Sachen wie .include "/etc/jail.conf.d/*.conf";
o.Ä. zu verzichten –
Debugging wird einfacher wenn man nur ein File öffnen muss.
Das Resultat: Eine handverlesene Mixtur aus den Thick &
VNET Handbuch Seiten, der /var/run/jail.some.conf
und der Quelle Internet…
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.consolelog = "/var/log/jail_console_${name}.log";
exec.system_user = "root";
exec.jail_user = "root";
exec.clean;
mount.fstab;
mount.devfs;
devfs_ruleset = 5;
path = "/usr/jails/containers/${name}";
mount.fstab = "/etc/fstab.jail.${name}";
allow.raw_sockets;
host.hostname = "${name}";
vnet;
vnet.interface = "${epair}b";
exec.prestart = "/sbin/ifconfig ${epair} create up";
exec.prestart += "/sbin/ifconfig ${epair}a descr jail=${name} up";
exec.prestart += "/sbin/ifconfig ${bridge} addm ${epair}a up";
exec.start += "/sbin/ifconfig ${epair}b inet ${ipv4} up";
exec.start += "/sbin/ifconfig ${epair}b inet6 ${ipv6} up";
exec.start += "/sbin/route -4 add default ${gw_4}";
exec.start += "/sbin/route -6 add default ${gw_6}";
exec.poststop += "/sbin/ifconfig ${bridge} deletem ${epair}a";
exec.poststop += "/sbin/ifconfig ${epair}a destroy";
classic {
$num = "23";
$hex = "17";
}
* {
$ipv4 = "10.13.37.${num}/24";
$ipv6 = "fd32:10:13:37:11::${hex}/64";
$gw_4 = "10.13.37.1";
$gw_6 = "fd32:10:13:37::1";
$epair = "epair${num}";
$bridge = "bridge0";
}
Pro Jail muss man nur $num
und $hex
definieren, Netzwerk Config in einer
Wildcard, ganz oben einheitliche Config. So der Plan…
-
exec.consolelog = "/var/log/jail_console_${name}.log";
ezjail
macht/var/log/jail_${name}_console.log
- somit wird neu/alt nicht clashen.
-
devfs_ruleset = 5;
muss dasvnet
ruleset sein..- Das Default in
/etc/defaults/devfs.rules
ist5
:[devfsrules_jail_vnet=5]
- Das Default in
-
mount.fstab = "/etc/fstab.jail.${name}";
ezjail
macht/etc/fstab.${name}
- somit wird neu/alt nicht clashen.
- Wird erst für Thin Jails relevant
- Es reicht
echo "#" > /etc/fstab.jail.classic
-
vnet;
&vnet.interface = "${epair}b";
- Ist das Ziel der ganzen Aktion
- Für die Jail
classic
wäre dasepair23b
-
exec.prestart
(Auf dem Host)- Interfaces
epair23a
&epair23b
werden erstellt epair23a
wird member derbridge0
- Interfaces
-
exec.start
(In der Jail)epair23b
bekommt IPv4 & IPv6 Addressen gesetzt- default routen werden gesetzt
Starten
Eigentlich haben wir alles die Jail sollte hoch kommen:
service jail onestart classic
In ezjail-admin list
taucht classic
nicht auf, jedoch in jls
:
JID IP Address Hostname Path
…
5 10.13.12.3 some /usr/jails/some
…
10 classic /usr/jails/containers/classic
IP-Addresse hier nicht dabei! 🙀 Danke, VNET
!
ifconfig
zeigt epair23a
und bridge0
hat dies als Member…
Testen
In die Jail kommt man stumpf mit jexec classic
, oder vornehmer mit
jexec classic login -f root
(motd, “You have mail.”).
Wir sollten die Devices /dev/zfs
& /dev/pf
(wegen: devfs_ruleset = 5;
) sehen.
Netzwerk geht?
drill aaaa wissen.der-beweis.de
drill a wissen.der-beweis.de
ping -6 -c 3 wissen.der-beweis.de
ping -c 3 wissen.der-beweis.de
;; ANSWER SECTION:
& 0.0% packet loss
ist das was wir sehen wollen! \o/
Wir haben Verbindung nach draußen.
Dann mal anders rum: nc -l 4242
Und von außen auf den Server: nc fetter.server.example.net 4242
Kryptische Nachricht erscheint. Also funktioniert auch! \o/
Fazit
Läuft!
Seitdem eine /etc/jail.conf
existiert, wird pro einzelner ezjail
die startet eine neue Warning ausgegeben:
WARNING: /var/run/jail.some.conf is created and used for jail some.
…
/etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete.
Please consider migrating to /etc/jail.conf.
Letzte Nachricht ist ja bereits bekannt - Was meinst du warum ich gerade den ganzen Aufwand treibe? 😅
Auch dauert das starten der Jails von ezjail
jetzt gefühlt länger,
aber es funktioniert alles weiterhin.
ezjail
parallel mit jail
funktioniert auch:
sysrc ezjail_enable=YES ; sysrc jail_enable=YES
service ezjail restart
startet nur die eigenen Jails neu.service jail restart
stoppt alle Jails, aber hängt beiezjail
die mountpoints nicht korrekt aus…
Also besser die Jails immer einzeln mit dem richtigen Tool neu starten.
- Jetzt funktionieren auch
service jail console classic
&service jail console some
.- Macht aber
less
kaputtWARNING: terminal is not fully functional
- wtf?
- Macht aber
Was fehlt:
- Nur
/etc/resolv.conf
&/etc/localtime
haben wir angefasst..- Irgendwas wie
ezjail
flavor nachbauen?sysrc sendmail_enable=NONE
oder ähnliche Späße laufen lassen..
- Irgendwas wie
Und weiter?
¯\_(ツ)_/¯