![在桥接机器上具有不对称 IP 的相同网络副本之间进行路由](https://linux22.com/image/218467/%E5%9C%A8%E6%A1%A5%E6%8E%A5%E6%9C%BA%E5%99%A8%E4%B8%8A%E5%85%B7%E6%9C%89%E4%B8%8D%E5%AF%B9%E7%A7%B0%20IP%20%E7%9A%84%E7%9B%B8%E5%90%8C%E7%BD%91%E7%BB%9C%E5%89%AF%E6%9C%AC%E4%B9%8B%E9%97%B4%E8%BF%9B%E8%A1%8C%E8%B7%AF%E7%94%B1.png)
鉴于以下情况:
一台名为 middleman 的主机具有以下接口:
界面 | 地址 | 地点 | 大师VRF |
---|---|---|---|
恩普1s0 | 192.168.2.99 | 外网 | VRF-外层 |
恩普2s0 | 192.168.2.1 | 内网 | VRF-内部 |
假设外部网络有默认网关 192.168.2.1,并且我们有另一个网络 - 192.168.3.0/24。如果我们在外网有一台机器 192.168.2.22,在内网有一台具有相同 ip 的机器,我们使用 192.168.3.0/24 网络使它们能够相互通信。如果外部网络上的主机 192.168.2.22 想要联系内部网络上的 192.168.2.22,我们使用 IP 192.168.3.22。它被传输到 enp1s0、dstnat:ed,通过 vrf-outer、srcnat:ed 路由,并通过 enp2s0 路由到正确的机器。然后,响应在返回时使用 conntrack nat 采取相同的路径。
我目前使用问题中的修改配置进行了一些工作这里,但无法从外部网络上的计算机 ssh 192.168.2.99。相反,我从 vrf-outer 收到“连接被拒绝”(通过wireshark找到)。从同一台机器 Ping 192.168.2.99 有效,并且内部网络和外部网络(以及互联网)上的机器之间的所有通信都有效。
ssh 192.168.2.99
在外网主机192.168.2.234上执行命令,报文流程如下:
- 外部主机 -> enp1s0 (192.168.234 -> 192.168.2.99) [SYN]
- enp1s0 -> VRF 外部 (192.168.234 -> 192.168.2.99) [SYN]
- vrf-outer -> enp1s0 (192.168.99 -> 192.168.2.234) [RST, ACK]
- enp1s0 -> 外部主机 (192.168.99 -> 192.168.2.234) [RST, ACK]
conntrack -L
不显示此连接的任何痕迹,并且nft monitor trace
只显示verdict accept
所有规则。 Firewalld 配置为允许在所有接口和区域上使用 ssh。
我正在使用的配置包含在下面。感谢您的时间!
#!/bin/bash
TW_INT="vrf-tw-int"
TW_EXT="vrf-tw-ext"
EXT="enp1s0"
INT="enp2s0"
DESIRED_ZONE="FedoraServer"
############################### SET ECHO COMMAND WHEN EXECUTING ###################################
set -x
############################### ENABLE IP-FORWARDING ##############################################
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1
############################### REMOVE OLD VRF INTERFACES #########################################
nmcli con del ${TW_INT} || true
nmcli con del ${TW_EXT} || true
############################### ADD VRF INTERFACES ################################################
nmcli con add type vrf con-name ${TW_INT} ifname ${TW_INT} table 100 ipv4.method disabled ipv6.method disabled
nmcli con add type vrf con-name ${TW_EXT} ifname ${TW_EXT} table 200 ipv4.method disabled ipv6.method disabled
############################### SET VRF INTERFACES UP #############################################
nmcli con up ${TW_INT}
nmcli con up ${TW_EXT}
############################### ADD VRF INTERFACES TO ACTUAL INTERFACES ###########################
nmcli con mod ${INT} master ${TW_INT}
nmcli con mod ${EXT} master ${TW_EXT}
nmcli con up ${INT}
nmcli con up ${EXT}
############################### ADD IP-ADDRESSES ##################################################
nmcli con mod ${INT} ipv4.addresses 192.168.2.1/24
nmcli con mod ${INT} ipv4.method manual
nmcli con up ${INT}
ip route show table 100
ip route show table 200
ip route
############################### MOVE INTERFACES IN FIREWALLD AND SET FORWARD ######################
ZONE_INT=$(firewall-cmd --get-zone-of-interface=${INT})
ZONE_EXT=$(firewall-cmd --get-zone-of-interface=${EXT})
ZONE_TW_INT=$(firewall-cmd --get-zone-of-interface=${TW_INT})
ZONE_TW_EXT=$(firewall-cmd --get-zone-of-interface=${TW_EXT})
firewall-cmd --zone=${DESIRED_ZONE} --add-forward --permanent
firewall-cmd --zone=${ZONE_INT} --remove-interface ${INT} --permanent
firewall-cmd --zone=${ZONE_EXT} --remove-interface ${EXT} --permanent
firewall-cmd --zone=${ZONE_TW_INT} --remove-interface ${TW_INT} --permanent
firewall-cmd --zone=${ZONE_TW_EXT} --remove-interface ${TW_EXT} --permanent
firewall-cmd --zone=${DESIRED_ZONE} --add-interface ${INT} --permanent
firewall-cmd --zone=${DESIRED_ZONE} --add-interface ${EXT} --permanent
firewall-cmd --zone=${DESIRED_ZONE} --add-interface ${TW_INT} --permanent
firewall-cmd --zone=${DESIRED_ZONE} --add-interface ${TW_EXT} --permanent
firewall-cmd --reload
ip addr
############################### ADD CONNTRACK LABELS ##############################################
mkdir -p /etc/xtables
cat << EOF > /etc/xtables/connlabel.conf
1 INSIDE
2 OUTSIDE
EOF
ln -s /etc/xtables/connlabel.conf /etc/connlabel.conf
ln -s /etc/xtables/connlabel.conf /etc/nftables/connlabel.conf
############################### ADD ROUTING RULES FOR MARKED PACKETS ##############################
ip rule add prio 100 fwmark 100 lookup 200
ip rule add prio 200 fwmark 200 lookup 100
############################### ADD DEFAULT ROUTE FOR MACHINE #####################################
ip route add default via 192.168.2.1 dev ${EXT}
############################### FIX VRF ROUTE SOURCES #############################################
ip route del 192.168.2.0/24 dev ${EXT} proto kernel scope link src 192.168.2.99 metric 105 table 200 || true
ip route add 192.168.2.0/24 dev ${EXT} proto kernel scope link metric 105 table 200 || true
ip route del default via 192.168.2.1 dev ${EXT} proto dhcp src 192.168.2.99 metric 105 table 200 || true
ip route add default via 192.168.2.1 dev ${EXT} proto dhcp metric 105 table 200 || true
ip route del 192.168.2.0/24 dev ${INT} proto kernel scope link src 192.168.2.1 metric 106 table 100 || true
ip route add 192.168.2.0/24 dev ${INT} proto kernel scope link metric 106 table 100 || true
############################### ADD TABLES AND FLUSH OLD TABLES ###################################
nft 'add table ip twilight'
nft 'delete table ip twilight'
nft 'add table ip twilight'
############################### ADD PREROUTING CHAINS #############################################
nft 'add chain ip twilight prerouting { type nat hook prerouting priority -100; policy accept; }'
############################### ADD PREROUTING MANGLE CHAINS ######################################
nft 'add chain ip twilight premangle { type filter hook prerouting priority -180; policy accept; }'
############################### ADD RAW (PRE-CONNTRACK) CHAINS ####################################
nft 'add chain ip twilight raw { type filter hook prerouting priority raw; policy accept; }'
############################### ADD POSTROUTING CHAINS ############################################
nft 'add chain ip twilight postrouting { type nat hook postrouting priority 100; policy accept; }'
############################### ADD FORWARDING CHAINS #############################################
nft 'add chain ip twilight forward { type filter hook forward priority filter; policy accept; }'
############################### ADD EXTERNAL TRANSLATION MAPS #####################################
nft 'add map ip twilight from_192_168_3_0_to_192_168_2_0 { type ipv4_addr: ipv4_addr; }'
############################### ADD INTERNAL TRANSLATION MAPS #####################################
nft 'add map ip twilight from_192_168_2_0_to_192_168_3_0 { type ipv4_addr: ipv4_addr; }'
############################### ADD DEBUG RULES FOR ALL PACKETS ###################################
nft 'add rule ip twilight prerouting meta nftrace set 1'
nft 'add rule ip twilight postrouting meta nftrace set 1'
nft 'add rule ip twilight forward meta nftrace set 1'
nft 'add rule ip twilight raw meta nftrace set 1'
nft 'add rule ip twilight premangle meta nftrace set 1'
############################### ADD DNAT RULES ####################################################
nft 'add rule ip twilight prerouting ip daddr 192.168.3.0/24 meta nftrace set 1 dnat to ip daddr map @from_192_168_3_0_to_192_168_2_0'
############################### ADD ROUTING RULES - MARK PACKETS ##################################
nft "add rule ip twilight raw iif "${INT}" ip daddr 192.168.3.0/24 meta mark set 100"
nft "add rule ip twilight raw iif "${EXT}" ip daddr 192.168.3.0/24 meta mark set 200"
nft "add rule ip twilight prerouting iif "${INT}" ip daddr != 192.168.3.0/24 ct label set INSIDE"
nft "insert rule ip twilight premangle iif "${EXT}" ct label INSIDE meta mark set 200"
############################### TELL CONNTRACK ORIGINAL ZONES FOR MARKED PACKETS ##################
nft "add rule ip twilight raw iif "${INT}" ip saddr 192.168.2.0/24 ip daddr != 192.168.2.0/24 ct original zone set 100"
nft "add rule ip twilight raw iif "${EXT}" ip saddr 192.168.2.0/24 ip daddr != 192.168.2.0/24 ct original zone set 200"
############################### ADD SNAT RULES ####################################################
nft 'add rule ip twilight postrouting ip saddr 192.168.2.0/24 ip daddr 192.168.2.0/24 meta nftrace set 1 snat to ip saddr map @from_192_168_2_0_to_192_168_3_0'
############################### ADD TWILIGHT -> WORLD MASQUERADE ##################################
nft "add rule ip twilight postrouting iif "${TW_INT}" oif "${EXT}" ip daddr != 192.168.2.0/24 meta nftrace set 1 masquerade"
############################### ADD TWILIGHT -> REGLER FORWARDING #################################
nft "add rule ip twilight forward iif "${INT}" meta nftrace set 1 accept"
nft "add rule ip twilight forward iif "${TW_EXT}" meta nftrace set 1 accept"
nft "add rule ip twilight forward oif "${INT}" meta nftrace set 1 accept"
############################### ADD REGLER -> TWILIGHT FORWARDING #################################
nft "add rule ip twilight forward iif "${EXT}" ip daddr 192.168.3.0/24 meta nftrace set 1 accept"
############################### ADD ELEMENTS TO INTERNAL TRANSLATION MAP ##########################
nft 'include "/etc/nftables/nft-host-alias-twilight-192.168.2.0-192.168.3.0"'
############################### ADD ELEMENTS TO EXTERNAL TRANSLATION MAP ##########################
nft 'include "/etc/nftables/nft-host-alias-twilight-192.168.3.0-192.168.2.0"'
############################### MAKE FIREWALLD IGNORE TWILIGHT TRAFFIC ############################
FIREWALLD_CHAINS="mangle_PREROUTING nat_PREROUTING nat_POSTROUTING nat_OUTPUT filter_PREROUTING filter_INPUT filter_FORWARD filter_OUTPUT"
for CHAIN in ${FIREWALLD_CHAINS}; do
nft "insert rule inet firewalld "${CHAIN}" iif "${TW_INT}" accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${TW_EXT}" accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${EXT}" oif "${INT}" accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${EXT}" ip daddr 192.168.3.0/24 accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${EXT}" oif "${TW_INT}" accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${EXT}" oif "${TW_EXT}" accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${INT}" oif "${EXT}" accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${INT}" ip daddr 192.168.221.0/24 accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${INT}" oif "${TW_INT}" accept"
nft "insert rule inet firewalld "${CHAIN}" iif "${INT}" oif "${TW_EXT}" accept"
done
答案1
上面显示的配置按预期工作,但有一点需要注意。 VRF 接口包括 VRF 上下文,用于处理多租户应用程序。这意味着应用程序可以感知 VRF,并且仅侦听特定的 VRF 上下文,其中所有程序都在默认的 VRF 上下文中运行,除非另有说明。我的流量被路由到 vrf-outer 上下文,因此流量被丢弃,因为没有 ssh 服务器侦听该 vrf 上下文。
您可以通过运行以下命令使侦听默认 VRF 上下文的程序在所有上下文中工作:
sysctl -w net.ipv4.tcp_l3mdev_accept=1
sysctl -w net.ipv4.udp_l3mdev_accept=1
如记录在VRF 接口的内核文档。
这似乎不适用于 ipv6,因为它没有 l3mdev_accept 选项。我还不清楚为什么 ipv6 不需要这个。