第四篇 Proxmox 端口转发

教程参考:
暂无~
如果你想快速安装,可以点此链接
Step 1 : iptables的背景介绍
netfilter/iptables,简称为 iptables。由Rusty Russell开发,于1998年正式启动了 netfilter/iptables 项目,皆在取代 ipchains 和 ipnatctl ,同样这两个项目的作者也是他,与iptables的区别就是ipchains是无状态的,这与Hetzner那个防火墙差不多是一个路子(点名批评)。1999年成立了 netfilter 核心团队,并在1999年8月正式发布,被合并至Linux 内核 2.3.15版本以至后来成为 2.4.0 稳定版本。
下面是来自于维基百科的对iptables的解释:(iptables – Wikipedia)
iptables是一个用户空间实用程序,允许系统管理员配置Linux 内核防火墙的IP 数据包过滤规则,这些规则由不同的Netfilter模块实现。这些过滤器被组织成一组表,其中包含用于处理网络流量数据包的规则链。目前,不同的内核模块和程序用于不同的协议;iptables适用于 IPv4,ip6tables适用于 IPv6,arptables适用于ARP,ebtables适用于以太网帧。
iptables 需要提升权限才能运行,并且必须由root用户执行,否则将无法正常工作。在大多数 Linux 系统上,iptables 安装在/usr/sbin/iptables目录下,并在其手册页中提供相关说明,安装后可以使用手册页打开man iptables
。它也可以安装在 目录下/sbin/iptables
,但由于 iptables 更像是一个服务,而非一个“必需的二进制文件”,因此首选位置仍然是/usr/sbin。
术语iptables也通常用于统称内核级组件。x_tables是内核模块的名称,它承载着所有四个模块使用的共享代码部分,同时还提供用于扩展的 API;随后,Xtables或多或少用于指代整个防火墙(v4、v6、arp 和 eb)架构。
iptables 取代了ipchains;iptables 的后继者是nftables,它于 2014 年 1 月 19 日发布[ 2 ] ,并在内核版本 3.13 中 合并到Linux 内核主线。
iptables 概述:
iptables 允许系统管理员定义包含用于处理数据包的规则链的表。每个表都与一种不同的数据包处理方式相关联。数据包的处理是通过按顺序遍历链中的规则来实现的。链中的规则可以触发跳转(goto)或跳转到另一个链,并且可以重复执行到所需的嵌套层级。(跳转类似于“调用”,即记住跳转的起点。)每个到达或离开计算机的网络数据包至少要遍历一条链。
数据包的来源决定了它最初会遍历哪条链。虽然一个表可能并不包含所有链,但预定义链中确实有五条链(分别对应五个可用的 Netfilter 钩子)。预定义链包含一个策略,例如 DROP,当数据包到达链的末尾时,该策略会被应用到数据包上。系统管理员可以根据需要创建任意数量的其他链。这些链没有策略;如果数据包到达链的末尾,它将被返回到调用它的链。链可以是空的。
PREROUTING
:在做出路由决策之前,数据包将进入此链。INPUT
:数据包将在本地投递。这与进程是否打开套接字无关;本地投递由“本地投递”路由表控制:ip route show table local
。FORWARD
:所有已路由且不用于本地传送的数据包都将遍历此链。OUTPUT
:从机器本身发送的数据包将访问该链。POSTROUTING
:已做出路由决策。数据包在交给硬件之前会进入此链。
链本身并不存在;它属于一个表。共有三个表:nat、filter和mangle。除非前面带有选项-t,否则命令默认与filteriptables
表相关。例如,显示一些链及其规则的命令 等同于。要显示表nat中的链,请使用命令iptables -L -v -n
iptables -t filter -L -v -n
iptables -t nat -L -v -n
链中的每条规则都包含其匹配数据包的规范。它还可能包含目标(用于扩展)或判定(内置决策之一)。当数据包遍历链时,将依次检查每条规则。如果一条规则与数据包不匹配,则数据包将传递到下一条规则。如果一条规则与数据包匹配,则该规则将采取目标/判定指示的操作,这可能导致数据包被允许继续沿着链运行,也可能被禁止。匹配构成了规则集的很大一部分,因为它们包含测试数据包的条件。这些可能发生在OSI模型中的任何层,例如--mac-source
和-p tcp --dport
参数,并且还有与协议无关的匹配,例如-m time
。
数据包继续穿过链条,直到
- 规则与数据包匹配并决定数据包的最终命运,例如通过调用
ACCEPT
或之一DROP
,或返回此类最终命运的模块; - 规则调用
RETURN
判决,在这种情况下处理返回到调用链; - 到达链的末尾;遍历要么在父链中继续(就像
RETURN
使用过一样),要么使用作为最终命运的基本链策略。
ACCEPT
目标还会返回类似(NAT
模块将执行此操作)或DROP
(例如模块)的判决REJECT
,但也可能暗示CONTINUE
(例如LOG
模块;CONTINUE
是一个内部名称)继续执行下一个规则,就好像根本没有指定任何目标/判决一样。
—分隔符—
这个时候nftables虽然发展完善,但是对于怎么进行NAT配置我们仍然正在探索中,所以说要先用上已经成熟无比的稳妥方法,这样对系统的稳定度大有裨益。但是由于年代较早,对于现在的网络情况勉强够用,但是针对我之前碰到的那个奇怪问题,iptables也有一部分的责任。
iptables 并不是防火墙的本体,他只是一个防火墙的管理工具,而真正的防火墙本体便是 netfilter ,在内核中实现数据包过滤的重要功能。


