TL;DR - 我想设置一个 FreeBSD 虚拟机,其中一张网卡位于我的家庭 LAN (192.168.1.0/24) 上,一张网卡位于私有内部到虚拟盒网络 (10.9.9.0/24) 上,并通过两者之间来回的任何和所有流量。
长期 Linux 用户(服务器上的 Debian)但只使用 FreeBSD 大约一天:)
无论如何,对于我的实验材料,我有一台带有 2 个网络接口的虚拟机 - 一个桥接到我的家庭 LAN,一个位于仅限内部网络上。这台机器被设置为无块路由器,只需在 eth0 和 eth1 之间传递数据包,无论源或目的地如何。使用 iptables 很容易做到 -
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
但我一直在尝试让它与 pf 一起工作,但只取得了部分成功。
和
gateway_enable="YES"
pf_enable="YES"
pf_rules="/etc/pf.conf"
在我的/etc/rc.conf
和/etc/pf.conf
包含的
pass from em1:network to any keep state
pass from em0:network to any keep state
pass in inet proto tcp to any keep state
pass in inet proto udp to any keep state
pass out inet proto tcp to any keep state
pass out inet proto udp to any keep state
我可以启动仅连接到内部的实时光盘虚拟机,并将 em1 的 IP 设置为默认网关,并且能够 ping em1、ping em0,但我无法 ping 正在运行的主机 vbox 或我的任何其他计算机LAN 或通过 http、ssh 等连接。
[root@bsdtest ~]# pfctl -sa
FILTER RULES:
pass in inet proto tcp all flags S/SA keep state
pass in inet proto udp all keep state
pass out inet proto tcp all flags S/SA keep state
pass out inet proto udp all keep state
pass inet from 10.9.9.0/24 to any flags S/SA keep state
pass inet from 192.168.1.0/24 to any flags S/SA keep state
STATES:
all tcp 192.168.1.90:22 <- 192.168.1.10:48102 ESTABLISHED:ESTABLISHED
all udp 192.168.1.2:53 <- 10.9.9.5:59075 NO_TRAFFIC:SINGLE
all udp 10.9.9.5:59075 -> 192.168.1.2:53 SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:34207 NO_TRAFFIC:SINGLE
all udp 10.9.9.5:34207 -> 192.168.1.2:53 SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:43515 NO_TRAFFIC:SINGLE
all udp 10.9.9.5:43515 -> 192.168.1.2:53 SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:1636 NO_TRAFFIC:SINGLE
all udp 10.9.9.5:1636 -> 192.168.1.2:53 SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:60124 NO_TRAFFIC:SINGLE
all udp 10.9.9.5:60124 -> 192.168.1.2:53 SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:8866 NO_TRAFFIC:SINGLE
all udp 10.9.9.5:8866 -> 192.168.1.2:53 SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:25534 NO_TRAFFIC:SINGLE
all udp 10.9.9.5:25534 -> 192.168.1.2:53 SINGLE:NO_TRAFFIC
all udp 192.168.1.2:53 <- 10.9.9.5:30141 NO_TRAFFIC:SINGLE
all udp 10.9.9.5:30141 -> 192.168.1.2:53 SINGLE:NO_TRAFFIC
INFO:
Status: Enabled for 0 days 00:08:28 Debug: Urgent
State Table Total Rate
current entries 17
searches 1990 3.9/s
inserts 253 0.5/s
removals 236 0.5/s
Counters
match 253 0.5/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
TIMEOUTS:
tcp.first 120s
tcp.opening 30s
tcp.established 86400s
tcp.closing 900s
tcp.finwait 45s
tcp.closed 90s
tcp.tsdiff 30s
udp.first 60s
udp.single 30s
udp.multiple 60s
icmp.first 20s
icmp.error 10s
other.first 60s
other.single 30s
other.multiple 60s
frag 30s
interval 10s
adaptive.start 6000 states
adaptive.end 12000 states
src.track 0s
LIMITS:
states hard limit 10000
src-nodes hard limit 10000
frags hard limit 5000
table-entries hard limit 200000
OS FINGERPRINTS:
758 fingerprints loaded
[root@bsdtest ~]#
有任何想法吗?有关从 10.9.9.5(我的实时光盘)到 192.168.1.2 的 udp 流量的线路将用于 DNS 到我的家庭 LAN 名称服务器,但没有响应到达...这是 http 请求显示的内容 -
[root@bsdtest ~]# pfctl -sa | grep 80
all tcp 192.168.1.10:80 <- 10.9.9.5:59436 CLOSED:SYN_SENT
all tcp 10.9.9.5:59436 -> 192.168.1.10:80 SYN_SENT:CLOSED
all tcp 192.168.1.10:80 <- 10.9.9.5:59438 CLOSED:SYN_SENT
all tcp 10.9.9.5:59438 -> 192.168.1.10:80 SYN_SENT:CLOSED
有想法吗?
答案1
好的,找到解决方案。
我的 /etc/rc.conf 没问题......
/etc/pf.conf 需要是
# cat /etc/pf.conf
ext_if="em0"
int_if="em1"
boxnet = $int_if:network
homenet = $ext_if:network
nat on $ext_if from $boxnet to any -> ($ext_if)
pass quick from { lo0, $boxnet, $homenet } to any keep state
可能变量太多了,我只能使用原来的 em0/em1。不管怎样,这给了你——
[root@bsdtest ~]# pfctl -vnf /etc/pf.conf
ext_if = "em0"
int_if = "em1"
icmp_types = "echoreq"
boxnet = "em1:network"
homenet = "em0:network"
nat on em0:network inet from 10.9.9.0/24 to any -> 192.168.1.0/24
nat on em1:network inet from 192.168.1.0/24 to any -> 10.9.9.0/24
pass quick inet from 127.0.0.0/8 to any flags S/SA keep state
pass quick inet from 192.168.1.0/24 to any flags S/SA keep state
答案2
以下是一些猜测,所以买者自负。然而,这是一种非常典型的设置,让许多一开始就将路由、数据包过滤(防火墙)和 NAT(网络地址转换)混为一谈的人感到困惑。
你没有明确说明 - 但我猜你的网络看起来像这样:
Internet <-A-> SOHO Router <-B-> Server/workstation <-C-> VM
您的 DNS 服务器位于 B 网络,即 192.168.1.0/24
我猜测您的 Internet SOHO 路由器是 192.168.1.1,并且被设置为网络的默认网关。这将是一种非常常见的设置。
您声明 DNS 服务器位于 192.168.1.2,服务器桥接接口为 192.168.1.10。在其后面有网络 10.9.9.0/24。
您的 iptables 设置将转发全部上的数据包界面。实际上,您将所有数据包从一个网络发送到另一个网络 - 甚至是本地数据包。这是重要的区别。
在你的 pf 配置中你做不是向前全部上的数据包界面。您已指定一个网络 em1:network
。我们没有完整的配置,但我猜您实际上有一个很好且可以正常工作的准系统配置。困扰你的是缺失的路线。
当您从 10.9.9.0/24 发送数据包时,它将到达 192.168.1.0/24 网络。您的服务器已进入该网络,因此您将直接到达您的 DNS。但 B 网络上的 DNS 服务器不知道如何到达非本地 C 10.9.9.0/24 网络。然后所有响应都会发送到“默认路由器”,我猜这是您的 SOHO 路由器。该路由器也只知道在哪里可以找到 192.168.1.0/24 网络(而不是 10.9.9.0/24),并且通常会将所有内容路由到您的外部 Internet 链接。在这种情况下,您使用的是正确的私有地址 - 因此数据包将被丢弃,因为私有地址未在 Internet 上路由。
“正确”的解决方案是在 SOHO 路由器上设置一条路由,告诉它将 10.9.9.0/24 的数据包路由到 192.168.1.10。一个像样的路由器可以让你做到这一点。不幸的是,许多廉价的 SOHO 路由器没有。在这种情况下,您可以在 DNS 服务器上添加路由来测试它。
- 它对 iptables 起作用的原因是在 eth0 接口上可以看到响应数据包,并且所有数据包都会被转发。 B 网络上的所有流量都发送到 C 网络(并反向)。这包括可以/应该留在本地的流量。实际上您已经设置了一个网桥。
- 它对您的第一个 pf 设置不起作用的原因是您已经指定了您期望看到的网络。 B网上只有一台机器知道去哪里找到C网。这是 192.168.1.10,因为它在 C 网上有一个接口。实际上,您已经设置了基本的防火墙。过滤已准备就绪,但您尚未过滤任何内容。但缺少路由。
- 它在您的第二个 pf 配置(您自己的答案)中工作的原因是您将 10.9.9.0/24 网络 NAT 到 192.168.1.0/24 的地址空间。来自 C 网 10.9.9.0/24 的所有流量在 B 网上将显示为来自 192.168.1.10。应避免使用 NAT只要有可能,并且仅作为最后的手段使用。
如果您不需要/想要过滤包 - 那么我建议您不要使用防火墙。你想要做的事情应该由简单路由。
答案3
如果您希望拥有“全开放”网关,您只需使用一条规则即可做到这一点:
pass all allow-opts
不需要搞乱明确的“保持状态”或标志。