更新

更新

iptables背景:我已经好几年没有做过任何事情了...我在 VMWare 上的虚拟机中运行 Fedora 16,并将我的防火墙 (TomatoUSB) 端口转发到虚拟机。

虚拟机位于192.168.1.155.我知道数据包正在发送到虚拟机......

基于这个插图要查看数据包应该如何发送,我希望数据包能够流出nat-PREROUTING并进入mangle-INPUTmangle-FORWARD除非内核由于某些其他原因而丢弃它们。

所以我打开了一些日志记录:

iptables -t mangle -v -A PREROUTING -j LOG -p tcp --destination-port 80 --log-prefix 'mangle-PREROUTING '
iptables -t nat -v -A PREROUTING -j LOG -p tcp --destination-port 80 --log-prefix 'nat-PREROUTING '
iptables -t filter -v -I INPUT 1 -j LOG -p tcp --destination-port 80 --log-prefix 'filter-INPUT '
iptables -t filter -v -I FORWARD 1 -j LOG -p tcp --destination-port 80 --log-prefix 'filter-FORWARD '
iptables -t mangle -v -I INPUT 1 -j LOG -p tcp --destination-port 80 --log-prefix 'mangle-INPUT ' 
iptables -t mangle -v -I FORWARD 1 -j LOG -p tcp --destination-port 80 --log-prefix 'mangle-FORWARD '

然后我用了一个外部测试服务我可以看到数据包穿过PREROUTING链条,但随后被忽略:

Apr 23 19:11:52 webmail64 kernel: [  351.116042] mangle-PREROUTING IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:bc:ae:c5:c3:68:f9:08:00 SRC=66.249.67.195 DST=192.168.1.155 LEN=60 TOS=0x00 PREC=0x20 TTL=48 ID=20466 DF PROTO=TCP SPT=64135 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 
Apr 23 19:11:52 webmail64 kernel: [  351.121701] nat-PREROUTING IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:bc:ae:c5:c3:68:f9:08:00 SRC=66.249.67.195 DST=192.168.1.155 LEN=60 TOS=0x00 PREC=0x20 TTL=48 ID=20466 DF PROTO=TCP SPT=64135 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 
Apr 23 19:11:55 webmail64 kernel: [  354.113372] mangle-PREROUTING IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:bc:ae:c5:c3:68:f9:08:00 SRC=66.249.67.195 DST=192.168.1.155 LEN=60 TOS=0x00 PREC=0x20 TTL=48 ID=20467 DF PROTO=TCP SPT=64135 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 
Apr 23 19:11:55 webmail64 kernel: [  354.114834] nat-PREROUTING IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:bc:ae:c5:c3:68:f9:08:00 SRC=66.249.67.195 DST=192.168.1.155 LEN=60 TOS=0x00 PREC=0x20 TTL=48 ID=20467 DF PROTO=TCP SPT=64135 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 
Apr 23 19:12:01 webmail64 kernel: [  360.109534] mangle-PREROUTING IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:bc:ae:c5:c3:68:f9:08:00 SRC=66.249.67.195 DST=192.168.1.155 LEN=60 TOS=0x00 PREC=0x20 TTL=48 ID=20468 DF PROTO=TCP SPT=64135 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 
Apr 23 19:12:01 webmail64 kernel: [  360.111023] nat-PREROUTING IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:bc:ae:c5:c3:68:f9:08:00 SRC=66.249.67.195 DST=192.168.1.155 LEN=60 TOS=0x00 PREC=0x20 TTL=48 ID=20468 DF PROTO=TCP SPT=64135 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 

你可以看到这TTL很好。虚拟机的 IP 是192.168.1.155这样的,所以它应该转到INPUT下一个,但它永远不会成功。如果数据包来自我的网络内部,则符合预期:

