前两天在工作中遇到一个需求,某192.168.1.0/24内网网段内只有一台主机A连接到了公网,A的两块网卡分别有一个公网地址(123.234.345.456)和一个内网地址(192.168.1.10),现需要内网的另一台主机B(192.168.1.77)连接到互联网下载某些东西,同时将B的某服务端口开放到公网上,两台主机的系统均为CentOS7。
主要参考了https://www.cnblogs.com/ssgeek/p/9220680.html 和 https://blog.csdn.net/light_jiang2016/article/details/79029661 两篇文章,事实证明并不需要改路由表等操作,简单几条命令即可完成我们的需求。
解决思路为使用iptables的转发功能,当然CentOS7自带了firewalld防火墙也有转发功能,但因为配置内网转接公网也需要通过iptables进行,这里就都使用iptables(CentOS7无需安装和启用iptables.service,我们只是用到了iptables命令)。
首先查看B主机的网卡
[root@~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 20:04:0f:f5:25:c0 brd ff:ff:ff:ff:ff:ff inet 192.168.1.77/24 brd 192.168.1.255 scope global noprefixroute em1 valid_lft forever preferred_lft forever inet6 fe80::2204:fff:fef5:25c0/64 scope link noprefixroute valid_lft forever preferred_lft forever
编辑网卡ens1的配置文件
[root@r740 redis]# vi /etc/sysconfig/network-scripts/ifcfg-ens1 TYPE=Ethernet PROXY_METHOD=none BOOTPROTO=static #也可以设置为dhcp,具体看路由器是否开启了dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes NAME=ens1 UUID=531a7963-406d-4e4d-b949-efe5d55d6cc DEVICE=ens1 ONBOOT=yes IPADDR=192.168.1.77 PREFIX=24 GATEWAY=192.168.1.10 #重点在这里,网关要设成主机A的内网地址 DNS1=114.114.114.114 ~ ~ ~
:wq保存修改,然后重启网络服务
systemctl restart network
systemctl restart NetworkManager #如果安装了图形界面,network会被NetworkManager代替
之后回到A主机,开启A的内核转发
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf && sysctl -p iptables -t nat -A POSTROUTING -s 192.168.1.77 -j MASQUERADE #进行ip伪装,对来源为192.168.1.77的主机数据报进行转发,如果改为192.168.1.0/24,则对整个内网网段的主机都进行转发
OK,现在在主机B ping一个公网网址,发现已经可以ping通了。
将以下代码保存成shell脚本,执行,即可开启对应端口的公网映射
#!/bin/bash pro='tcp' src_host='123.234.345.456' #主机A的公网地址 src_port=16379 #在主机A上要映射的端口 Dst_Host='192.168.1.77' #主机B的内网地址 Dst_Port=6379 #在主机B上要映射过去的端口 # 清空规则(如果自己以前定义过规则,比如上文的转发规则,则慎用!) #iptables -F #iptables -X #iptables -Z #iptables -t nat -F # Destination network address translate (dnat) iptables -t nat -A PREROUTING -p $pro -d $src_host --dport $src_port -j DNAT --to $Dst_Host:$Dst_Port iptables -A FORWARD -p $pro -d $Dst_Host --dport $Dst_Port -j ACCEPT # 本地连接不经过prerouting,只经过output链,所以想要在服务器A通过本地ip访问服务器B需要在output 链增加dnat规则 iptables -t nat -A OUTPUT -p $pro -d $src_host --dport $src_port -j DNAT --to $Dst_Host:$Dst_Port
在主机B运行redis服务后,扫描123.234.345.456的13679端口,发现已经是开启状态,端口转发成功。
如果希望持久化配置
iptables-save > /etc/sysconfig/iptables
将新加规则写入到配置文件中。