无法通过虚拟网桥将端口转发到 Tap 接口

无法通过虚拟网桥将端口转发到 Tap 接口

我在 Ubuntu 16.04 上开箱即用地安装了 libvirt,它在 192.168.122.0/24 处创建了一个 virbr0 虚拟桥,这是一个服务于该范围的 dnsmasq 实例,并设置了基本的 NAT 伪装。

我在其下方创建了一个点击界面,供我的虚拟化软件使用。该软件本身能够完美地访问互联网和网络的其余部分,因此伪装工作正常。我还可以使用该软件声明的 IP 地址从主机访问虚拟化软件 ssh 端口。所以我认为“开箱即用”的路由表通常是正确的。

我想要做的是将入站 ssh 连接从外部端口转发到该软件以及整个主机系统。现在主机系统当然有 ssh,我需要它才能工作。所以我尝试使用另一个端口,例如端口 2022。

我在 iptables 中创建了一条 DNAT 规则,将端口 2022 上的入站流量定向到端口 22 处的软件的 IP 地址。当我尝试从外部(例如下面的计算机 A)登录时,我无法访问目标。看起来地址转换正常进行,但在遍历到 iptables 中的“FORWARD”步骤后,我立即开始收到出站无法访问的 ICMP 数据包。

我对如何继续感到困惑。我尝试过一些 SNAT 规则,但要么我搞砸了,要么这不是问题。有人对此有想法吗?

更新:tap0 上的 Wireshark 未显示已收到转发的数据包。返回数据包的内容与虚拟化软件无关。

这是我的网络的图片:

           ----------
          | Internet |
           ----------
               |
               |
            --------
           | Router | 10.211.255.1
            --------
               |
               | 
   ____________|_______________
  |                            |
 ----------                   ---------
|          |                 |  enp0s5 | 10.211.255.4
| Computer | 10.211.255.2    |  Host   | 192.168.122.1
|    A     |                 |  virbr0 |
 ----------                   ---------
                                  |
                                  | LAN NAT 192.168.122.0/24 
                                  |
                              ----------
                             |   tap0   |
                             | Guest OS | 192.168.122.118
                             |          |
                              ----------

这是我的 IP 表规则:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             LOG level debug prefix "INTRACE: "
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             LOG level debug prefix "FORTRACE: "
ACCEPT     all  --  anywhere             192.168.122.0/24     ctstate RELATED,ESTABLISHED
ACCEPT     all  --  192.168.122.0/24     anywhere
ACCEPT     all  --  anywhere             anywhere
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             LOG level debug prefix "OUTTRACE: "
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootpc

NAT tables:
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
LOG        tcp  --  anywhere             anywhere             tcp dpt:2022 LOG level debug prefix "NATPTRACE: "
DNAT       tcp  --  anywhere             anywhere             tcp dpt:2022 to:192.168.122.118:22

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             LOG level debug prefix "NATITRACE: "

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             LOG level debug prefix "NATOTRACE: "

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             LOG level debug prefix "NATQTRACE: "
SNAT       tcp  --  anywhere             anywhere             tcp spt:ssh to::2022
RETURN     all  --  192.168.122.0/24     base-address.mcast.net/24
RETURN     all  --  192.168.122.0/24     broadcasthost.localdomain
MASQUERADE  tcp  --  192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
MASQUERADE  udp  --  192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
MASQUERADE  all  --  192.168.122.0/24    !192.168.122.0/24

最后,这是我在 syslog 中看到的具有上述规则的示例:

Oct 20 09:49:15 ubuntu kernel: [85149.812291] RAWPTRACE: IN=enp0s5 OUT= MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.4 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=40132 DF PROTO=TCP SPT=53245 DPT=2022 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812318] MGPTRACE: IN=enp0s5 OUT= MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.4 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=40132 DF PROTO=TCP SPT=53245 DPT=2022 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812326] NATPTRACE: IN=enp0s5 OUT= MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.4 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=40132 DF PROTO=TCP SPT=53245 DPT=2022 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812336] MGFTRACE: IN=enp0s5 OUT=virbr0 MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812340] FORTRACE: IN=enp0s5 OUT=virbr0 MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812354] RAWOTRACE: IN= OUT=enp0s5 SRC=10.211.55.4 DST=10.211.55.2 LEN=92 TOS=0x00 PREC=0xC0 TTL=64 ID=50608 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 ]
Oct 20 09:49:15 ubuntu kernel: [85149.812357] MGOTRACE: IN= OUT=enp0s5 SRC=10.211.55.4 DST=10.211.55.2 LEN=92 TOS=0x00 PREC=0xC0 TTL=64 ID=50608 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 ]
Oct 20 09:49:15 ubuntu kernel: [85149.812361] OUTTRACE: IN= OUT=enp0s5 SRC=10.211.55.4 DST=10.211.55.2 LEN=92 TOS=0x00 PREC=0xC0 TTL=64 ID=50608 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 ]
Oct 20 09:49:15 ubuntu kernel: [85149.812364] MGQTRACE: IN= OUT=enp0s5 SRC=10.211.55.4 DST=10.211.55.2 LEN=92 TOS=0x00 PREC=0xC0 TTL=64 ID=50608 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 ]

答案1

问题出在 FORWARD 规则中。由于我没有设置它们,所以我误解了 的输出iptables --list

该列表中的规则 4 如下:

ACCEPT     all  --  anywhere             anywhere

这似乎接受从任何地方绑定到任何地方的所有传入数据包。

然而,如果我看看iptables -S规则 4 实际上是:

-A FORWARD -i virbr0 -o virbr0 -j ACCEPT

这不会与从 enp0s5 传入、发往 vibr0 的数据包匹配。因此它遇到了 REJECT 规则 5,这实际上是拒绝所有发往 vibr0 的数据包。

我学到的教训是不要相信输出,而是在出现问题时iptables --list检查输出。iptables -S

相关内容