Introduction
- FreeBSD PF Firewall
- PF traffic filtering <- You are here
In the last article, we discussed what PF is in general, its main features, and created a simple config that uses filtering rules and macros. Today we will deal with tags and learn how to filter traffic according to various conditions in a more advanced way. Thanks to the users who commented on the previous article for their interest.
This time, let's try different options for more advanced filtering:
- Macros in various places in the config file.
- Lists are a set of parameters. PF will expand it into separate rules.
- Rules limiting the number of connections from one IP, their frequency.
- Tables. This is a list of IP addresses that the rule can compare against. Possible dynamic filling options. And checking the status of our tables.
The task will be like this:
- Allow access from trusted IPs to any port
- Create ban-list loading from file
- crm api 8080 8443
- 80 443 CRM API
- - 22 -
- DDOS DOS 80 443, -
, .
. ( ) . , IP ( ), tcp, . IP , .
# macros section If="re0" # IfIp="192.169.12.10" # IP permit_tcp_ports="22,53" permit_udp_ports="53,123" web_ports = "http,https"
:
pass in on $IfIp inet proto tcp from any to $IfIp port {$permit_tcp_ports}
:
pfctl -sr ... pass in on re0 inet proto tcp from any to 192.169.12.10 port = ssh flags S/SA keep state pass in on re0 inet proto tcp from any to 192.169.12.10 port = domain flags S/SA keep state ...
, . , . . flags tcp , . S/SA โ SYN. , , .
Keep state โ . , . (state table), .
quick. , . :
pass in quick on em0 from { 192.168.1.0/24 } to 192.168.1.1
โ PF. , , . , , , , , , . .
:
- const โ . IP " "
- counters โ IP
- persist โ ,
persist. .
:
# , table <admins> { 173.18.12.22, 173.18.12.45 }
:
pass in quick on $If from <admins> to $IfIp
, IP , , IP .
:
# , table <block_list> file "/etc/pf.blocklist.conf"
:
block in quick on $If from <block_list> to any
<simple-ban> $If
:
# cat /etc/pf.blocklist.conf 1.1.1.1 111.12.46.0/24 !111.12.46.17
. IP 1.1.1.1, 111.12.46.0/24, IP 111.12.46.17. . :
pfctl -t block_list -T replace -f /etc/pf.blocklist.conf 3 addresses added.
IP , . . cron , . , , :
# cat /etc/pf.blocklist.conf ya.ru 1.2.3.4 mail.ru
, :
# pfctl -t blocklist -T show 1.2.3.4 87.250.250.242 94.100.180.200 94.100.180.201 217.69.139.200 217.69.139.202 2a00:1148:db00:0:b0b0::1 2a02:6b8::2:242
/ :
# pfctl -t blocklist -T add 123.12.34.5 # pfctl -t blocklist -T delete 123.12.34.5
, , .
IP . .
# pfctl -t blocklist -T test 1.2.3.4 1/1 addresses match. # pfctl -t blocklist -T test 1.1.1.1 0/1 addresses match. # pfctl -t blocklist -T test ya.ru 2/2 addresses match. # pfctl -t blocklist -T test 1.1.1.1 1.2.3.4 1/2 addresses match.
cron :
# cat /etc/crontab ... 0 * * * * root /sbin/pfctl -t block_list -T replace -f /etc/pf.blocklist.conf ...
http(s) 8080 8443. , :
permit_corp_ports ="http,https" # . permit_add_tcp_ports = "8080,8443" # ,
, , :
table <corp_res> file "/etc/pf.corpres.conf" # , http(s)
, :
# cat /etc/pf.corpres.conf example.com
:
pass in quick on $If proto tcp from <corp_res> to $IfIp ports { $permit_add_tcp_ports } pass out quick on $If proto tcp from $IfIp to <corp_res> port { $permit_corp_ports }
. ssh. PF โ , , .
:
table <block_ssh> persist # ssh. , PF . persist
persist โ , . , PF .
:
block in quick on $If proto tcp from <block_ssh> to any port 22 pass in on $If proto tcp to $IfIp port { 22 } \ keep state (max-src-conn 10, max-src-conn-rate 3/10, \ overload <block_ssh> flush)
max-src-conn 10 โ 10 , max-src-conn-rate 3/10 โ 3 10 , overload <block_ssh> โ , flush โ , .
โ -.
:
table <block_web> persist #
:
# block in quick on $If from <block_web> pass in on $If proto tcp to $IfIp port { $permit_tcp_ports } \ synproxy state (max-src-conn 100, max-src-conn-rate 20/1, \ overload <block_web> flush global)
. Synproxy โ syn , synflood . flush global -, .
:
pfctl -t block_ssh -T expire 3600
, . :
... 0 * * * * root /sbin/pfctl -t block_ssh -T expire 3600 0 * * * * root /sbin/pfctl -t block_web -T expire 3600 ...
.
# cat /etc/pf.conf # macros section If="re0" # IfIp="192.169.12.10" # ip permit_tcp_ports="22,53" permit_udp_ports="53,123" web_ports = "http,https" permit_corp_ports ="http,https" permit_add_tcp_ports = "8080,8443" # table section # , table <admins> { 192.168.11.0/24, 173.18.12.22, 173.18.12.45 } # , , table <block_list> file "/etc/pf.blocklist.conf" # , hppt(s) table <corp_res> file "/etc/pf.corpres.conf" # ssh. , PF . # persist table <block_ssh> persist # table <block_web> persist # options section # , set block-policy return # , set skip on lo0 # scrub section scrub in all # # Queueing section # # nat section # , # filtering section # , , # . block all # # quick - . pass in quick on $If from <admins> to $IfIp pass in quick on $If proto tcp from <corp_res> to $IfIp \ port { $permit_add_tcp_ports } # ssh block in quick on $If proto tcp from <block_ssh> port 22 pass in on $If proto tcp to $IfIp port { 22 } \ keep state (max-src-conn 10, max-src-conn-rate 3/10, \ overload <block_ssh> flush) # Web block in quick on $If from <block_web> pass in on $If proto tcp to $IfIp port { $web_ports } \ keep state (max-src-conn 100, max-src-conn-rate 20/1, \ overload <block_web> flush global) # pass out quick on $If proto tcp from $IfIp to <corp_res> port { $permit_corp_ports } # # udp# tcp pass out proto udp to port { $permit_tcp_ports } # udp pass out proto udp to port { $permit_udp_ports } pass out inet proto icmp # icmp
, .
:
# pfctl -nf pf.conf
:
# pfctl -f pf.conf
, (NAT). , !