如上两个图,解释了 netfilter/iptables 工作流程。在后面的设置端口转发能够实现的便是这样的。


Step 2 : iptables的基础结构
(来源于:iptables全面详解(图文并茂含命令指南))
iptables的规则表和链:
表(tables)提供特定的功能,iptables内置了4个表,即filter表、nat表、mangle表和raw表,分别用于实现包过滤,网络地址转换、包重构(修改)和数据跟踪处理。
链(chains)是数据包传播的路径,每一条链其实就是众多规则中的一个检查清单,每一条链中可以有一条或数条规则。当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。
规则表:
1. filter表——三个链:INPUT、FORWARD、OUTPUT
作用:过滤数据包 内核模块:iptables_filter.
2. Nat表——三个链:PREROUTING、POSTROUTING、OUTPUT
作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat
3. Mangle表——五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(别看这个表这么麻烦,咱们设置策略时几乎都不会用到它),
4. Raw表——两个链:OUTPUT、PREROUTING
作用:决定数据包是否被状态跟踪机制处理 内核模块:iptable_raw
- filter表
主要用于对数据包进行过滤,根据具体的规则决定是否放行该数据包(如DROP、ACCEPT、REJECT、LOG)。filter 表对应的内核模块为iptable_filter,包含三个规则链:
INPUT链:INPUT针对那些目的地是本地的包
FORWARD链:FORWARD过滤所有不是本地产生的并且目的地不是本地(即本机只是负责转发)的包
OUTPUT链:OUTPUT是用来过滤所有本地生成的包 - nat表
主要用于修改数据包的IP地址、端口号等信息(网络地址转换,如SNAT、DNAT、MASQUERADE、REDIRECT)。属于一个流的包(因为包
的大小限制导致数据可能会被分成多个数据包)只会经过这个表一次。如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作,也就是说,余下的包不会再通过这个表。表对应的内核模块为 iptable_nat,包含三个链:
PREROUTING链:作用是在包刚刚到达防火墙时改变它的目的地址
OUTPUT链:改变本地产生的包的目的地址
POSTROUTING链:在包就要离开防火墙之前改变其源地址 - mangle表
主要用于修改数据包的TOS(Type Of Service,服务类型)、TTL(Time To Live,生存周期)指以及为数据包设置Mark标记,以实现Qos(Quality Of Service,服务质量)调整以及策略路由等应用,由于需要相应的路由设备支持,因此应用并不广泛。包含五个规则链——PREROUTING,POSTROUTING,INPUT,OUTPUT,FORWARD。
强烈建议你不要在这个表里做任何过滤,不管是DANT,SNAT或者Masquerade。 - raw表
是自1.2.9以后版本的iptables新增的表,主要用于决定数据包是否被状态跟踪机制处理。在匹配数据包时,raw表的规则要优先于其他表。包含两条规则链——OUTPUT、PREROUTING
iptables中数据包和4种被跟踪连接的4种不同状态:
NEW:该包想要开始一个连接(重新连接或将连接重定向)
RELATED:该包是属于某个已经建立的连接所建立的新连接。例如:FTP的数据传输连接就是控制连接所 RELATED出来的连接。--icmp-type 0
( ping 应答) 就是--icmp-type 8
(ping 请求)所RELATED出来的。
ESTABLISHED :只要发送并接到应答,一个数据连接从NEW变为ESTABLISHED,而且该状态会继续匹配这个连接的后续数据包。
INVALID:数据包不能被识别属于哪个连接或没有任何状态比如内存溢出,收到不知属于哪个连接的ICMP错误信息,一般应该DROP这个状态的任何数据。
规则表之间的优先顺序
Raw>>>>mangle>>>>nat>>>>filter
规则链之间的优先顺序(分三种情况):
第一种情况:入站数据流向
从外界到达防火墙的数据包,先被PREROUTING规则链处理(是否修改数据包地址等),之后会进行路由选择(判断该数据包应该发往何处),如果数据包的目标主机是防火墙本机(比如说Internet用户访问防火墙主机中的web服务器的数据包),那么内核将其传给INPUT链进行处理(决定是否允许通过等),通过以后再交给系统上层的应用程序(比如Apache服务器)进行响应。
第二冲情况:转发数据流向
来自外界的数据包到达防火墙后,首先被PREROUTING规则链处理,之后会进行路由选择,如果数据包的目标地址是其它外部地址(比如局域网用户通过网关访问QQ站点的数据包),则内核将其传递给FORWARD链进行处理(是否转发或拦截),然后再交给POSTROUTING规则链(是否修改数据包的地址等)进行处理。
第三种情况:出站数据流向
防火墙本机向外部地址发送的数据包(比如在防火墙主机中测试公网DNS服务器时),首先被OUTPUT规则链处理,之后进行路由选择,然后传递给POSTROUTING规则链(是否修改数据包的地址等)进行处理。
规则链:
1.INPUT——进来的数据包应用此规则链中的策略
2.OUTPUT——外出的数据包应用此规则链中的策略
3.FORWARD——转发数据包时应用此规则链中的策略
4.PREROUTING——对数据包作路由选择前应用此链中的规则
(记住!所有的数据包进来的时侯都先由这个链处理)
5.POSTROUTING——对数据包作路由选择后应用此链中的规则
(所有的数据包出来的时侯都先由这个链处理)
防火墙处理数据包的方式(规则):
ACCEPT:允许数据包通过
DROP:直接丢弃数据包,不给任何回应信息
REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息。
SNAT:源地址转换。在进入路由层面的route之后,出本地的网络栈之前,改写源地址,目标地址不变,并在本机建立NAT表项,当数据返回时,根据NAT表将目的地址数据改写为数据发送出去时候的源地址,并发送给主机。解决内网用户用同一个公网地址上网的问题。
MASQUERADE,是SNAT的一种特殊形式,适用于像adsl这种临时会变的ip上
DNAT:目标地址转换。和SNAT相反,IP包经过route之前,重新修改目标地址,源地址不变,在本机建立NAT表项,当数据返回时,根据NAT表将源地址修改为数据发送过来时的目标地址,并发给远程主机。可以隐藏后端服务器的真实地址。
REDIRECT:是DNAT的一种特殊形式,将网络包转发到本地host上(不管IP头部指定的目标地址是啥),方便在本机做端口转发。
LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则
除去最后一个LOG,前3条规则匹配数据包后,该数据包不会再往下继续匹配了,所以编写的规则顺序极其关键。

