接口上所有 IP 的端口转发

接口上所有 IP 的端口转发

我以非特权用户身份运行基于 Java 的 Web 服务器。因此,它监听端口 8080 和 8443,而不是 80 和 443。

现在我正在使用以下pf规则在内部转发端口:

rdr pass on $ext_if proto tcp from any to $ext_ip port 80 -> $ext_ip port 8080
rdr pass on $ext_if proto tcp from any to $ext_ip port 443 -> $ext_ip port 8443

(显然,使用为$ext_if和定义的宏)$ext_ip

现在我想向接口添加更多 IP(用于 SSL vHosts)——最好的方法是什么?我是否必须为每个添加的 IP 重复这些规则?或者我可以以某种方式为“该接口上的每个 IP”制定规则吗?

编辑:不幸的是,这些 IP 不属于同一子网。我尝试在$ext_ip宏中列出它们,但我仍然希望找到一种不需要明确添加每个 IP 的解决方案。

谢谢!

答案1

我的研究表明,没有任何pf.conf条款可以让你达到这种程度的一对一规则扩展。

我希望您可以使用宏来做到这一点,对于您来说,这将是类似的:

vhost_ips = "{ 198.51.100.4, 198.51.100.5 }"
rdr pass on $ext_if proto tcp from any to $vhost_ips port 80  -> $ext_ip port 8080
rdr pass on $ext_if proto tcp from any to $vhost_ips port 443 -> $ext_ip port 8443

...但是如果在同一行上多次使用宏,它实际上会将后者扩展为整个宏,并调用循环:

rdr pass on int0 proto tcp from any to 198.51.100.4 port 80  -> { 198.51.100.4, 198.51.100.5 } port 8080 round-robin
rdr pass on int0 proto tcp from any to 198.51.100.5 port 443 -> { 198.51.100.4, 198.51.100.5 } port 8443 round-robin

... 我确信这不是您想要的。:-) 表格似乎也不对。手册页明确指出:

“表格还可以用于 nat 和 rdr 规则的重定向地址以及过滤规则的路由选项,但仅适用于循环池。”

因此不幸的是,看起来您唯一的选择是手动维护列表,或者将其生成为单独的文件并将其包含在内。

同样不幸的是,我的 7.4、8.2 或 9.0-RC2 系统的手册页include中没有提到该子句,所以如果你运行的是 FreeBSD 自带的股票 PF,我相信他们正在运行从 OpenBSD 4.5 导入的 PF,而 OpenBSD 4.5 似乎不支持...但以防万一,这里有一种生成包含的方法:pf.confinclude

$ cat vhost.list
198.51.100.4
198.51.100.5

$ cat gen-vhosts-pf.sh
#!/bin/sh
for ip in `egrep -v ^# /etc/vhost.list`; do
        echo "rdr pass on \$ext_if proto tcp from any to $ip port 80  -> $ip port 8080"
        echo "rdr pass on \$ext_if proto tcp from any to $ip port 443 -> $ip port 8443"
done

$ ./gen-vhosts-pf.sh | sudo tee /etc/pf.conf.vhosts
rdr pass on $ext_if proto tcp from any to 198.51.100.4 port 80  -> 198.51.100.4 port 8080
rdr pass on $ext_if proto tcp from any to 198.51.100.4 port 443 -> 198.51.100.4 port 8443
rdr pass on $ext_if proto tcp from any to 198.51.100.5 port 80  -> 198.51.100.5 port 8080
rdr pass on $ext_if proto tcp from any to 198.51.100.5 port 443 -> 198.51.100.5 port 8443

...它将被导入到 pf.conf 中:

include "/etc/pf.conf.vhosts"

如果您没有运行支持包含的 PF,那么这会有点棘手,但您明白了。

抱歉,我的研究稍微有点零散;我还找不到向 PF 询问其版本信息的规范方法,所以不得不费些周折。

编辑: 您可能能够使用该load anchor子句进行包含,但看起来您必须$ext_if在锚点内重复您的宏。

答案2

假设所有 IP 都在同一个子网中,则可以使用聚合

$ext_net = "192.168.1.0/24"

答案3

我认为您不需要做任何特别的事情,因为别名没有配置为单独的网络设备。这与 Linux 不同,在 Linux 中,您将eth0eth0:1eth0:2视为离散接口。因此,pf 规则应扩展以应用于该接口上存在的所有 IP 地址:

# ifconfig sis2 192.168.4.1 netmask 255.255.255.0 alias
# ifconfig sis2
sis2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:00:24:c6:4d:ee
        priority: 0
        media: Ethernet autoselect (100baseTX full-duplex)
        status: active
        inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
        inet6 fe80::200:24ff:fec6:4dee%sis2 prefixlen 64 scopeid 0x3
        inet 192.168.4.1 netmask 0xffffff00 broadcast 192.168.4.255

使用以下 pf 规则...

# allow untrusted -> trusted ssh & http traffic
untrust="sis2"
pass in log on $untrust inet proto tcp from $untrust:network to $trust:network port 22
pass in log on $untrust inet proto tcp from $untrust:network to $trust:network port 80

并且这扩展到以下内容...

@32 pass in log on sis2 inet proto tcp from 192.168.1.0/24 to 192.168.0.0/24 port = ssh flags S/SA
@33 pass in log on sis2 inet proto tcp from 192.168.1.0/24 to 192.168.0.0/24 port = www flags S/SA
@34 pass in log on sis2 inet proto tcp from 192.168.4.0/24 to 192.168.0.0/24 port = ssh flags S/SA
@35 pass in log on sis2 inet proto tcp from 192.168.4.0/24 to 192.168.0.0/24 port = www flags S/SA
@36 pass in log on sis1 inet proto tcp from 192.168.0.0/24 to 192.168.0.1 port = ssh flags S/SA

您将需要重新应用您的 pf 规则,pfctl但这就是您要做的全部工作,以解决别名 IP 地址问题,假设您的宏和规则是正确的。

此外,您还可以忽略通过列出 pf 中接口的所有别名来查看它interface:0

相关内容