前两天在工作中遇到一个需求,某192.168.1.0/24内网网段内只有一台主机A连接到了公网,A的两块网卡分别有一个公网地址(123.234.345.456)和一个内网地址(192.168.1.10),现需要内网的另一台主机B(192.168.1.77)连接到互联网下载某些东西,同时将B的某服务端口开放到公网上,两台主机的系统均为CentOS7。
主要参考了 和 两篇文章,事实证明并不需要改路由表等操作,简单几条命令即可完成我们的需求。
解决思路为使用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
将新加规则写入到配置文件中。