管理和设置iptables规则
[-t 表名]:该规则所操作的哪个表,可以使用filter、nat等,如果没有指定则默认为filter
-A:新增一条规则,到该规则链列表的最后一行
-I:插入一条规则,原本该位置上的规则会往后顺序移动,没有指定编号则为1
-D:从规则链中删除一条规则,要么输入完整的规则,或者指定规则编号加以删除
-R:替换某条规则,规则替换不会改变顺序,而且必须指定编号。
-P:设置某条规则链的默认动作
-nL:-L、-n,查看当前运行的防火墙规则列表
chain名:指定规则表的哪个链,如INPUT、OUPUT、FORWARD、PREROUTING等
[规则编号]:插入、删除、替换规则时用,--line-numbers
显示号码
[-i|o 网卡名称]:i是指定数据包从哪块网卡进入,o是指定数据包从哪块网卡输出
[-p 协议类型]:可以指定规则应用的协议,包含tcp、udp和icmp等
[-s 源IP地址]:源主机的IP地址或子网地址
[–sport 源端口号]:数据包的IP的源端口号
[-d目标IP地址]:目标主机的IP地址或子网地址
[–dport目标端口号]:数据包的IP的目标端口号
-m:extend matches,这个选项用于提供更多的匹配参数,如:
-m state –state ESTABLISHED,RELATED
-m tcp –dport 22
-m multiport –dports 80,8080
-m icmp –icmp-type 8
<-j 动作>:处理数据包的动作,包括ACCEPT、DROP、REJECT等
Step 3 : iptables的操作示范
查看规则
查看规则集
[root@zcwyou ~]# iptables --list -n
加一个-n以数字形式显示IP和端口,而不是默认的服务名称
修改规则
配置默认规则,不允许数据进入
[root@zcwyou ~]# iptables -P INPUT DROP
允许转发
[root@zcwyou ~]# iptables -P FORWARD ACCEPT
不允许数据流出
[root@zcwyou ~]# iptables -P OUTPUT DROP
添加规则
允许源IP地址为192.168.0.0/24网段的包流进(包括所有的协议,这里也可以指定单个IP)
[root@zcwyou ~]# iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT
允许所有的IP到192.168.0.22的访问
[root@zcwyou ~]# iptables -A INPUT -d 192.168.0.22 -j ACCEPT
开放本机80端口
[root@zcwyou ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
开放本机的ICMP协议
[root@zcwyou ~]# iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
删除规则
删除允许源地址进入的规则
[root@zcwyou ~]# iptables -D INPUT -s 192.168.0.21 -j ACCEPT
iptables服务命令
启动服务
[root@zcwyou ~]# /etc/init.d/iptables start
或者
[root@zcwyou ~]# service iptables start
停止服务
[root@zcwyou ~]# /etc/init.d/iptables stop
或者
[root@zcwyou ~]# service iptables stop
重启服务
[root@zcwyou ~]# /etc/init.d/iptables restart
或者
[root@zcwyou ~]# service iptables restart
空当前的所有规则和计数
清空所有的防火墙规则
[root@zcwyou ~]# iptables -F
删除用户自定义的空链
[root@zcwyou ~]# iptables -X
清空计数
[root@zcwyou ~]# iptables -Z
清空指定链 INPUT 上面的所有规则
[root@zcwyou ~]# iptables -F INPUT
删除指定的链,这个链必须没有被其它任何规则引用,而且这条上必须没有任何规则。
[root@zcwyou ~]# iptables -X INPUT
如果没有指定链名,则会删除该表中所有非内置的链。
把指定链,或者表中的所有链上的所有计数器清零。
[root@zcwyou ~]# iptables -Z INPUT
保存规则
保存设置,将规则保存在/etc/sysconfig/iptables文件里
方法1:
[root@zcwyou ~]# /etc/init.d/iptables save
或者
[root@zcwyou ~]# service iptables save
iptables防火墙的配置文件存放于:/etc/sysconfig/iptables
修改/etc/sysconfig/iptables-config 将里面的IPTABLES_SAVE_ON_STOP=”no”, 这一句的”no”改为”yes”这样每次服务在停止之前会自动将现有的规则保存在 /etc/sysconfig/iptables 这个文件中去。
iptables命令及参数介绍
iptables常用命令:
iptables -A 将一个规则添加到链末尾
iptables -D 将指定的链中删除规则
iptables -F 将指定的链中删除所有规则
iptables -I 将在指定链的指定编号位置插入一个规则
iptables -L 列出指定链中所有规则
iptables -t nat -L 列出所有NAT链中所有规则
iptables -N 建立用户定义链
iptables -X 删除用户定义链
iptables -P 修改链的默认设置,如将iptables -P INPUT DROP (将INPUT链设置为DROP)
常见设置参数介绍:--dport
指定目标TCP/IP端口 如 –dport 80--sport
指定源TCP/IP端口 如 –sport 80
-p tcp 指定协议为tcp
-p icmp 指定协议为ICMP
-p udp 指定协议为UDP
-j DROP 拒绝
-j ACCEPT 允许
-j REJECT 拒绝并向发出消息的计算机发一个消息
-j LOG 在/var/log/messages中登记分组匹配的记录
-m mac –mac 绑定MAC地址
-m limit –limit 1/s 1/m 设置时间策列
-s 10.10.0.0或10.10.0.0/16 指定源地址或地址段
-d 10.10.0.0或10.10.0.0/16 指定目标地址或地址段
-s ! 10.10.0.0 指定源地址以外的
假设INPUT和OUTPUT链的默认规则都是DROP,所以我们就写需要ACCETP(通过)的链。
开启SSH服务端口
[root@zcwyou ~]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
[root@zcwyou ~]# iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
注:如果在预设设置把OUTPUT设置成DROP策略的话,就需要设置OUTPUT规则,否则无法进行SSH连接。
Step 4 : PVE上为虚拟机设置端口转发的工具 – iptables
以上我们了解了iptables的使用方法,这对于后面的某种故障有了解决思路,也能更好地使用iptables以优化虚拟机联网性能。
这次是为在虚拟机上面的必要服务端口开放对接到宿主机上的未占用的其他端口上,以供访问虚拟机服务的教程。
1.首先检查iptables安装情况:
root@BSX05 /etc/network # iptables --version
iptables v1.8.9 (legacy)
2.安装用于永久保存并能在宿主机启动的同时激活iptables转发规则的实用工具:
apt-get install iptables-persistent
3.(示例,非实际使用)创建 iptables 规则:
iptables -A INPUT -p tcp --dport 80 -j DROP
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 23333 -j DNAT --to-destination 192.168.1.2:22
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 63306 -j DNAT --to-destination 127.0.0.1:3306
iptables -t nat -A POSTROUTING -p tcp -m tcp --dport 63306 -j SNAT --to-source 127.0.0.1
3.5.(示范)删除 iptables 规则:
iptables -L -t nat --line-number
iptables -t nat -D POSTROUTING 1 #1为nat规则表的规则行号。
4.保存 iptables 规则:
netfilter-persistent save
5.查看保存的规则:
root@BSX05 /etc/network # vim /etc/iptables/rules.v4
root@BSX05 /etc/network # vim /etc/iptables/rules.v6
这个规则是可以用文本编辑器进行改写的,改写了记得输入以下命令以重新生效:
netfilter-persistent restart
6.查看 iptables 规则生效情况:
root@BSX05 /etc/network # iptables -L -n -v
Chain INPUT (policy ACCEPT 75262 packets, 5103K bytes)
pkts bytes target prot opt in out source destination
293K 105M ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Chain FORWARD (policy ACCEPT 785K packets, 775M bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 9647 packets, 590K bytes)
pkts bytes target prot opt in out source destination
303K 108M ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
或者
root@BSX05 /etc/network # iptables -L -t nat --line-number
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 DNAT tcp -- anywhere anywhere tcp dpt:3395 to:10.0.0.8:3389
2 DNAT tcp -- anywhere anywhere tcp dpt:20022 to:10.0.0.7:22
3 DNAT tcp -- anywhere anywhere tcp dpt:20023 to:10.0.0.7:3389
4 DNAT tcp -- anywhere anywhere tcp dpt:20024 to:10.0.0.7:3390
5 DNAT tcp -- anywhere anywhere tcp dpt:22032 to:10.0.0.7:22032
6 DNAT tcp -- anywhere BSX05 tcp dpt:http to:10.0.0.7:80
7 DNAT tcp -- anywhere BSX05 tcp dpt:https to:10.0.0.7:443
8 DNAT tcp -- anywhere anywhere tcp dpt:888 to:10.0.0.7:888
9 DNAT tcp -- anywhere anywhere tcp dpt:81 to:10.0.0.8:80
10 DNAT tcp -- anywhere anywhere tcp dpt:snpp to:10.0.0.8:443
11 DNAT tcp -- anywhere anywhere tcp dpt:6080 to:10.0.0.8:6080
12 DNAT tcp -- anywhere anywhere tcp dpt:6443 to:10.0.0.8:6443
13 DNAT tcp -- anywhere anywhere tcp dpt:ftp to:10.0.0.8:21
14 DNAT tcp -- anywhere anywhere tcp dpt:telnet to:10.0.0.7:21
15 DNAT tcp -- anywhere anywhere tcp dpt:20025 to:10.0.0.9:22
16 DNAT tcp -- anywhere BSX05 tcp dpt:smtp to:10.0.0.8:25
17 DNAT tcp -- anywhere BSX05 tcp dpt:pop3 to:10.0.0.8:110
18 DNAT tcp -- anywhere BSX05 tcp dpt:imap2 to:10.0.0.8:143
19 DNAT tcp -- anywhere BSX05 tcp dpt:submissions to:10.0.0.8:465
20 DNAT tcp -- anywhere BSX05 tcp dpt:submission to:10.0.0.8:587
21 DNAT tcp -- anywhere BSX05 tcp dpt:imaps to:10.0.0.8:993
22 DNAT tcp -- anywhere BSX05 tcp dpt:pop3s to:10.0.0.8:995
Chain INPUT (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
num target prot opt source destination
1 MASQUERADE all -- 10.0.0.0/24 anywhere
2 MASQUERADE all -- 10.0.0.0/24 anywhere
3 MASQUERADE all -- 10.0.0.0/24 anywhere
以上是iptables的命令示范,其中的变量请根据实际进行修改。下面是我的rules.v4参考:
# Generated by iptables-save v1.8.9 on Thu May 8 17:40:40 2025
*nat
:PREROUTING ACCEPT [67:4314]
:INPUT ACCEPT [52:3321]
:OUTPUT ACCEPT [3:201]
:POSTROUTING ACCEPT [11:633]
-A PREROUTING -p tcp -m tcp --dport 3395 -j DNAT --to-destination 10.0.0.8:3389
-A PREROUTING -p tcp -m tcp --dport 20022 -j DNAT --to-destination 10.0.0.7:22
-A PREROUTING -p tcp -m tcp --dport 20023 -j DNAT --to-destination 10.0.0.7:3389
-A PREROUTING -p tcp -m tcp --dport 20024 -j DNAT --to-destination 10.0.0.7:3390
-A PREROUTING -p tcp -m tcp --dport 22032 -j DNAT --to-destination 10.0.0.7:22032
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.7:80
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.0.0.7:443
-A PREROUTING -p tcp -m tcp --dport 888 -j DNAT --to-destination 10.0.0.7:888
-A PREROUTING -p tcp -m tcp --dport 81 -j DNAT --to-destination 10.0.0.8:80
-A PREROUTING -p tcp -m tcp --dport 444 -j DNAT --to-destination 10.0.0.8:443
-A PREROUTING -p tcp -m tcp --dport 6080 -j DNAT --to-destination 10.0.0.8:6080
-A PREROUTING -p tcp -m tcp --dport 6443 -j DNAT --to-destination 10.0.0.8:6443
-A PREROUTING -p tcp -m tcp --dport 21 -j DNAT --to-destination 10.0.0.8:21
-A PREROUTING -p tcp -m tcp --dport 23 -j DNAT --to-destination 10.0.0.7:21
-A PREROUTING -p tcp -m tcp --dport 20025 -j DNAT --to-destination 10.0.0.9:22
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.0.0.8:25
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 110 -j DNAT --to-destination 10.0.0.8:110
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 143 -j DNAT --to-destination 10.0.0.8:143
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 465 -j DNAT --to-destination 10.0.0.8:465
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 587 -j DNAT --to-destination 10.0.0.8:587
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 993 -j DNAT --to-destination 10.0.0.8:993
-A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp --dport 995 -j DNAT --to-destination 10.0.0.8:995
-A POSTROUTING -s 10.0.0.0/24 -o vmbr0 -j MASQUERADE
-A POSTROUTING -s 10.0.0.0/24 -o vmbr0 -j MASQUERADE
-A POSTROUTING -s 10.0.0.0/24 -o vmbr0 -j MASQUERADE
COMMIT
# Completed on Thu May 8 17:40:40 2025
# Generated by iptables-save v1.8.9 on Thu May 8 17:40:40 2025
*filter
:INPUT ACCEPT [5251:355788]
:FORWARD ACCEPT [47056:6056308]
:OUTPUT ACCEPT [238:16538]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT
# Completed on Thu May 8 17:40:40 2025
# Generated by iptables-save v1.8.9 on Thu May 8 17:40:40 2025
*raw
:PREROUTING ACCEPT [344:24930]
:OUTPUT ACCEPT [168:21947]
-A PREROUTING -i fwbr+ -j CT --zone 1
-A PREROUTING -i fwbr+ -j CT --zone 1
-A PREROUTING -i fwbr+ -j CT --zone 1
COMMIT
# Completed on Thu May 8 17:40:40 2025


Step 5 : iptables的常见问题(持续更新中)
1.当您已经配置好了iptables的端口转发规则,生效后发现虚拟机突然不能访问外网。
这个问题就是我之前碰过的比较掉头发的奇葩问题了。先看一下这个故障现象:
第一次:Proxmox 虚拟机网络连接正常,但是无法访问nodeseek.com在内的网站,请问是怎么回事?
最近遇到了非常麻烦的问题:
在五一前几天登录服务器,访问外网什么的都很正常,用来下载web服务器的模块都没问题。
然而到五一前三天的时候,这个时候在虚拟机上面打开游览器,打开nodeseek.com一直报连接超时(ERR_CONNECTION_TIMED_OUT)
然而的然而,访问google.com,bing.com等特定问题却是秒开,真的是牛逼...
但是PVE Web界面,RDP,SSH,SFTP均无受影响,甚至还能在另一台不同地方的服务器访问我的服务器都是正常访问的。
这个问题好像是第一次出现的,有哪位大佬知道的可以发表一二,以此解惑。
好,第二次:【Solved】PVE的虚拟机无法通过IPV4访问外网,但IPV6却畅通无阻地访问,且Web服务正常,外网正常访问本机
在HZ的防火墙重新梳理,该开通的端口全开了,特别是tcp established那个,意思是是TCP传输控制协议,请注意这就是这个问题的根源。开通这个协议的端口之后,在宿主机上面重新检查了UFW防火墙和INTERFACE网络配置文件,确认了无错误之后,curl nodeseek.com便正常显示了,然后我当时在考虑是不是这个原因也导致了虚拟机无法访问nodeseek等网站。
这些问题的共同点:宿主机对外连接正常,能够访问网页啥的。宿主机和虚拟机之间的通信正常,可以内网IP访问网站,而且虚拟机正常SSH、FTP、RDP等等。就是虚拟机不能在上面访问外网网站,除了支持v6访问的网站是正常访问的。
这个故障看起来像是v4的问题,而且还是端口转发的问题,之前说到,想要访问虚拟机上面的服务,需要把宿主机上面的未占用的端口对接到虚拟机上的服务端口。但是这个话不全面,比如虚拟机的http端口为80,我们就需要把它接到宿主机上面的某一个端口,此时宿主机我当时并未安装Web服务器,因此通过端口检查此端口为:空闲,为了省事直接把它对接到宿主机的80端口罢了。殊不知这就是造成虚拟机无法访问外网网站的罪魁祸首。我们需要知道这个iptables是怎么工作的,简单来说,INPUT是传入的意思,OUTPUT是传出的意思,按普通人的理解,这传入是从公网的数据包传入到虚拟机上面,而传出是虚拟机的数据包上面传出到公网上面;然而实际上这是反过来的,INPUT:公网 <- 宿主机 <- 虚拟机 | OUTPUT:公网 -> 宿主机 -> 虚拟机 。这就是为什么我们端口转发设置是关于OUTPUT居多的原因,我们在iptables上面已经设置了 INPUT 全局 ACCEPT,这样出问题的便是OUTPUT了。
各位应该了解过 TCP/IP 协议么?这里可详细了解 TCP/IP 协议的作用:TCP/IP协议 (图解+秒懂+史上最全)
简单来说,TCP有三次握手,如下图所示:

我们虚拟机无法访问外网网站,在三次握手图中的第二次握手:SYN=1,ACK=1,Seq=b,Ack=a+1 这个地方出现了问题:陷入未知位置。从而导致虚拟机上访问外网网站连接超时,如果在服务端那边,查看Web服务器连接日志应该会有相关的客户端连接超时,上一条应该是是成功接收这个客户端的SYN请求。
而造成这样的原因,在iptables上面的规则说明可知:iptables 一般会管理所有网卡的数据包传输,宿主机没有安装Web服务器,但是宿主机可不止拥有一个网卡,在其他网卡上可能会有所连接的客户端存在80端口开放,因此 iptables 会根据网卡的优先级,在拥有相同的80端口的情况下,优先把外网的ACK报文转发到不属于目标客户端的客户端上的80端口上,由于此端口占用的软件会自动丢弃不属于自己该收到的数据包,因此ACK报文石沉大海,这导致了目标客户端未能在超时时间内接收到。而且这并不是说,iptables固定死了这些常见端口,个人认为如果只有一个公网网卡的话,只搭载一个内网网卡,虚拟机也能会正常访问外网的。这在:【已解决】Proxmox 8.4虚拟机上IPV4无法访问互联网,但IPV6可以访问互联网。有所记载。
根据上面的帖子可知,我们在iptables规则表中发现几个我当时认为没有问题的错误规则:
- -A PREROUTING -p tcp -m tcp –dport 80 -j DNAT –to-destination 10.0.0.7:80
- -A PREROUTING -p tcp -m tcp –dport 443 -j DNAT –to-destination 10.0.0.7:443
根据描述,需要在 -p 的前面加上 <-d 强制性目标外部IP>,例如:-d 192.168.xxx.xxx/32 ,所以我修改为如下内容:
- -A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp –dport 80 -j DNAT –to-destination 10.0.0.7:80
- -A PREROUTING -d 65.108.196.xxx/32 -p tcp -m tcp –dport 443 -j DNAT –to-destination 10.0.0.7:443
iptables规则重新生效的瞬间,虚拟机上一直连接超时的网站突然自动刷新,正常打印网站内容,这表示着虚拟机正式恢复外网访问了。问题解决!
2.等待收集…
—分隔符—

Pingback: 在Hetzner独立服务器上使用 Proxmox VE 8.4 教程·第三篇 – LandC77's blog