Freebsd. Filtering PF traffic

Introduction



  1. FreeBSD PF Firewall
  2. 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
      
      







PF . . , . . 35 9 .







, (NAT). , !








All Articles