点击上方"程序员小乐"关注,星标或置顶一起成长
后台回复“大礼包”有惊喜礼包!
关注订阅号「程序员小乐」,收看更多精彩内容
每日英语
We'vestickedforalongtimebutfinallydefeatedbyeternity.
我们撑了很久,输给天长地久。
每日掏心话
生命是一场游戏,在这个世上,做你想做的梦,去你想去的地方,成为你想成为的人吧,由于你只有一次生命,一个机会去做所有这些你想做的事。
来自:ZONG_XP|责编:乐乐
链接:/N3Qz6j
程序员小乐(ID:study_tech)第1046次推文
往日回顾:厉害了!天猫手动刷喵币!靠这一个脚本就够了!
正文
0背景
考虑一种网路拓扑应用情境,一个内部局域网中有多台服务器提供不同的服务,如web服务、FTP服务、ssh、telnet等,通过服务器(或网段、防火墙)联接外部网路,假如外部网路上的主机须要访问那些服务器,则须要在网段上实现转发。
再转述成另一种应用场合,多台设备联接到一台服务器,服务器有2个网卡,分别联接内外网。内网难以直接访问设备上的数据、服务。在服务器上实现转发后,则可达到目的。
网路拓扑如下:
例如,可以通过服务器的8081端口访问1号设备的web服务,8082端口访问2号设备web,这样可以在外部网路对外网设备进行参数配置、调整。类似地linux 查看应用端口,通过2321访问1号设备的telnet服务,2322访问2号设备telnet,以便捷登录设备系统,进行设备状态监控,日志处理,等等。
本文将直接引用此网路拓扑图中的名称及IP地址。实际使用配置依据实际情况更改。另外说明一下,何必屈从于本文给出的名称。像拓扑图中的“设备”,可以使用一台安装linux的服务器替换。其它的类似。
一、原理
在Linux系统使用iptables实现防火墙、数据转发等功能。iptables有不同的表(tables)linux视频,每位tables有不同的链(chain),每条chain有一个或多个规则(rule)。本文借助NAT(networkaddresstranslation,网路地址转换)表来实现数据包的转发。iptables命令要用-t来指定表,假如没有指明,则使用系统缺省的表“filter”。所以使用NAT的时侯,就要用“-tnat”选项了。
在公众号程序员小乐后台回复“Java”,获取Java笔试题和答案。
NAT表有三条缺省的链,它们分别是PREROUTING、POSTROUTING和OUTPUT。
先给出NAT结构,如右图:
PREROUTING:在数据包传入时,就进到PREROUTIING链。该链执行的是更改数据包内的目的IP地址,即DNAT(变更目的IP地址)。PREROUTING只能进行DNAT。由于进行了DNAT,能够在路由表中做判定,决定送到本地或其它网口。
POSTROUTING:相对的,在POSTROUTING链后linux 查看应用端口,就传出数据包,该链是整个NAT结构的最末端。执行的是更改数据包的源IP地址,即SNAT。POSTROUTING只能进行SNAT。
OUTPUT:定义对本地形成的数据包的目的NAT规则。
每位数据包就会依次经过三个不同的机制,首先是PREROUTING(DNAT),再到路由表,最后到POSTROUTING(SNAT)。下边给出数据包流方向:
文中的网路拓扑图所示的数据包,是从eth0入,eth1出。而且,无论从eth0到eth1,还是从eth1到eth0,均遵循上述的原理。就是说,SNAT和DNAT并没有规定只能在某一个网口(某左侧)。
顺便给出netfilter的完整结布光:
二、实现
出于安全考虑,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、不同端口的映射,如下命令为一种示例方式:
# 第一台设备的telnet服务
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2321 -j DNAT --to 100.100.100.101:23
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.101 -p tcp --dport 23 -j SNAT --to 100.100.100.44
# 第二台设备的telnet服务
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2322 -j DNAT --to 100.100.100.102:23
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.102 -p tcp --dport 23 -j SNAT --to 100.100.100.44
# 第一台设备的web服务
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8081 -j DNAT --to 100.100.100.101:80
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.101 -p tcp --dport 80 -j SNAT --to 100.100.100.44
# 第二台设备的web服务
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8082 -j DNAT --to 100.100.100.102:80
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.102 -p tcp --dport 80 -j SNAT --to 100.100.100.44
以第一台设备转发命令为例,用白话解释一下。
上述命令的SNAT有些冗余,可以做简化,命令如下:
# 第一台设备的telnet、web服务
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2321 -j DNAT --to 100.100.100.101:23
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8081 -j DNAT --to 100.100.100.101:80
# 第二台设备的telnet、web服务
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2322 -j DNAT --to 100.100.100.102:23
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8082 -j DNAT --to 100.100.100.102:80
# 源IP地址SNAT
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.0/24 -j SNAT --to 100.100.100.44
实际中使用的命令可能还有变化(简化),本文不再展示。
三、测试
为了保证文中所述的正确性,本节列举操作结果,以及实验过程的信息。服务器(网段)上的路由表如下:
root@latelee:test# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
100.100.100.0 * 255.255.255.0 U 0 0 0 eth1
172.18.0.0 * 255.255.0.0 U 0 0 0 eth0
可以看见服务器上有2个网卡,网关都不相同。iptables的NAT表如下:
root@latelee:~# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere 172.18.44.44 tcp dpt:2324 to:100.100.100.101:23
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- anywhere 100.100.100.0/24 to:100.100.100.44
可以看见,PREROUTING和POSTROUTING各有一条规则,这种规则由上文命令所形成。对应的,在第一号设备上查看路由信息,如下:
在公众号程序员小乐后台回复“offer”,获取算法笔试题和答案。
~# route :
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
* 255.255.255.0 U 0 0 0 eth0
* 255.255.0.0 U 0 0 0 eth1
default 100.100.100.44 0.0.0.0 UG 0 0 0 eth0
可以看见这台设备有2个网卡,默认网段为服务器的IP地址。并且,其中一个网卡eth1居然和PC所在网关相同!假如没有进行源IP地址更改(伪装),会匹配到eth1这个网口,难以匹配eth0。
在内网的PC上对设备进行telnet,设备抓包信息如下:
IP 100.100.100.44.32253 > 100.100.100.101.2323: Flags [P.], seq 1:4, ack 16, win 256, length 3
IP 100.100.100.101.2323 > 100.100.100.44.32253: Flags [P.], seq 16:19, ack 4, win 2190, length 3
IP 100.100.100.44.32253 > 100.100.100.101.2323: Flags [P.], seq 4:25, ack 19, win 256, length 21
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网关,如下:
IP 100.100.100.44.32253 > 100.100.100.101.telnet: Flags [.], ack 1, win 256, length 0
IP 100.100.100.101.telnet > 100.100.100.44.32253: Flags [P.], seq 1:16, ack 1, win 2190, length 15
IP 100.100.100.44.32253 > 100.100.100.101.telnet: Flags [P.], seq 1:4, ack 16, win 256, length 3
IP 100.100.100.101.telnet > 100.100.100.44.32253: Flags [P.], seq 16:19, ack 4, win 2190, length 3
然而,在服务器eth0抓包linux命令行和shell脚本编程宝典,将会是172.18.0.0/16的网关数据包:
IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [P.], seq 18:20, ack 154, win 255, length 2
IP 172.18.44.44.2324 > 172.18.44.142.32253: Flags [P.], seq 154:156, ack 20, win 2190, length 2
IP 172.18.44.44.2324 > 172.18.44.142.32253: Flags [F.], seq 156, ack 20, win 2190, length 0
IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [.], ack 157, win 255, length 0
IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [F.], seq 20, ack 157, win 255, length 0
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开机加载
iptables-save > /etc/iptables.up.rules
echo -e '#!/bin/bashn/sbin/iptables-restore /etc/network/if-pre-up.d/iptables
chmod +x /etc/network/if-pre-up.d/iptables
本地测试指令
iptables -t nat -A PREROUTING -i wlan0 -d 192.168.11.100 -p tcp --dport 8081 -j DNAT --to 192.168.10.101:80
iptables -t nat -A POSTROUTING -o eth0 -d 192.168.10.101 -p tcp --dport 80 -j SNAT --to 192.168.10.52
欢迎在留言区留下你的观点,一起讨论提升。假如明天的文章让你有新的启发,欢迎转发分享给更多人。欢迎加入程序员小乐技术交流群,在后台回复“加群”或者“学习”即可。
猜你还想看
阿里、腾讯、百度、华为、京东最新笔试题汇集
Java中几种常用的RPC框架介绍
怎样实现MySQL删掉重复记录而且只保留一条
通宵慢性自尽全过程爆光
嘿,你在看吗?