关于nat表格

关于nat表格

我目前已在服务器上设置了 IPTables,以将特定接口 (venet0:1) 上的某些端口转发到另一台 IP 上的服务器。我的配置文件如下所示:

# Generated by iptables-save v1.4.12 on Sat Jun  8 08:36:54 2013
*mangle
:PREROUTING ACCEPT [480:39372]
:INPUT ACCEPT [480:39372]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [339:44328]
:POSTROUTING ACCEPT [339:44328]
COMMIT
# Completed on Sat Jun  8 08:36:54 2013
# Generated by iptables-save v1.4.12 on Sat Jun  8 08:36:54 2013
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -i venet0:1 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 51315 -j DNAT --to-destination 76.xxx.xxx.xxx
-A PREROUTING -i venet0:1 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 27015:27020 -j DNAT --to-destination 76.xxx.xxx.xxx
-A PREROUTING -i venet0:1 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 25565:25570 -j DNAT --to-destination 76.xxx.xxx.xxx
-A PREROUTING -i venet0:1 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 7777 -j DNAT --to-destination 76.xxx.xxx.xxx
COMMIT
# Completed on Sat Jun  8 08:36:54 2013
# Generated by iptables-save v1.4.12 on Sat Jun  8 08:36:54 2013
*filter
:INPUT ACCEPT [86:6572]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [66:6912]
-A INPUT -i venet0:1 -j LOG
-A INPUT -i venet0:1 -p tcp -m tcp --dport 51315 -j ACCEPT
-A INPUT -i venet0:1 -p tcp -m tcp --dport 27015:27020 -j ACCEPT
-A INPUT -i venet0:1 -p tcp -m tcp --dport 25565:25570 -j ACCEPT
-A INPUT -i venet0:1 -p tcp -m tcp --dport 7777 -j ACCEPT
COMMIT
# Completed on Sat Jun  8 08:36:54 2013

(隐藏 IP 地址)

我已确保启用了 IPv4 转发,但是当我执行 时lsmod,什么都没有显示。

我也尝试过modprobe添加 iptables 内核模块,但是没有找到任何东西。

会不会是 IPTables 模块没有安装,而我需要重新编译内核才能安装它们?

当我尝试连接这些端口时,连接被拒绝,就好像 iptables 根本没有运行一样。

我在 OpenVZ VPS(主机名实际上不是hostname)上运行 Ubuntu 12.04 LTS。

Linux hostname 2.6.32-042stab076.7 #1 SMP Thu Apr 25 13:35:47 MSK 2013 x86_64 x86_64 x86_64 GNU/Linux

编辑:好的,根据其中一个答案的建议,我将其更改为venet0:1venet0行为仍然相同。端口的 tcpdump 显示以下内容:

23:15:34.940437 IP 76.yyy.yyy.yyy.53802 > 192.xxx.xxx.xxx.51315: Flags [S], seq 3804882566, win 65535, options [mss 1460,nop,wscale 0,nop,nop,sackOK], length 0
23:15:34.940485 IP 76.yyy.yyy.yyy.53802 > 76.xxx.xxx.xxx.51315: Flags [S], seq 3804882566, win 65535, options [mss 1460,nop,wscale 0,nop,nop,sackOK], length 0

在上面的代码中,76.yyy.yyy.yyy 是我用来测试连接的计算机,192.xxx.xxx.xxx 是服务器的 IP,76.xxx.xxx.xxx 是它应该转发到的服务器的地址。它似乎以某种方式转发了流量,只是数据包的长度为零,而且从未得到回复。我还在接收机器上运行了 tcpdump,但什么也没出现。

答案1

我已确保启用了 IPv4 转发,但是当我执行 lsmod 时,什么都没有显示。

lsmod仅显示已加载的模块。这与 几乎没有关系iptablesiptables在插入规则时会自动加载所需的模块,如果失败,它会通过漂亮的错误消息通知您。如果您的规则已成功加载,iptables正在运行并且没有缺少任何模块。

此外,没有显示任何内容也是完全正常的lsmod:这意味着该功能被编译到内核中。所以的输出lsmod在这里完全不相关。

当我尝试连接这些端口时,连接被拒绝,就好像 iptables 根本没有运行一样。

-A 预路由 -ivenet0:1-p tcp -m state --state 新、相关、已建立 -m tcp --dport 51315 -j DNAT --to-destination 76.xxx.xxx.xxx

这里的问题很可能是venet0:1不存在的。iptables有这个限制,它接受任何接口名称,甚至是不存在的接口名称或看起来甚至不像接口名称的字符串(您甚至可以输入 IP 地址,只是为了好玩,它不起作用)。如果没有与给定名称匹配的接口,则规则将不匹配。当您的网络接口尚未准备好,或者您的网络接口是热插拔时,这很有用,但大多数时候,无法验证接口名称是否确实存在是一件很麻烦的事。很容易打错字。

相反,使用:

-A PREROUTING -i venet0 -p tcp -m state --state NEW,RELATED,ESTABLISHED -m tcp --dport 51315 -j DNAT --to-destination 76.xxx.xxx.xxx

现在,您可能会回答“但venet0:1存在,ifconfig表明它!”。

Exceptifconfig是错误的。原因是什么?Linuxifconfig已经过时、弃用、过时且糟糕。请使用ip addr。和 以及可能还有其他的也一样routenetstat全部brctl替换ip它们。

ip addr不要伪造或向内核隐藏任何信息。您看到的是网络堆栈的真实状态。现在您可以看到没有这样的venet0:1接口。相反,venet0有多个 IP 地址。这是自 Linux 2.2 时代以来一直支持的功能。

但是ifconfig(或者实际上,它用于与内核通信的 BSD API)不支持一个接口有多个 IP 地址。因此,您可以使用这个称为“接口别名”的旧 BSD 技巧,您可以使用它ifconfig venet0:1为配置额外的 IP 地址venet0,它将显示为venet0:1接口。除非venet0:1不是接口。差得远。

实际上,ip addr它会向您显示venet0:1IP 地址的标签,手册页会告诉您:

In order to preserve compatibility with Linux-2.0 net aliases, this string
must coincide with the name of the device or must be prefixed with the
device name followed by colon.

手册页iptables曾经告诉您不要使用接口别名或任何带有冒号的内容,但那行一定已经消失了。

答案2

关于nat表格

您可以在iptables 手册页

当遇到创建新连接的数据包时,就会查阅此表。

因此您不必在那里检查连接状态,因为该表仅检查NEW连接。

让我们谈谈你的问题

开放VZ是一种基于命名空间

基本上,您的虚拟机是一个简单的文件夹,其中设置并包含一个 Linux 系统树,让您感觉自己身处一个真正独立的系统中。这种虚拟化方法的独创性在于所有容器都在运行有且仅有一个Linux内核实例,主持人的一个。

现在您遇到了一个问题,因为您没有运行自己的内核实例,所以您无法完全控制,这解释了很多事情。

  • lsmod是空的,因为出于安全原因,他们不会让您知道哪些模块正在运行系统,当然,他们也不会让您通过添加新模块来更改系统配置。想象一下,每个客户端都修改运行其他客户端的相同内核。

  • 即使你可以允许使用iptables对于容器来说,nat可能尚未启用。

相关内容