在Hetzner独立服务器上使用 Proxmox VE 8.4 教程·第四篇

第四篇 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适用于ARPebtables适用于以太网帧

iptables 需要提升权限才能运行,并且必须由root用户执行,否则将无法正常工作。在大多数 Linux 系统上,iptables 安装在/usr/sbin/iptables目录下,并在其手册页中提供相关说明,安装后可以使用手册页打开man iptables。它也可以安装在 目录下/sbin/iptables,但由于 iptables 更像是一个服务,而非一个“必需的二进制文件”,因此首选位置仍然是/usr/sbin。

术语iptables也通常用于统称内核级组件。x_tables内核模块的名称,它承载着所有四个模块使用的共享代码部分,同时还提供用于扩展的 API;随后,Xtables或多或少用于指代整个防火墙(v​​4、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:已做出路由决策。数据包在交给硬件之前会进入此链。

链本身并不存在;它属于一个。共有三个表:natfiltermangle。除非前面带有选项-t,否则命令默认与filteriptables表相关。例如,显示一些链及其规则的命令 等同于。要显示表nat中的链,请使用命令iptables -L -v -niptables -t filter -L -v -niptables -t nat -L -v -n

链中的每条规则都包含其匹配数据包的规范。它还可能包含目标(用于扩展)或判定(内置决策之一)。当数据包遍历链时,将依次检查每条规则。如果一条规则与数据包不匹配,则数据包将传递到下一条规则。如果一条规则与数据包匹配,则该规则将采取目标/判定指示的操作,这可能导致数据包被允许继续沿着链运行,也可能被禁止。匹配构成了规则集的很大一部分,因为它们包含测试数据包的条件。这些可能发生在OSI模型中的任何层,例如--mac-source-p tcp --dport参数,并且还有与协议无关的匹配,例如-m time

数据包继续穿过链条,直到

  1. 规则与数据包匹配并决定数据包的最终命运,例如通过调用ACCEPT或之一DROP,或返回此类最终命运的模块;
  2. 规则调用RETURN判决,在这种情况下处理返回到调用链;
  3. 到达链的末尾;遍历要么在父链中继续(就像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的操作示范

查看规则

查看规则集

加一个-n以数字形式显示IP和端口,而不是默认的服务名称

修改规则

配置默认规则,不允许数据进入

允许转发

不允许数据流出

添加规则

允许源IP地址为192.168.0.0/24网段的包流进(包括所有的协议,这里也可以指定单个IP)

允许所有的IP到192.168.0.22的访问

开放本机80端口

开放本机的ICMP协议

删除规则

删除允许源地址进入的规则

iptables服务命令
启动服务

或者

停止服务

或者

重启服务

或者

空当前的所有规则和计数

清空所有的防火墙规则

删除用户自定义的空链

清空计数

清空指定链 INPUT 上面的所有规则

删除指定的链,这个链必须没有被其它任何规则引用,而且这条上必须没有任何规则。

如果没有指定链名,则会删除该表中所有非内置的链。

把指定链,或者表中的所有链上的所有计数器清零。

保存规则

保存设置,将规则保存在/etc/sysconfig/iptables文件里

方法1:

或者

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服务端口

注:如果在预设设置把OUTPUT设置成DROP策略的话,就需要设置OUTPUT规则,否则无法进行SSH连接。

Step 4 : PVE上为虚拟机设置端口转发的工具 – iptables

以上我们了解了iptables的使用方法,这对于后面的某种故障有了解决思路,也能更好地使用iptables以优化虚拟机联网性能。

这次是为在虚拟机上面的必要服务端口开放对接到宿主机上的未占用的其他端口上,以供访问虚拟机服务的教程。

1.首先检查iptables安装情况:

2.安装用于永久保存并能在宿主机启动的同时激活iptables转发规则的实用工具:

3.(示例,非实际使用)创建 iptables 规则:

3.5.(示范)删除 iptables 规则:

4.保存 iptables 规则:

5.查看保存的规则:

这个规则是可以用文本编辑器进行改写的,改写了记得输入以下命令以重新生效:

6.查看 iptables 规则生效情况:

以上是iptables的命令示范,其中的变量请根据实际进行修改。下面是我的rules.v4参考:

Step 5 : iptables的常见问题(持续更新中)

1.当您已经配置好了iptables的端口转发规则,生效后发现虚拟机突然不能访问外网。

这个问题就是我之前碰过的比较掉头发的奇葩问题了。先看一下这个故障现象:

第一次:Proxmox 虚拟机网络连接正常,但是无法访问nodeseek.com在内的网站,请问是怎么回事?

好,第二次:【Solved】PVE的虚拟机无法通过IPV4访问外网,但IPV6却畅通无阻地访问,且Web服务正常,外网正常访问本机

这些问题的共同点:宿主机对外连接正常,能够访问网页啥的。宿主机和虚拟机之间的通信正常,可以内网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.等待收集…

—分隔符—

成熟男人样子的饮月君,非常粘人啊~下面已经搭起了帐篷,要不帮我解渴么?

1人评论了“在Hetzner独立服务器上使用 Proxmox VE 8.4 教程·第四篇”

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

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部