Apr 23 19:20:03 webmail64 kernel: [  841.725402] mangle-PREROUTING IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:00:1f:3b:cb:2e:99:08:00 SRC=192.168.1.69 DST=192.168.1.155 LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=4562 DF PROTO=TCP SPT=61520 DPT=80 WINDOW=4042 RES=0x00 ACK FIN URGP=0 
Apr 23 19:20:03 webmail64 kernel: [  841.729647] mangle-INPUT IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:00:1f:3b:cb:2e:99:08:00 SRC=192.168.1.69 DST=192.168.1.155 LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=4562 DF PROTO=TCP SPT=61520 DPT=80 WINDOW=4042 RES=0x00 ACK FIN URGP=0 
Apr 23 19:20:03 webmail64 kernel: [  841.731056] filter-INPUT IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:00:1f:3b:cb:2e:99:08:00 SRC=192.168.1.69 DST=192.168.1.155 LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=4562 DF PROTO=TCP SPT=61520 DPT=80 WINDOW=4042 RES=0x00 ACK FIN URGP=0 
Apr 23 19:20:03 webmail64 kernel: [  841.732784] mangle-PREROUTING IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:00:1f:3b:cb:2e:99:08:00 SRC=192.168.1.69 DST=192.168.1.155 LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=4563 DF PROTO=TCP SPT=61520 DPT=80 WINDOW=4042 RES=0x00 ACK URGP=0 
Apr 23 19:20:03 webmail64 kernel: [  841.734257] mangle-INPUT IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:00:1f:3b:cb:2e:99:08:00 SRC=192.168.1.69 DST=192.168.1.155 LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=4563 DF PROTO=TCP SPT=61520 DPT=80 WINDOW=4042 RES=0x00 ACK URGP=0 
Apr 23 19:20:03 webmail64 kernel: [  841.735676] filter-INPUT IN=eth1 OUT= MAC=00:0c:29:fa:36:c7:00:1f:3b:cb:2e:99:08:00 SRC=192.168.1.69 DST=192.168.1.155 LEN=40 TOS=0x00 PREC=0x00 TTL=128 ID=4563 DF PROTO=TCP SPT=61520 DPT=80 WINDOW=4042 RES=0x00 ACK URGP=0 

我尝试了什么?

  • 关闭 SELinux
  • 完全关闭iptables
  • 确保默认策略是ACCEPT
    • 看到数据包计数ACCEPT增加了
  • 打开 IP 转发 ( /proc/sys/net/ipv4/ip_forward) 以防万一

我的设置:* kernel= Linux webmail64 3.3.2-1.fc16.x86_64 #1 SMP Sat Apr 14 00:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux *iptables v1.4.12

以下是所有iptables重要的信息:

[root@webmail64 ~]# iptables-save 
# Generated by iptables-save v1.4.12 on Mon Apr 23 20:47:24 2012
*nat
:PREROUTING ACCEPT [916:127527]
:INPUT ACCEPT [1:60]
:OUTPUT ACCEPT [87:7857]
:POSTROUTING ACCEPT [87:7857]
-A PREROUTING -p tcp -m tcp --dport 80 -j LOG --log-prefix "nat-PREROUTING "
COMMIT
# Completed on Mon Apr 23 20:47:24 2012
# Generated by iptables-save v1.4.12 on Mon Apr 23 20:47:24 2012
*mangle
:PREROUTING ACCEPT [1402:193108]
:INPUT ACCEPT [1343:189856]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [303:67789]
:POSTROUTING ACCEPT [303:67789]
-A PREROUTING -p tcp -m tcp --dport 80 -j LOG --log-prefix "mangle-PREROUTING "
-A INPUT -p tcp -m tcp --dport 80 -j LOG --log-prefix "mangle-INPUT "
-A FORWARD -p tcp -m tcp --dport 80 -j LOG --log-prefix "mangle-FORWARD "
COMMIT
# Completed on Mon Apr 23 20:47:24 2012
# Generated by iptables-save v1.4.12 on Mon Apr 23 20:47:24 2012
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1075:220262]
-A INPUT -p tcp -m tcp --dport 80 -j LOG --log-prefix "filter-INPUT "
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -p tcp -m tcp --dport 80 -j LOG --log-prefix "filter-FORWARD "
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Mon Apr 23 20:47:24 2012

接下来我可以去哪里看?

更新

我被要求运行tcpdump,看起来我从未发送ACK数据包?:

tcpdump -i eth1 -An -vvv \(net 50 or net 173\)
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
19:31:26.305048 IP (tos 0x20, ttl 53, id 26094, offset 0, flags [DF], proto TCP (6), length 60)
    50.22.90.226.48891 > 192.168.1.155.http: Flags [S], cksum 0xca12 (correct), seq 2918539684, win 5840, options [mss 1460,sackOK,TS val 1152517194 ecr 0,nop,wscale 7], length 0
