Skip to content
Matt Simerson edited this page Oct 5, 2023 · 5 revisions

Mail Toaster runs all the micro-services (both jails and VMs) on private addresses. Jails are isolated from public networks so redirection, network address translation (NAT) and firewall rules are used to pass only the necessary traffic.

Host

The pf.conf file on the host is similar to this:

## Macros

ext_if="em0"
table <ext_ip4> { 10.0.1.209 }
table <ext_ip6> { 2602:61:7e0a:8400:20c:29ff:fedb:44d8 }

table <bruteforce> persist
table <sshguard> persist

## Translation rules

# default route to the internet for jails
nat on $ext_if inet  from 172.16.15.0/12 to any -> ($ext_if)
nat on $ext_if inet6 from (lo1) to any -> <ext_ip6>

nat-anchor "nat/*"

## Redirection

rdr-anchor "rdr/*"

## Filtering rules

# block everything by default. Test before enabling!
#block in log on $ext_if

block in quick from <bruteforce>

block in quick inet  proto tcp from <sshguard> to any port { 22 }
block in quick inet6 proto tcp from <sshguard> to any port { 22 }

anchor "allow/*"

Jails

Each jail inserts PF rules when it starts and removes them when it stops. This happens using jail.conf hooks to call a shell script that loads named config files. From data/etc/jail.conf.d/dovecot.conf:

    exec.created = "/data/dovecot/etc/pf.conf.d/pfrule.sh load";
    exec.poststop = "/data/dovecot/etc/pf.conf.d/pfrule.sh unload";

pfrule.sh

pfrule.sh lists all .conf files in its working directory and attempts to [un]load them based on the file's name. Therefore, the base name of each config file must match an anchor in /etc/pf.conf. Example:

ls /data/dovecot/etc/pf.conf.d/
pfrule.sh*    nat.conf  rdr.conf allow.conf

rdr.conf

# to permit legacy users to access insecure POP3 & IMAP, add their IPs/masks
table <insecure_mua> persist file "/data/dovecot/etc/pf.conf.d/insecure_mua"

rdr inet  proto tcp from any to <ext_ip4> port { 993 995 } -> 172.16.15.15
rdr inet6 proto tcp from any to <ext_ip6> port { 993 995 } -> fd7a:e5cd:1fc1:186f:dead:beef:cafe:000f

rdr inet  proto tcp from <insecure_mua> to <ext_ip4> port { 110 143 } -> 172.16.15.15
rdr inet6 proto tcp from <insecure_mua> to <ext_ip6> port { 110 143 } -> fd7a:e5cd:1fc1:186f:dead:beef:cafe:000f

allow.conf

mua_ports = "{ 110 143 993 995 }"
table <mua_servers> { 172.16.15.15, fd7a:e5cd:1fc1:186f:dead:beef:cafe:000f }
pass in quick proto tcp from any to <mua_servers> port $mua_ports
Clone this wiki locally