你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

Linux之iptables端口转发

[复制链接]
gaosmile 发布时间:2020-11-3 12:02
0 背景
考虑一种网络拓扑应用情景,一个内部局域网中有多台服务器提供不同的服务,如web服务、FTP服务、ssh、telnet等,通过服务器(或网关、防火墙)连接外部网络,如果外部网络上的主机需要访问这些服务器,则需要在网关上实现转发。
再转述成另一种应用场合,多台设备连接到一台服务器,服务器有2个网卡,分别连接内外网。外网无法直接访问设备上的数据、服务。在服务器上实现转发后,则可达到目的。
网络拓扑如下:
微信图片_20201103113307.png
比如,可以通过服务器的8081端口访问1号设备的web服务,8082端口访问2号设备web,这样可以在外部网络对内网设备进行参数配置、调整。类似地,通过2321访问1号设备的telnet服务,2322访问2号设备telnet,以方便登陆设备系统,进行设备状态监控,日志处理,等等。
本文将直接引用此网络拓扑图中的名称及IP地址。实际使用配置根据实际情况修改。另外说明一下,不必拘泥于本文给出的名称。像拓扑图中的“设备”,可以使用一台安装linux的服务器替换。其它的类似。

一、原理
在Linux系统使用iptables实现防火墙、数据转发等功能。iptables有不同的表(tables),每个tables有不同的链(chain),每条chain有一个或多个规则(rule)。本文利用NAT(network address translation,网络地址转换)表来实现数据包的转发。iptables命令要用-t来指定表,如果没有指明,则使用系统缺省的表“filter”。所以使用NAT的时候,就要用“-t nat”选项了。
NAT表有三条缺省的链,它们分别是PREROUTING、POSTROUTING和OUTPUT。
先给出NAT结构,如下图:
微信图片_20201103113310.png
  • PREROUTING:在数据包传入时,就进到PREROUTIING链。该链执行的是修改数据包内的目的IP地址,即DNAT(变更目的IP地址)。PREROUTING只能进行DNAT。因为进行了DNAT,才能在路由表中做判断,决定送到本地或其它网口。
  • POSTROUTING:相对的,在POSTROUTING链后,就传出数据包,该链是整个NAT结构的最末端。执行的是修改数据包的源IP地址,即SNAT。POSTROUTING只能进行SNAT。
  • OUTPUT:定义对本地产生的数据包的目的NAT规则。

每个数据包都会依次经过三个不同的机制,首先是PREROUTING(DNAT),再到路由表,最后到POSTROUTING(SNAT)。下面给出数据包流方向:
微信图片_20201103113313.png
文中的网络拓扑图所示的数据包,是从eth0入,eth1出。但是,无论从eth0到eth1,还是从eth1到eth0,均遵守上述的原理。就是说,SNAT和DNAT并没有规定只能在某一个网口(某一侧)。
顺便给出netfilter的完整结构图:
微信图片_20201103113317.png
二、实现
出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将包发往本机另一网卡,该网卡根据路由表继续发送数据包。这通常就是路由器所要实现的功能。
配置Linux系统的ip转发功能,首先保证硬件连通,然后打开系统的转发功能
cat /proc/sys/net/ipv4/ip_forward,该文件内容为0,表示禁止数据包转发,1表示允许,将其修改为1。可使用命令echo "1" > /proc/sys/net/ipv4/ip_forward 修改文件内容,重启网络服务或主机后效果不再。若要其自动执行,可将命令echo "1" > /proc/sys/net/ipv4/ip_forward 写入脚本/etc/rc.d/rc.local 或者在/etc/sysconfig/network脚本中添加 FORWARD_IPV4="YES"
但在我的系统中没有这两个文件,因此可以修改/etc/sysctl.conf文件,将net.ipv4.ip_forward=1的注释取消即可
根据拓扑图,一一实现不同IP、不同端口的映射,如下命令为一种示例形式:

  1. # 第一台设备的telnet服务
  2. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2321 -j DNAT --to 100.100.100.101:23
  3. iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.101 -p tcp --dport 23 -j SNAT --to 100.100.100.44
  4. # 第二台设备的telnet服务
  5. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2322 -j DNAT --to 100.100.100.102:23
  6. iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.102 -p tcp --dport 23 -j SNAT --to 100.100.100.44

  7. # 第一台设备的web服务
  8. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8081 -j DNAT --to 100.100.100.101:80
  9. iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.101 -p tcp --dport 80 -j SNAT --to 100.100.100.44
  10. # 第二台设备的web服务
  11. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8082 -j DNAT --to 100.100.100.102:80
  12. iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.102 -p tcp --dport 80 -j SNAT --to 100.100.100.44
复制代码

以第一台设备转发命令为例,用白话解释一下。
  • 第一条是PREROUTING链,只能进行DNAT,该命令对从eth0进入且目的IP为172.18.44.44(注:可以用-s指明数据包来源地址,但这时无法知道来源IP是多少,虽然可以用网段的做法,但用-d则指定必须一定唯一的是本机的eth0地址,相对好一点),端口号为2321的数据包进行目的地址更改,更改为100.100.100.101,端口为23,亦即此包的目的地为第一台设备的telnet服务。
  • 第二条是POSTROUTING链,只能进行SNAT,即对先前已经DNAT过的数据包修改源IP地址。这样,这个数据包达到第一台设备时,源IP地址、目的IP地址,均为100.100.100.0/24网段了。

