如何在FreeBSD上设置PF防火墙来保护Web服务器
时间:2020-01-09 10:39:43 来源:igfitidea点击:
如何在FreeBSD服务器上设置带有PF的防火墙,以使用单个公共IP地址和接口保护Web服务器?
PF是数据包过滤器的首字母缩写。
它是为OpenBSD创建的,但已移植到FreeBSD和其他操作系统。
这是一个有状态的数据包过滤引擎。
本教程将向您展示如何在FreeBSD 10.x和11.x服务器上使用PF设置防火墙来保护您的Web服务器。
步骤1开启PF防火墙
您需要在/etc/rc.conf文件中添加以下三行:
# echo 'pf_enable="YES"' >> /etc/rc.conf # echo 'pf_rules="/usr/local/etc/pf.conf"' >> /etc/rc.conf # echo 'pflog_enable="YES"' >> /etc/rc.conf # echo 'pflog_logfile="/var/log/pflog"' >> /etc/rc.conf
其中:
pf_enable =" YES"
开启PF服务。pf_rules ="/usr/local/etc/pf.conf"
从该文件读取PF规则。pflog_enable =" YES"
为PF启用日志记录支持。pflog_logfile ="/var/log/pflog"
pflogd应该其中存储日志文件的文件,即,将日志存储在/var/log/pflog文件中。
步骤2在/usr/local/etc/pf.conf中创建防火墙规则
执行以下命令:
# vi /usr/local/etc/pf.conf
追加以下PF规则集:
# vim: set ft=pf # /usr/local/etc/pf.conf ## Set your public interface ## ext_if="vtnet0" ## Set your server public IP address ## ext_if_ip="172.xxx.yyy.zzz" ## Set and drop these IP ranges on public interface ## martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \ 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \ 0.0.0.0/8, 240.0.0.0/4 }" ## Set http(80)/https (443) port here ## webports = "{http, https}" ## enable these services ## int_tcp_services = "{domain, ntp, smtp, www, https, ftp, ssh}" int_udp_services = "{domain, ntp}" ## Skip loop back interface - Skip all PF processing on interface ## set skip on lo ## Sets the interface for which PF should gather statistics such as bytes in/out and packets passed/blocked ## set loginterface $ext_if ## Set default policy ## block return in log all block out all # Deal with attacks based on incorrect handling of packet fragments scrub in all # Drop all Non-Routable Addresses block drop in quick on $ext_if from $martians to any block drop out quick on $ext_if from any to $martians ## Blocking spoofed packets antispoof quick for $ext_if # Open SSH port which is listening on port 22 from VPN 139.xx.yy.zz Ip only # I do not allow or accept ssh traffic from ALL for security reasons pass in quick on $ext_if inet proto tcp from 139.xxx.yyy.zzz to $ext_if_ip port = ssh flags S/SA keep state label "USER_RULE: Allow SSH from 139.xxx.yyy.zzz" ## Use the following rule to enable ssh for ALL users from any IP address # ## pass in inet proto tcp to $ext_if port ssh ### [ OR ] ### ## pass in inet proto tcp to $ext_if port 22 # Allow Ping-Pong stuff. Be a good sysadmin pass inet proto icmp icmp-type echoreq # All access to our Nginx/Apache/Lighttpd Webserver ports pass proto tcp from any to $ext_if port $webports # Allow essential outgoing traffic pass out quick on $ext_if proto tcp to any port $int_tcp_services pass out quick on $ext_if proto udp to any port $int_udp_services # Add custom rules below
保存并关闭文件。
要检查语法错误,请运行:
# service pf check
或者
/etc/rc.d/pf check
或者
# pfctl -n -f /usr/local/etc/pf.conf
步骤3启动PF防火墙
请注意,您可能会通过基于ssh的会话从服务器断开连接:
启动PF
# service pf start
停止PF
# service pf stop
检查PF是否存在语法错误
# service pf check
重新启动PF
# service pf restart
查看PF状态
# service pf status
输出示例:
Status: Enabled for 0 days 00:02:18 Debug: Urgent Interface Stats for vtnet0 IPv4 IPv6 Bytes In 19463 0 Bytes Out 18541 0 Packets In Passed 244 0 Blocked 3 0 Packets Out Passed 136 0 Blocked 12 0 State Table Total Rate current entries 1 searches 395 2.9/s inserts 4 0.0/s removals 3 0.0/s Counters match 19 0.1/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 0 0.0/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
启动/停止/重新启动pflog服务的命令
执行以下命令:
# service pflog start # service pflog stop # service pflog restart
步骤4 pfctl命令快速入门
您需要使用pfctl命令查看PF规则集和参数配置,包括来自数据包过滤器的状态信息。
让我们查看所有常见命令:
显示PF规则信息
# pfctl -s rules
输出示例:
block return in log all block drop out all block drop in quick on ! vtnet0 inet from 172.xxx.yyy.zzz/24 to any block drop in quick inet from 172.xxx.yyy.zzz/24 to any pass in quick on vtnet0 inet proto tcp from 139.aaa.ccc.ddd to 172.xxx.yyy.zzz/24 port = ssh flags S/SA keep state label "USER_RULE: Allow SSH from 139.aaa.ccc.ddd" pass inet proto icmp all icmp-type echoreq keep state pass out quick on vtnet0 proto tcp from any to any port = domain flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = ntp flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = smtp flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = http flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = https flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = ftp flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = ssh flags S/SA keep state pass out quick on vtnet0 proto udp from any to any port = domain keep state pass out quick on vtnet0 proto udp from any to any port = ntp keep state
显示每个规则的详细输出
# pfctl -v -s rules
为每个规则添加带有详细输出的规则编号
# pfctl -vvsr show
显示状态
# pfctl -s state # pfctl -s state | more # pfctl -s state | grep 'something'
如何从CLI禁用PF
# pfctl -d
如何从CLI启用PF
# pfctl -e
如何从CLI刷新所有PF规则/nat /表
# pfctl -F all
输出示例:
rules cleared nat cleared 0 tables deleted. 2 states cleared source tracking entries cleared pf: statistics cleared pf: interface flags reset
如何仅从CLI刷新PF规则
# pfctl -F rules
如何仅从CLI刷新队列
# pfctl -F queue
如何从CLI刷新不属于任何规则的所有统计信息
# pfctl -F info
如何从CLI清除所有计数器
# pfctl -z clear
步骤5请参阅PF日志
PF日志为二进制格式。
要查看它们,请执行:
# tcpdump -n -e -ttt -r /var/log/pflog
要查看实时日志运行:
# tcpdump -n -e -ttt -i pflog0