370 Configure pf
Use case
Use the role vbotka.freebsd.pf to configure pf.
Tree
shell> tree .
.
├── ansible.cfg
├── host_vars
│ └── iocage_04.yml
├── iocage.ini
└── pb.yml
Synopsis
The Ansible controller connects the iocage host
iocage_04at IP 10.1.0.29 configured in/etc/rc.confcloned_interfaces="bridge0" create_args_bridge0="addm igb0" ifconfig_bridge0="inet 10.1.0.29/24" ifconfig_igb0="up -tso -vlanhwtso"
In the playbook
pb.ymlatiocage_04configure:blacklistd, fail2ban, and sshguard
nat
log all blocked
pass from localnet to any
Requirements
root privilege in the managed nodes.
Notes
TBD
Note
vbotka.freebsd.pf is the role pf in the collection vbotka.freebsd.
vbotka.freebsd_pf is the role freebsd_pf in the namespace vbotka.
Please make sure the versions are the same before you switch between them.
See also
FreeBSD Handbook Firewalls
FreeBSD Forum pf and bridge
ansible.cfg
[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false
[connection]
pipelining = true
Inventory iocage.ini
iocage_04 ansible_host=10.1.0.29
[iocage]
iocage_04
[iocage:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent
host_vars
host_vars/iocage_04.yml
pf_install: false
pf_blacklistd: true
pf_fail2ban: true
pf_sshguard: true
pf_enable: true
pf_blacklistd_enable: true
pf_fail2ban_enable: true
pf_sshguard_enable: true
pf_log_enable: true
pf_backup_conf: true
# /etc/pf.conf
pf_type: default2
pf_ext_if: bridge0
pf_log_all_blocked: log
pf_pass_icmp_types: [echoreq, unreach]
pf_pass_icmp6_types: [echoreq, unreach]
pf_local_net: 10.1.0.0/24
pf_macros:
ext_if: "{{ pf_ext_if }}"
localnet: "{{ pf_local_net }}"
logall: "{{ pf_log_all_blocked }}"
icmp_types: "{{ pf_pass_icmp_types }}"
icmp6_types: "{{ pf_pass_icmp6_types }}"
# pf blocks
pf_options:
- set skip on lo0
- set block-policy return
- set loginterface $ext_if
pf_tables:
- table <sshabuse> persist
pf_normalization:
- scrub in on $ext_if all fragment reassemble
pf_translation:
- nat on $ext_if from $localnet to any -> ($ext_if)
pf_filtering:
- antispoof for $ext_if
- "{{ pf_anchors }}"
- block $logall all
- pass inet proto icmp icmp-type $icmp_types
- pass inet6 proto icmp6 icmp6-type $icmp6_types
- pass from { self, $localnet } to any keep state
# blacklistd
pf_blacklistd_conf_local:
- {adr: ssh, type: stream, proto: '*', owner: '*', name: '*', nfail: '3', disable: 24h}
- {adr: ftp, type: stream, proto: '*', owner: '*', name: '*', nfail: '3', disable: 24h}
- {adr: smtp, type: stream, proto: '*', owner: '*', name: '*', nfail: '3', disable: 24h}
- {adr: smtps, type: stream, proto: '*', owner: '*', name: '*', nfail: '3', disable: 24h}
- {adr: submission, type: stream, proto: '*', owner: '*', name: '*', nfail: '3', disable: 24h}
- {adr: '*', type: '*', proto: '*', owner: '*', name: '*', nfail: '3', disable: '60'}
pf_blacklistd_flags: '-r'
pf_blacklistd_rcconf:
- {name: blacklistd_flags, value: "{{ pf_blacklistd_flags }}"}
Playbook pb.yml
- name: Test role vbotka.freebsd.pf
hosts: iocage
gather_facts: true
roles:
- vbotka.freebsd.pf
Playbook output - Install packages
(env) > ansible-playbook pb.yml -i iocage.ini -t pf_packages -e pf_install=true
PLAY [Test role vbotka.freebsd.pf] *********************************************
TASK [Gathering Facts] *********************************************************
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Packages: Install packages.] *************************
ok: [iocage_04]
PLAY RECAP *********************************************************************
iocage_04 : ok=2 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
Playbook output - Configure pf
Firewall starting and restarting breaks the ssh connections. See the handlers for details. As a consequence, both handlers starting and reloading don’t work properly and the ssh connection will stale. Therefore, let us first configure the rules
(env) > ansible-playbook pb.yml -i iocage.ini -e pf_enable=false
PLAY [Test role vbotka.freebsd.pf] *********************************************
TASK [Gathering Facts] *********************************************************
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-blacklistd: Stat /etc/rc.d/blacklistd] ********
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Blacklistd: Backup /etc/blacklistd.conf.orig] ********
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Blacklistd: Configure /etc/blacklistd.conf] **********
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-fail2ban: Stat /usr/local/etc/rc.d/fail2ban] ***
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Fail2ban: Configure /usr/local/etc/fail2ban/fail2ban.local] ***
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Fail2ban: Configure /usr/local/etc/fail2ban/jail.local] ***
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-sshguard: Stat /usr/local/etc/rc.d/sshguard] ***
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Configure sshguard.conf] *****************************
ok: [iocage_04] => (item={'key': 'BACKEND', 'value': '/usr/local/libexec/sshg-fw-pf'})
ok: [iocage_04] => (item={'key': 'WHITELIST_FILE', 'value': '/usr/local/etc/sshguard.whitelist'})
TASK [vbotka.freebsd.pf : Pfconf: Configure and validate rules using template default2-pf.conf.j2] ***
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-blacklistd: Enable and start blacklistd.] *****
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-blacklistd: Configure blacklistd.] ************
ok: [iocage_04] => (item={'name': 'blacklistd_flags', 'value': '-r'})
TASK [vbotka.freebsd.pf : Rcconf-fail2ban: Enable and start fail2ban.] *********
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-fail2ban: Configure fail2ban.] ****************
ok: [iocage_04] => (item={'name': 'fail2ban_flags', 'value': ''})
TASK [vbotka.freebsd.pf : Rcconf-sshguard: Enable and start sshguard.] *********
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-pf: Disable and stop pf.] *********************
changed: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-pflog: Enable and start pflog.] ***************
ok: [iocage_04]
RUNNING HANDLER [vbotka.freebsd.pf : Disable and stop pf] **********************
changed: [iocage_04]
PLAY RECAP *********************************************************************
iocage_04 : ok=18 changed=2 unreachable=0 failed=0 skipped=39 rescued=0 ignored=0
Playbook output - Enable pf
(env) > ansible-playbook pb.yml -i iocage.ini -t pf_rcconf_pf
PLAY [Test role vbotka.freebsd.pf] *********************************************
TASK [Gathering Facts] *********************************************************
ok: [iocage_04]
TASK [vbotka.freebsd.pf : Rcconf-pf: Enable and start pf.] *********************
changed: [iocage_04]
RUNNING HANDLER [vbotka.freebsd.pf : Start pf] *********************************
changed: [iocage_04]
PLAY RECAP *********************************************************************
iocage_04 : ok=3 changed=2 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
Result
pf status
(env) > ssh admin@10.1.0.29 sudo service pf status
Status: Disabled for 0 days 00:00:04 Debug: Urgent
Interface Stats for bridge0 IPv4 IPv6
Bytes In 0 0
Bytes Out 0 0
Packets In
Passed 233387 987
Blocked 394 0
Packets Out
Passed 0 0
Blocked 174948 0
State Table Total Rate
current entries 164
searches 426626 106656.5/s
inserts 8549 2137.2/s
removals 8385 2096.2/s
Counters
match 12205 3051.2/s
bad-offset 0 0.0/s
fragment 0 0.0/s
short 0 0.0/s
normalize 0 0.0/s
memory 0 0.0/s
bad-timestamp 0 0.0/s
congestion 0 0.0/s
ip-option 107 26.8/s
proto-cksum 872 218.0/s
state-mismatch 6 1.5/s
state-insert 0 0.0/s
state-limit 0 0.0/s
src-limit 0 0.0/s
synproxy 0 0.0/s
map-failed 0 0.0/s
translate 0 0.0/s
/etc/pf.conf
(env) > ssh admin@10.1.0.29 cat /etc/pf.conf
# Ansible managed
# template: default2-pf.conf.j2
# MACROS
ext_if = "bridge0"
localnet = "10.1.0.0/24"
logall = "log"
icmp_types = "{ echoreq, unreach }"
icmp6_types = "{ echoreq, unreach }"
# TABLES
table <sshabuse> persist
# OPTIONS
set skip on lo0
set block-policy return
set loginterface $ext_if
# NORMALIZATION
scrub in on $ext_if all fragment reassemble
# TRANSLATION
nat on $ext_if from $localnet to any -> ($ext_if)
# FILTERING
antispoof for $ext_if
anchor "blacklistd/*" in on $ext_if
anchor "f2b/*"
block $logall all
pass inet proto icmp icmp-type $icmp_types
pass inet6 proto icmp6 icmp6-type $icmp6_types
pass from { self, $localnet } to any keep state
# EOF