上述命令的SNAT有些冗余,可以做简化,命令如下:

  1. # 第一台设备的telnet、web服务
  2. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2321 -j DNAT --to 100.100.100.101:23
  3. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8081 -j DNAT --to 100.100.100.101:80
  4. # 第二台设备的telnet、web服务
  5. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2322 -j DNAT --to 100.100.100.102:23
  6. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8082 -j DNAT --to 100.100.100.102:80
  7. # 源IP地址SNAT
  8. iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.0/24 -j SNAT --to 100.100.100.44
复制代码

实际中使用的命令可能还有变化(简化),本文不再展示。

三、测试
为了保证文中所述的正确性,本节列出操作结果,以及实验过程的信息。服务器(网关)上的路由表如下:

  1. root@latelee:test# route
  2. Kernel IP routing table
  3. Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
  4. 100.100.100.0   *               255.255.255.0   U     0      0        0 eth1
  5. 172.18.0.0      *               255.255.0.0     U     0      0        0 eth0
复制代码

可以看到服务器上有2个网卡,网段都不相同。iptables的NAT表如下:

  1. root@latelee:~# iptables -L -t nat
  2. Chain PREROUTING (policy ACCEPT)
  3. target     prot opt source               destination         
  4. DNAT       tcp  --  anywhere             172.18.44.44         tcp dpt:2324 to:100.100.100.101:23
  5. Chain INPUT (policy ACCEPT)
  6. target     prot opt source               destination         
  7. Chain OUTPUT (policy ACCEPT)
  8. target     prot opt source               destination         
  9. Chain POSTROUTING (policy ACCEPT)
  10. target     prot opt source               destination         
  11. SNAT       all  --  anywhere             100.100.100.0/24     to:100.100.100.44
复制代码

可以看到,PREROUTING和POSTROUTING各有一条规则,这些规则由上文命令所产生。对应的,在第一号设备上查看路由信息,如下:

  1. root@latelee:~# route
  2. Kernel IP routing table
  3. Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
  4. 100.100.100.0   *               255.255.255.0   U     0      0        0 eth0
  5. 172.18.0.0      *               255.255.0.0     U     0      0        0 eth1
  6. default         100.100.100.44 0.0.0.0         UG    0      0        0 eth0
复制代码

可以看到这台设备有2个网卡,默认网关为服务器的IP地址。但是,其中一个网卡eth1竟然和PC所在网段相同!如果没有进行源IP地址修改(伪装),会匹配到eth1这个网口,无法匹配eth0。

在外网的PC上对设备进行telnet,设备抓包信息如下:

  1. IP 100.100.100.44.32253 > 100.100.100.101.2323: Flags [P.], seq 1:4, ack 16, win 256, length 3
  2. IP 100.100.100.101.2323 > 100.100.100.44.32253: Flags [P.], seq 16:19, ack 4, win 2190, length 3
  3. IP 100.100.100.44.32253 > 100.100.100.101.2323: Flags [P.], seq 4:25, ack 19, win 256, length 21
  4. IP 100.100.100.101.2323 > 100.100.100.44.32253: Flags [P.], seq 19:34, ack 25, win 2190, length 15
复制代码

可见,所有包的IP段都相同。在服务器上对内网eth1进行抓包,由于进行了DNAT和SNAT,此网卡数据包IP地址还是100.100.100.0/24网段,如下:

  1. IP 100.100.100.44.32253 > 100.100.100.101.telnet: Flags [.], ack 1, win 256, length 0
  2. IP 100.100.100.101.telnet > 100.100.100.44.32253: Flags [P.], seq 1:16, ack 1, win 2190, length 15
  3. IP 100.100.100.44.32253 > 100.100.100.101.telnet: Flags [P.], seq 1:4, ack 16, win 256, length 3
  4. IP 100.100.100.101.telnet > 100.100.100.44.32253: Flags [P.], seq 16:19, ack 4, win 2190, length 3
复制代码

但是,在服务器eth0抓包,将会是172.18.0.0/16的网段数据包:

  1. IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [P.], seq 18:20, ack 154, win 255, length 2
  2. IP 172.18.44.44.2324 > 172.18.44.142.32253: Flags [P.], seq 154:156, ack 20, win 2190, length 2
  3. IP 172.18.44.44.2324 > 172.18.44.142.32253: Flags [F.], seq 156, ack 20, win 2190, length 0
  4. IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [.], ack 157, win 255, length 0
  5. IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [F.], seq 20, ack 157, win 255, length 0
  6. IP 172.18.44.44.2324 > 172.18.44.142.32253: Flags [.], ack 21, win 2190, length 0
复制代码
从抓包分析,本文所用命令已经能正确进行DNAT和SNAT了。

四、其它
建议在使用iptabls指令时,使用root用户进行操作,否则容易失败
保存iptables配置方法:

  • iptables-save > /etc/iptables.up.rules

配置iptables开机加载

  1. iptables-save > /etc/iptables.up.rules
  2. echo -e '#!/bin/bash\n/sbin/iptables-restore < /etc/iptables.up.rules' > /etc/network/if-pre-up.d/iptables
  3. chmod +x /etc/network/if-pre-up.d/iptables
复制代码

本地测试指令

  1. iptables -t nat -A PREROUTING -i wlan0 -d 192.168.11.100 -p tcp --dport 8081 -j DNAT --to 192.168.10.101:80
  2. iptables -t nat -A POSTROUTING -o eth0 -d 192.168.10.101 -p tcp --dport 80 -j SNAT --to 192.168.10.52
复制代码

收藏 评论0 发布时间:2020-11-3 12:02

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版