E .<[email protected]....................
D..J........
19:31:26.521815 IP (tos 0x20, ttl 53, id 61033, offset 0, flags [DF], proto TCP (6), length 60)
    50.22.90.226.48892 > 192.168.1.155.http: Flags [S], cksum 0x82b4 (correct), seq 1826089481, win 5840, options [mss 1460,sackOK,TS val 1152517216 ecr 0,nop,wscale 7], length 0
E .<[email protected]..     ...................
D..`........
19:31:29.300994 IP (tos 0x20, ttl 53, id 26095, offset 0, flags [DF], proto TCP (6), length 60)
    50.22.90.226.48891 > 192.168.1.155.http: Flags [S], cksum 0xc8e6 (correct), seq 2918539684, win 5840, options [mss 1460,sackOK,TS val 1152517494 ecr 0,nop,wscale 7], length 0
E .<[email protected]....................
D..v........
19:31:29.521214 IP (tos 0x20, ttl 53, id 61034, offset 0, flags [DF], proto TCP (6), length 60)
    50.22.90.226.48892 > 192.168.1.155.http: Flags [S], cksum 0x8188 (correct), seq 1826089481, win 5840, options [mss 1460,sackOK,TS val 1152517516 ecr 0,nop,wscale 7], length 0
E .<[email protected]..     ...................
D...........
19:31:35.302578 IP (tos 0x20, ttl 53, id 26096, offset 0, flags [DF], proto TCP (6), length 60)
    50.22.90.226.48891 > 192.168.1.155.http: Flags [S], cksum 0xc68e (correct), seq 2918539684, win 5840, options [mss 1460,sackOK,TS val 1152518094 ecr 0,nop,wscale 7], length 0
E .<[email protected]....................
D...........
19:31:35.532347 IP (tos 0x20, ttl 53, id 61035, offset 0, flags [DF], proto TCP (6), length 60)
    50.22.90.226.48892 > 192.168.1.155.http: Flags [S], cksum 0x7f2f (correct), seq 1826089481, win 5840, options [mss 1460,sackOK,TS val 1152518117 ecr 0,nop,wscale 7], length 0
E .<[email protected]..     ........./.........
D...........

答案1

我知道这有点晚了,但是……楼主知道它负责那个IP?这是我放在我创建的规则文件顶部的架构。您可以在其他地方找到类似的流程图,但以 ASCII 格式显示(不想称其为艺术;))在终端上可能非常有用。

大多数情况下,我心里都知道这一点,但是,嘿,如果忘记了,有一个参考也没什么坏处。

###############################################################################
###
###            PACKET FLOW THROUGH NETFILTER TABLES AND CHAINS
###
###
###                          {Packet in}
###                               |
###                               v
###                       +-----------------+
###                       |mangle/PREROUTING|
###                       +-----------------+
###                               |
###                               v
###                       +-----------------+
###                       |  nat/PREROUTING |
###                       +-----------------+
###                               |
###                               v
###                       *~~~~~~~~~~~~~~~~~*
###                       |  kernel routing |
###                       *~~~~~~~~~~~~~~~~~*
###                               |
###                               v
###           .------------{?for this host?}------------.
###      yes! |                                         | no!
###           v                                         v
###  +-----------------+                       +-----------------+
###  |   mangle/INPUT  |                       |  mangle/FORWARD |
###  +-----------------+                       +-----------------+
###           |                                         |
###           v                                         v
###  +-----------------+                       +-----------------+
###  |   filter/INPUT  |                       |  filter/FORWARD |
###  +-----------------+                       +-----------------+
###           |                                         |
###           v                                         |
### *~~~~~~~~~~~~~~~~~~~~*                              |
### | response & routing |                              |
### *~~~~~~~~~~~~~~~~~~~~*                              |
###           |                                         |
###           v                                         |
###  +-----------------+                                |
###  |  mangle/OUTPUT  |                                |
###  +-----------------+                                |
###           |                                         |
###           v                                         |
###  +-----------------+                                |
###  |    nat/OUTPUT   |                                |
###  +-----------------+                                |
###           |                                         |
###           v                                         |
###  +-----------------+                                |
###  |  filter/OUTPUT  |                                |
###  +-----------------+                                |
###           |                                         |
###           .-------------------+---------------------.
###                               |
###                               v
###                      +------------------+
###                      |mangle/POSTROUTING|
###                      +------------------+
###                               |
###                               v
###                      +------------------+
###                      |  nat/POSTROUTING |
###                      +------------------+
###                               |
###                               v
###                          {Packet out}
###
###############################################################################

这是什么意思?

路由可以使用路由表(上面流程图中的“内核路由”)或使用 netfilter 进行。现在,如果 - 这是您的情况最有可能的情况 - 您没有相应地设置路由表,内核将不知道数据包必须去往何处并最终将其丢弃。顺便说一句:在这种情况下,创建一个自定义链非常有用,LOG然后DROP按该顺序添加规则。这样您就可以看到哪些规则受到了影响。同样有用的是iptables-save -c将数据包和字节计数器添加到每个规则行,类似于它为链附加它的方式(格式[packets:bytes])。

对于通过我转发到虚拟机的端口,DNAT我有以下配方(将在下面解释):

#!/bin/bash
VMNET=192.168.1.0/24
MAINIP=66.249.67.195
CONTIP=192.168.1.2
VMPORT=80
INPORT=80
ACTION="-I"
iptables -t nat    $ACTION PREROUTING  -d $MAINIP -p tcp --dport $INPORT -j DNAT --to-destination $CONTIP:$VMPORT
iptables -t nat    $ACTION POSTROUTING -s $VMNET ! -d $VMNET -p tcp -j MASQUERADE --to-ports 1024-65535
iptables -t nat    $ACTION POSTROUTING -s $VMNET ! -d $VMNET -p udp -j MASQUERADE --to-ports 1024-65535
iptables -t nat    $ACTION POSTROUTING -s $VMNET ! -d $VMNET -j MASQUERADE
iptables -t filter $ACTION INPUT       -p tcp -d $MAINIP --dport $INPORT -j ACCEPT
iptables -t filter $ACTION FORWARD     -p tcp --dport $INPORT -d $VMNET -j ACCEPT
iptables -t filter $ACTION FORWARD     -p tcp --dport $INPORT -d $MAINIP -j ACCEPT

请注意,您可能想要更改顺序以适应您自己的规则。另外,如果OUTPUT链没有ACCEPT默认策略,请确保添加输出规则,尽管出于所有实际目的,这应该通过拥有RELATED,ESTABLISHED状态规则来满足。您还可以细化接口以进行匹配或通过通配符进行匹配。例如,我为虚拟访客的网桥提供了所有前缀_(下划线),因此可以匹配-i _+-o _+。同样,对于多个网卡 ( eth0, eth1),您可以将其与 相匹配-i eth+

所以这里发生的是:

  1. DNAT插入一条规则,该规则$INPORT接受 TCP(主机)端口上的输入并将其“路由”到$CONTIP:$VMPORT,即容器的 IP 和容器中的端口。是的,他们可能有所不同。如果他们不这样做,可以省略目标部分(即只是“$CONTIP”)。
  2. 掩盖流量的三个规则虚拟访客的子网但不去另一位虚拟客人。
  3. INPUT允许公共 IP 上的传入数据包(未给出接口,但可能是!)端口通过的规则$INPORT。我认为这条规则并不是严格需要的,至少如果您将其绑定到公共接口则不需要。
  4. $INPORT将流量转发到虚拟来宾子网的规则( $VMNET)
  5. $INPORT将流量转发到公共 IP ( $MAINIP)的规则

sysctl最后但并非最不重要的一点是( )的值/proc/sys/net/ipv4/ip_forward应该是:

# cat /proc/sys/net/ipv4/ip_forward
1

让你的主机成为路由器。

如果不用于echo 1写入上面的“文件”,procfs或者更好地使用sysctl -w net.ipv4.ip_forward=1as root

答案2

我还是不知道为什么但我让它工作了。

我有两个接口,eth0(192.168.99.x)和eth1(192.168.1.x)。它们的存在是出于遗留原因,当我想要一个新的虚拟机并复制我以前的虚拟机时,我很懒。不管怎样,我只是禁用了eth0,一切正常。

我检查了一些rp_filter设置,/etc/sysctl.conf但没有解决它(但让我认为这是一个奇怪的 IF 问题)。这些设置记录在包/usr/share/doc/kernel-doc-x.x.x/Documentation/networking/ip-sysctl.txtkernel-doc

现在它可以工作了,我将把它留在这里供搜索引擎查找,也许有一天这会对其他人有所帮助。

相关内容