企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## PF 防火墙 当我们使用 Linux 时,iptables 能够很容易的实现对入站和出站的访问控制,也能够很容易的完成端口转发与 NAT 转化等需求。那么在 Mac 上该怎么做到呢? 实际上,macOS 预置了从 OpenBSD 引入的 PF 防火墙。 ## 基本结构 PF Firewall 主要由以下三个文件完成配置和加载 * **/etc/pf.conf** PF Firewall 的配置文件,规则的存放位置,锚点 (anchors) 文件也可以在这里被指定进行加载。 * **/etc/pf.conf/anchors/*** pf.conf 中需要加载的锚点文件的存放目录。 * **/System/Library/LaunchDaemons/com.apple.pfctl.plist** 在启动时执行 "pfctl -f /etc/pf.conf" 完成 PF Firewall 的加载。 ## 修改配置文件 你可以直接修改 /etc/pf.conf, 但是该文件会在系统每次升级后被重置。因此,最好的办法是另外写一份配置文件 /opt/pf.conf,然后设置为开机自动加载。 > 配置文件 en3 是当前正在使用的物理网卡,请根据情况配置 ```config # PF Set set block-policy drop set fingerprints '/etc/pf.os' set skip on lo0 scrub-anchor "com.apple/*" # NAT NET nat on en3 from 198.51.100.0/24 to any -> (en3) # TABLES table <Everyone> {0.0.0.0/0 ::/0 } persist table <192.168-net> {192.168.0.0/16 } persist table <10-net> {10.0.0.0/8 } persist table <172.16-net> {172.16.0.0/12 } persist table <IPv6-net> {fe80::/10 } persist table <169.254-net> {169.254.0.0/16 } persist table <bruteforce> { } persist table <Blacklist> { 104.24.28.50 104.24.29.50 } persist table <sshguard> { } persist table <spam> { } persist table <NatLanInterfaces> {en3 } # Inbond Block block in quick from <sshguard> to any label "SSHGuard_BruteForce" block in quick proto tcp from <spam> to any port {25 465 } block in log quick from <Blacklist> to any label "BlackList_IN" block out log quick from any to <Blacklist> label "BlackList_OUT" block in quick from no-route to any label "NO_BACK_ROUTE" block in quick from urpf-failed label "uRPF" #block log inet all label "Generic_blocks_(IPv4)" block log inet6 all label "Generic_blocks_(IPv6)" # MDNS pass proto igmp allow-opts pass quick from any to {224.0.0.0/4 ff00::/8} allow-opts pass in quick proto udp from any port {5353} to any port {5353} allow-opts pass out quick proto udp from any port {5353} to any port {5353} allow-opts # APPLE ANCHOR anchor 'com.apple/*' load anchor 'com.apple' from '/etc/pf.anchors/com.apple' # INBOUND ALLOW block in quick from <bruteforce> to any label "Inbound" block in proto {tcp, udp} from any to any port {49152:65535} label "Inbound" block in proto {tcp, udp} from any to any port {53 67 68 123 389 546 547 636 5353 5354} label "Inbound" pass in proto {tcp, udp} from <192.168-net> to any port {53 67 68 123 389 546 547 636 5353 5354} flags S/SA keep state label "Inbound" pass in proto {tcp, udp} from <10-net> to any port {53 67 68 123 389 546 547 636 5353 5354} flags S/SA keep state label "Inbound" pass in proto {tcp, udp} from <172.16-net> to any port {53 67 68 123 389 546 547 636 5353 5354} flags S/SA keep state label "Inbound" pass in proto {tcp, udp} from <IPv6-net> to any port {53 67 68 123 389 546 547 636 5353 5354} flags S/SA keep state label "Inbound" pass in proto {tcp, udp} from <192.168-net> to any port {49152:65535} flags S/SA keep state label "Inbound" pass in proto {tcp, udp} from <10-net> to any port {49152:65535} flags S/SA keep state label "Inbound" pass in proto {tcp, udp} from <172.16-net> to any port {49152:65535} flags S/SA keep state label "Inbound" pass in proto {tcp, udp} from <IPv6-net> to any port {49152:65535} flags S/SA keep state label "Inbound" # OUTBOUND pass out proto {tcp, udp} from any to any port {1:65535} label "Outbound" # OUTBOUND NAT pass inet proto {tcp, udp} from { 198.51.100.0/24 } to !<NatLanInterfaces> port {1:65535} label "NAT_Clients" ``` ## 创建执行脚本 为了完成 pf.conf 的加载,我们需要创建一份开机脚本来加载 pf.conf 并打开系统的路由转发功能,这是 NAT 规则所需要的。 创建 /etc/mypfctl.sh,并修改权限 ``` chown root:wheel /etc/mypfctl.sh chmod a+x /etc/mypfctl.sh ``` > 脚本文件 ``` #!/bin/sh # Trap On TERM Signals trap 'exit 1' 15 # Wait For All The Interfaces ipconfig waitall sleep 5 # System Sysctl sysctl -w net.inet6.ip6.fw.verbose=0 sysctl -w net.inet.ip.fw.verbose=0 sysctl -w net.inet.ip.fw.verbose_limit=0 # Enable Interface Forwarding sysctl -w net.inet.ip.forwarding=1 # Enable PF And Load Rules /sbin/pfctl -e /sbin/pfctl -Ef /opt/pf.conf # Enable PF Logs ifconfig pflog0 create # /usr/local/bin/pfloggerd /usr/sbin/tcpdump -lnettti pflog0 | /usr/bin/logger -t pf -p local2.info # Exit With a Clean Status exit 0 ``` ## 设置开机启动 /etc/mypfctl.sh 虽然已经创建完成,但是并不会在开机时自动执行。可以使用 Launch Daemon 来完成 /etc/mypfctl.sh 的开机自动加载。 * 创建 /Library/LaunchDaemons/pf.mypfctl.plist 并修改权限。 ``` chmod 644 /Library/LaunchDaemons/pf.mypfctl.plist chown root:wheel /Library/LaunchDaemons/pf.mypfctl.plist ``` * 编辑 /Library/LaunchDaemons/pf.mypfctl.plist ``` <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>pf.firewall</string> <key>ProgramArguments</key> <array> <string>/bin/sh</string> <string>-c</string> <string>/etc/mypfctl.sh</string> </array> <key>RunAtLoad</key> <true/> <key>ExitTimeOut</key> <integer>1</integer> </dict> </plist> ``` ## 查看实时日志 ``` clear; sudo /usr/sbin/tcpdump -lnettti pflog0 ```