Pf example jails on loopback addr

From wikinotes

Jails need ip addresses, but since we are working with the real internet, we can't just bind any address on our public-facing network interface.

To work around this, we'll setup a clone of the loopback address, where to which we can bind any address in the private address range see RFC 1918.

NOTE:

I do not fully understand how the interface's address can communicate with the jail's address when they are using different netmasks - but I only have a fuzzy understanding of how netmasks work. I can confirm that this does work:

  • lo1: 172.16.1.1/24
  • jail: 172.16.1.*/32


Create a clone of the loopback addr lo0, which we will bind to an address in the private address-space.

#### /etc/rc.conf
cloned_interfaces="lo1"    # we clone the loopback iface
pf_enable="YES"            # enable pf

ifconfig_lo1="inet 172.16.1.1 netmask 255.255.255.0"
#### /etc/sysctl.conf
# ip forwarding must be enabled in order to use nat in pf.
net.inet.ip.forwarding=1
net.inet.ip6.forwarding=1
#### /etc/pf.conf
# variables
WAN_ipaddr = "192.168.1.1"      # your external ip
ext_if   = "vtnet0"             # a variable for interface with external traffic
jail_if  = "lo1"                # a variable for interface with internal traffic
jail_net = $jail_if:network     # all netwk-traffic from lo1

nat on $ext_if from $jail_net to any -> $WAN_ipaddr # forward traffic on all jail ifaces to external-interface
sudo service pf start               # start pf
sudo pfctl -nvf /etc/pf.conf        # test pf.conf - errors will be printed on stdout
sudo pfctl -F all  -f /etc/pf.conf  # flush all rules, then reapply rules from /etc/pf.conf

When you have decided on a port you'd like to forward (from WAN to your jail) You will need append it to your /etc/pf.conf.

melody_ip = "172.16.1.2/32"
melody_tcp_ports = "{ 80, 443 }"    # you may also configure a range of ports

# redirect traffic on ports 80/443 to the jail
rdr pass on $ext_if    inet proto tcp   to port 9999  -> $melody_ip port 80



sudo reboot     ## you'll need to reboot so the ip alias takes effect
#### /etc/jail.conf
yourhostname {
    mount.devfs;
    exec.start    = "/bin/sh /etc/rc";
    exec.strop    = "/bin/sh /etc/rc.shutdown";
    host.hostname = "yourhostname";
    path          = "/usr/home/j/yourhostname";
    mount.fstab   = "/etc/jails/yourhost.fstab";

    interface     = "lo1";
    ip4.addr      = 127.16.1.2/32   # (created on alias you just created)
                                    # take note of the /32 netmask 
                                    # (which is different from the interface's /24)
}

See

https://www.kirkg.us/posts/how-to-configure-a-freebsd-jail-on-a-digital-ocean-droplet/
http://srobb.net/pf.html
https://www.openbsd.org/faq/pf/nat.html
https://forums.freebsd.org/threads/30063/