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¶
Starting and restarting of the firewall 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:05 Debug: Urgent
Interface Stats for bridge0 IPv4 IPv6
Bytes In 340786839 0
Bytes Out 53359463 0
Packets In
Passed 452561 0
Blocked 697 0
Packets Out
Passed 416568 0
Blocked 0 0
State Table Total Rate
current entries 12
searches 909778 181955.6/s
inserts 15410 3082.0/s
removals 15398 3079.6/s
Counters
match 16592 3318.4/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 224 44.8/s
proto-cksum 0 0.0/s
state-mismatch 0 0.0/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
/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