如何使用 pf 在 macOS 上设置简单的端口转发? “规则必须按顺序排列:选项、规范化、排队、翻译、过滤”

如何使用 pf 在 macOS 上设置简单的端口转发? “规则必须按顺序排列:选项、规范化、排队、翻译、过滤”

我正在尝试使用将流量从 Mac A 端口 5800 传递到端口 5900 上的 Mac pfB。

这是预期的行进路径:

Client to port 5800 → Router (Yes, port forwarding is setup here) → Mac with PF → PF → 192.168.1.246 port 5900

以下是我打算使用的规则(也许是错误的):

rdr pass inet proto tcp from any to any port 5800 -> 192.168.1.246 port 5900

问题1

当我直接添加规则/etc/pf.conf并运行时sudo pfctl -f /etc/pf.conf,我得到:

$ sudo pfctl -f /etc/pf.conf
pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.

No ALTQ support in kernel
ALTQ related functions disabled
/etc/pf.conf:29: Rules must be in order: options, normalization, queueing, translation, filtering
pfctl: Syntax error in config file: pf rules not loaded

我的配置文件如下:

#
# Default PF configuration file.
#
# This file contains the main ruleset, which gets automatically loaded
# at startup.  PF will not be automatically enabled, however.  Instead,
# each component which utilizes PF is responsible for enabling and disabling
# PF via -E and -X as documented in pfctl(8).  That will ensure that PF
# is disabled only when the last enable reference is released.
#
# Care must be taken to ensure that the main ruleset does not get flushed,
# as the nested anchors rely on the anchor point defined here. In addition,
# to the anchors loaded by this file, some system services would dynamically 
# insert anchors into the main ruleset. These anchors will be added only when
# the system service is used and would removed on termination of the service.
#
# See pf.conf(5) for syntax.
#

#
# com.apple anchor point
#
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

rdr pass inet proto tcp from any to any port 5800 -> 192.168.1.246 port 5900

问题2

如果我使用anchor与上面相同的规则,则不会出现错误。但是,该端口仍然关闭,并且connection refused在尝试连接时出现。经过一番研究,我发现一个可能是端口 5800 上没有列出任何内容,因此被拒绝,但是

  1. 我不想让任何东西被监听,只需将流量转发到另一台计算机
  2. 即使nc正在监听,我仍然会被外部和内部(本地主机)拒绝,它不会转发

答案1

正如错误消息所述,您需要将您的rdr规则添加到 上的其他翻译规则旁边pf.conf。由于已经存在一个rdr锚点,最好的选择是将您的rdr规则放在它后面:

scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
rdr pass inet proto tcp to port 5800 -> 192.168.1.246 port 5900
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

from any to any如果省略则隐含,因此为了可读性我将其删除)

rdr规则仅告诉数据包过滤器如何处理到达端口 5800 的 TCP 数据包。您通常需要一条pass规则(即过滤规则)来告诉pf它们允许进入,但这足以添加passrdr规则,因此rdr pass.

请注意,对于要转发的数据包,您需要启用它sysctl或将其永久设置sysctl.conf(请参阅man pfctl):

$ sudo sysctl net.inet.ip.forwarding=1

相关内容