Jails
Von der Pools Seite gibt es das virt/jail/demo Dataset.
Erstmal Platz machen:
zfs destroy -r virt/jail/demo
Installation
Um das nicht jedes mal von Hand zu machen gibt es die bootstrap_jail
Scripte von der Setup Seite.
Die Datasets (-c) werden so angelegt:
bjail_dataset -c virt/jail demo
Das andere Script kann installieren:
bjail_install \
-z /usr/share/zone/Europe/Berlin \
-d /etc/resolv.conf \
-x \
-r \
-p \
-m \
-t \
/usr/jail/demo
Parameter
-
-x-
Installation durchführen (Script nimmt sonst fertige Installation an)
Lädt
$(uname -r | ✨)/base.txznach/var/tmp, checkt SHA & Ausweispapiere. Erst dann wird die Jail enpackt.
-
-
-z-
Setzt einen symlink auf
/etc/localtimeinnerhalb der JailDa Host & Jail gleich sind, passen “zufällig” die Pfade.
-
-
-d-
Kopiert eine
/etc/resolv.confin die JailHier die vom Host, aber je nach Setup bietet sich hier ein Template an
-
-
-r-
/etc/rc.confin der Jail vorbereitenclear_tmp_enable="YES" syslogd_flags="-ss" cron_flags="-J 60" sendmail_enable="NO" sendmail_submit_enable="NO" sendmail_outbound_enable="NO" sendmail_msp_queue_enable="NO"
-
-
-p-
/etc/periodic.confin der Jail vorbereitendaily_output="/var/log/daily.log" daily_show_badconfig="YES" daily_status_security_output="/var/log/daily.log" weekly_output="/var/log/weekly.log" weekly_show_badconfig="YES" weekly_status_security_output="/var/log/weekly.log" monthly_output="/var/log/monthly.log" monthly_show_badconfig="YES" monthly_status_security_output="/var/log/monthly.log" security_show_badconfig="YES"
-
-
-m-
/etc/motd.templatefür die Jail schreiben+===========+ | demo jail | +===========+
-
-
-t-
/etc/fstab.demofür den Host erzeugentmpfs /usr/jail/demo/tmp tmpfs rw,mode=1777 0 0 /usr/src /usr/jail/demo/usr/src nullfs ro 0 0Für
/tmpeintmpfsund der Source Tree wird vom Host in den Container gemounted.
-
Netzwerk
Beim Setup wurde zunächst nur eine Verbindung zur Installation sicher gestellt. Für die Jails kommt eine Bridge zum Zuge, darauf lauschen dann die Jails.
Bridge
Die /etc/rc.conf erweitern:
gateway_enable="NO"
ipv6_gateway_enable="NO"
cloned_interfaces="bridge0"
ifconfig_bridge0="inet <private v4 Adresse der Bridge>/32"
ifconfig_bridge0_ipv6="inet6 <private v6 Adresse der Bridge> prefixlen 128"
jail_enable="YES"
jail_reverse_stop="YES"
Wichtig - Bei diesem Setup muss gateway_enable & ipv6_gateway_enable
inaktiv sein, sonst wird die (virtuelle) MAC-Adresse durch das normale
Netzwerk-Interface durchgereicht. Der Hoster mag sowas nicht und schickt
dann böse Mails 🙈.
Zu einem herkömmlichen Setup mit geklontem lo1 Interface gibt es
noch wenig Unterschied. Jetzt allerdings schon eine Bridge zu nutzen
lässt aber die Möglichkeit offen einige Jails mit VNET laufen zu lassen.
Firewall
Die /etc.pf.conf anpassen:
# public addresses
ip_igb0_p4 = "<v4 Adresse vom Server>"
ip_igb0_p6 = "<v6 Adresse vom Server>"
# jail addresses
ip_j_demo_p4 = "<v4 Adresse der Jail>"
ip_j_demo_p6 = "<v6 Adresse der Jail>"
# tables
table <tbl_allow> const { "my.other.host.example.net", "dyndns.example.org" }
table <tbl_block> persist {}
# services hosted on this box
# 60000: mosh
inbound_tcp = "{ telnet }"
inbound_udp = "{ 60000:60010 }"
# services consumed by this box
outbound_tcp = "{ ssh, telnet, domain, http, https, ftp }"
outbound_udp = "{ domain, ntp }"
# services hosted inside jails
inbound_tcp_j_demo = "{ http, https }"
inbound_udp_j_demo = "{}"
# icmp types
icmp_types_p4 = "{ echoreq, unreach }"
icmp_types_p6 = "{ echoreq, echorep, unreach, toobig, timex, routersol, routeradv, neighbrsol, neighbradv, redir }"
# allow loopback traffic
set skip on { lo0, bridge0 }
# do not reject, just drop
set block-policy drop
# incoming traffic is normalized and defragmented
scrub in on igb0 all fragment reassemble
# outbound traffic from jails
nat pass on igb0 inet from (bridge0:network) to any -> $ip_igb0_p4
nat pass on igb0 inet6 from (bridge0:network) to any -> $ip_igb0_p6
# redirect traffic into jails
rdr pass log on igb0 inet proto tcp from any to (igb0:network) port $inbound_tcp_j_demo -> $ip_j_demo_p4
#rdr pass log on igb0 inet proto udp from any to (igb0:network) port $inbound_udp_j_demo -> $ip_j_demo_p4
rdr pass log on igb0 inet6 proto tcp from any to (igb0:network) port $inbound_tcp_j_demo -> $ip_j_demo_p6
#rdr pass log on igb0 inet6 proto udp from any to (igb0:network) port $inbound_udp_j_demo -> $ip_j_demo_p6
# default rule - block all
block log all
# apply tables
block drop in from <tbl_block> to any
pass in from <tbl_allow> to any
# allow ping
pass inet proto icmp all icmp-type $icmp_types_p4 keep state
pass inet6 proto icmp6 all icmp6-type $icmp_types_p6 keep state
# allow access to outside world
pass out proto tcp to any port $outbound_tcp keep state
pass out proto udp to any port $outbound_udp keep state
# allow outside access into this box
pass in log proto tcp to any port $inbound_tcp keep state (max-src-conn 5, max-src-conn-rate 2/10, overload <tbl_block> flush global)
pass in log proto udp to any port $inbound_udp keep state (max-src-conn 5, max-src-conn-rate 2/10, overload <tbl_block> flush global)
Somit wird jeder Traffic auf Port 80 & 443 in die Demo-Jail gesteckt, raus
kommt diese fein über ein NAT…
Jail Config
Jetzt noch schnell die losen Enden zusammen binden.
Die /etc/jail.conf erstellen:
path = "/usr/jail/${name}";
mount.fstab = "/etc/fstab.${name}";
mount.devfs;
host.hostname = "${name}";
exec.clean;
exec.consolelog = "/var/log/jail_console_${name}.log";
exec.system_user = "root";
exec.jail_user = "root";
exec.start = "";
exec.start += "/bin/sh /etc/rc";
exec.stop += "/bin/sh /etc/rc.shutdown jail";
demo {
ip4.addr = "bridge0|<v4 Adresse der Jail>";
ip6.addr = "bridge0|<v6 Adresse der Jail>";
}
Das müsste alles gewesen sein. Mit einem service jail start demo sollte
diese starten. Ein Login in die Jail geht so: jexec demo login -f root.