Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.txz nach /var/tmp, checkt SHA & Ausweispapiere. Erst dann wird die Jail enpackt.

  • -z

    • Setzt einen symlink auf /etc/localtime innerhalb der Jail

      Da Host & Jail gleich sind, passen “zufällig” die Pfade.

  • -d

    • Kopiert eine /etc/resolv.conf in die Jail

      Hier die vom Host, aber je nach Setup bietet sich hier ein Template an

  • -r

    • /etc/rc.conf in der Jail vorbereiten

      clear_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.conf in der Jail vorbereiten

      daily_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.template für die Jail schreiben

      +===========+
      | demo jail |
      +===========+
      
  • -t

    • /etc/fstab.demo für den Host erzeugen

      tmpfs       /usr/jail/demo/tmp        tmpfs   rw,mode=1777    0       0
      /usr/src    /usr/jail/demo/usr/src    nullfs  ro              0       0
      

      Für /tmp ein tmpfs und 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.

last update 0214624 • 2025-11-27 18:45:31 +0100