IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    macOS 上的 pf 与 Linux 上的 iptables:差异与配置

    血衫非弧の一存发表于 2024-07-29 00:00:00
    love 0

    在管理防火墙规则和网络包过滤时,macOS 和 Linux 系统各自采用了不同的工具。macOS 使用 pf(Packet Filter),而 Linux 则使用 iptables。

    这篇文章展示如何在 macOS 上配置 pf 规则以允许特定 IP 地址访问 SSH 端口。

    pf 和 iptables 的主要区别

    规则处理顺序

    • iptables:按顺序处理规则,从上到下,遇到匹配的规则后就停止继续匹配。因此,规则的顺序非常重要。
    • pf:规则处理更为复杂,并不总是按顺序匹配。pf 会根据规则的类型和其他因素进行匹配,允许更加灵活的规则设置。

    配置文件和语法

    • iptables:使用命令行工具进行配置,规则保存为脚本文件(通常是 bash 脚本)。配置文件不具备特定的结构。
    • pf:配置文件(通常是 /etc/pf.conf)有固定的结构和语法,更加人性化和易于管理。

    功能特性

    • iptables:基于链的架构,有 filter、nat、mangle、raw 等不同的表。每个表包含若干链,每个链包含若干规则。
    • pf:支持锚(anchors)和表(tables),规则可以引用其他规则集,通过使用 scrub、nat、rdr、queue 等关键字提供高级功能。

    pf 规则处理示例

    在 pf 中,规则并非简单地按顺序处理:

    # /etc/pf.conf 示例
    block in all  # 默认阻止所有入站流量
    
    pass in proto tcp from xx.xx.xx.xx to any port 22  # 允许特定 IP 的流量
    
    # 其他规则...
    

    在这个示例中,即使 block in all 在前面,后面的 pass 规则也会正确匹配并允许来自特定 IP 地址的流量连接到 22 端口。这与 iptables 的行为不同,iptables 会在遇到第一个匹配的 block 规则时停止处理。

    iptables 规则处理示例

    相同的规则在 iptables 中的配置如下:

    # 先允许特定 IP 地址的流量
    iptables -A INPUT -p tcp -s xx.xx.xx.xx --dport 22 -j ACCEPT
    
    # 然后阻止所有其他流量
    iptables -A INPUT -p tcp --dport 22 -j DROP
    

    在 iptables 中,规则的顺序非常重要。我们必须先允许特定的流量,然后再阻止所有其他流量。

    在 macOS 上配置 pf 规则

    为了在 macOS 上设置防火墙规则,只允许特定的 IP 地址连接到 SSH 端口(22),你需要编辑 pf 配置文件,并确保这些规则在系统启动时自动应用。

    默认规则:

    image-20240729下午51906975

    image-20240729下午54033902

    pf 的 anchor 和 load anchor 类似于 iptables 的链和表,用于组织和加载规则。
    pf 的 nat-anchor 和 rdr-anchor 处理 NAT 和端口重定向,类似于 iptables 的 nat 表和 PREROUTING 链。
    pf 的 scrub-anchor 和 dummynet-anchor 提供类似于 iptables 的流量处理和带宽限制功能。
    

    执行命令sudo pfctl -sr,输出是:

    No ALTQ support in kernel
    ALTQ related functions disabled
    scrub-anchor "com.apple/*" all fragment reassemble
    scrub-anchor "com.apple.internet-sharing" all fragment reassemble
    anchor "com.apple/*" all
    anchor "com.apple.internet-sharing" all
    

    解释一下:

    1. No ALTQ support in kernel / ALTQ related functions disabled:
      • ALTQ(ALTernate Queueing)是用于流量整形的工具,但我的 macOS 内核没有启用对 ALTQ 的支持,因此与 ALTQ 相关的功能被禁用。
    2. scrub-anchor “com.apple/*” all fragment reassemble:
      • 这个规则表示 macOS 会对所有通过 com.apple/* 锚点的流量进行 scrub 操作。scrub 是一种重新组装 IP 分片的操作,用于处理和纠正 IP 数据包中的潜在问题。
    3. scrub-anchor “com.apple.internet-sharing” all fragment reassemble:
      • 这个规则与上一个类似,但它专门用于通过 com.apple.internet-sharing 锚点的流量。它也会对这些流量进行 scrub 操作,重新组装 IP 分片。
    4. anchor “com.apple/*” all:
      • 这个规则表示所有通过 com.apple/* 锚点的流量将被转发到与 com.apple/* 匹配的子规则进行处理。anchor 是一种将规则分组的方法,允许对特定流量应用一组规则。
    5. anchor “com.apple.internet-sharing” all:
      • 这个规则与上一个类似,但它专门用于通过 com.apple.internet-sharing 锚点的流量。这些流量将被转发到与 com.apple.internet-sharing 匹配的子规则进行处理。

    这些规则主要是处理和转发由 macOS 系统创建的流量锚点和规则,特别是那些与互联网共享和其他系统功能相关的规则。

    scrub 操作用于重新组装分片的 IP 数据包,以确保它们在传输过程中没有问题,

    anchor 规则则用于将流量转发到特定的子规则进行进一步处理。

    编辑 pf.conf 文件

    1. 打开并编辑 /etc/pf.conf 文件:
      sudo vim /etc/pf.conf
      
    2. 添加新规则: 在合适的位置(例如在 scrub-anchor 和 nat-anchor 之后),在我本机上,我放到了最后一行,插入以下规则:

      block in proto tcp from any to any port 22
      pass in proto tcp from xx.xx.xx.xx to any port 22
      
    3. 保存并关闭文件。

    4. 重新加载 pf 配置:
      sudo pfctl -f /etc/pf.conf  # 重新加载配置
      sudo pfctl -e                # 启用 pf
      sudo pfctl -sr               # 查看当前规则以确认加载
      

    在 macOS 上配置配置 pf 自启动脚本

    1. 创建启动脚本文件: 在 /usr/local/bin 目录下创建一个启动脚本文件:

      sudo vim /usr/local/bin/startup.sh
      
    2. 在脚本文件中添加以下内容:
      #!/bin/bash
      
      # Enable and load pf rules
      sudo pfctl -e
      sudo pfctl -f /etc/pf.conf
      
      # 如果还有其他需求,可以一起加进来,例如增加一条路由
      sudo route -n add -net xx.xx.0.0 -netmask 255.255.0.0 xx.xx.xx.1
      
    3. 使脚本可执行:

      sudo chmod +x /usr/local/bin/startup.sh
      

    配置启动项:

    1. 创建 LaunchDaemon 配置文件: 在 /Library/LaunchDaemons 目录下创建一个 plist 文件:
      sudo vim /Library/LaunchDaemons/com.custom.startup.plist
      
    2. 在 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>com.custom.startup</string>
          <key>ProgramArguments</key>
          <array>
              <string>/usr/local/bin/startup.sh</string>
          </array>
          <key>RunAtLoad</key>
          <true/>
          <key>KeepAlive</key>
          <false/>
      </dict>
      </plist>
      
    3. 设置适当的权限:
      sudo chown root:wheel /Library/LaunchDaemons/com.custom.startup.plist
      sudo chmod 644 /Library/LaunchDaemons/com.custom.startup.plist
      

    测试和验证

    1. 加载并测试 LaunchDaemon:
      sudo launchctl load /Library/LaunchDaemons/com.custom.startup.plist
      
    2. 重启电脑以验证配置: 在重启后,确保 pf 规则和路由已正确应用。可以通过以下命令检查:
      sudo pfctl -sr  # 查看当前的 pf 规则
      sudo netstat -rn     # 查看路由表
      


沪ICP备19023445号-2号
友情链接