一、项目背景描述
实际运维工作中,很多机器是不带公网的,一般一个集群或一个平台只有前端能访问互联网,划属于DMZ区域,而内网机器一些因安全所进行的升级,如果采用手动离线升级的话,效率低,而且比如内核升级的话,因个人能力或系统未知原因,还会出现意外的问题。那我们如何借助于DMZ去的linux主机,让其具备路由转发功能(路由),从而实现内网机器外访互联网呢?
二、实现方法
我们知道,Linux本身自带iptables包过滤,但是其还有一重要功能,即实现数据的转发,本文就利用Linux 自带 iptables 实现从一个网络接口到另一个接口的IP转发(数据包转发)。IP转发的概念是,使 Linux 机器像路由器一样将数据从一个网络发送到另一个网络。所以,它能作为一个路由器或者代理服务器,实现将一个连接的互联网或者网络连接共享给多个客户端机器。
● 示例及原理解释(来源网络):
| 源IP | 源端口 | NAT | 网关机器IP | NAT 网关 | 机器端口 | 目标IP | 目标端口 |
|---|---|---|---|---|---|---|---|
| 192.168.10.14 | 8080 | 192.168.10.15 | 18080 | 106.11.45.35 | 80 |
转发过程如下:
- 192.168.10.14:8080 [request dysmsapi.aliyuncs.com] --> 192.168.10.15:18080
- 192.168.128.145:18080 [request dysmsapi.aliyuncs.com] --> dysmsapi.aliyuncs.com (106.11.211.236:80)
- dysmsapi.aliyuncs.com [response] --> 192.168.10.14:18080
- 查找映射表得知,18080获得的数据返还给 192.168.10.14:8080
- dysmsapi.aliyuncs.com [response] --> 192.168.10.14:8080
2.1、启用 IPv4 转发
带外主机上配置,使用root或sudo执行:
cat/proc/sys/net/ipv4/ip_forwardsysctl-a|grep'net.ipv4.ip_forward'//查看是否已经打开,如值为1,则已经打开echo1>/proc/sys/net/ipv4/ip_forward //开启ipv4转发,或修改配置文件/etc/sysctl.confvim/etc/sysctl.conf //修改参数为1 net.ipv4.ip_forward=1#立即生效sysctl-p注:执行命令后可马上启用ip转发,但仅对本次登录有效;要想永久生效需要修改配置文件/etc/sysctl.conf ,增加/修改 net.ipv4.ip_forward = 1。
修改后执行:#sysctl -p /etc/sysctl.conf##启用更改,使其立即生效。
2.2、内网主机配置静态路由转发到公网
本次项目中使用eth0网口的网关配置静态路由转发到公网,来实现连接外网,编辑配置文件:
vi/etc/sysconfig/static-routes格式如下:any net 172.16.152.0/24 gw 10.102.3.254 ;其中:
net 172.16.152.0/24 ----->目标网段,即你需要访问的公网网段
gw 10.102.3.254 -------->本地nat代理的网关(前提是开启了本地ipv4转发)
修改配置后需要重启网卡或主机,才能生效;
2.3、带外主机配置,如你本地有1块上网的网卡:
配置iptables,且由于netfilter/iptables是一个无状态(区别与安全组:无状态是双向放行,自动生成反向安全规则,存在更高的安全风险;有状态:单向放行,并动态放通回程流量)的防火墙(实际依赖的netfilter是内核的一个框架,这种无状态是指内核,它有五个钩子函数(hook)),我们需要让 iptables 允许已建立的连接通过。但iptables可通过依赖ip_conntrack机制实现有状态的防火墙功能。这意味着iptables能够跟踪连接的状态(如NEW、ESTABLISHED、RELATED、INVALID);
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p iptables -A FORWARD -i 内网口 -o 外网口 -j ACCEPT iptables -A FORWARD -i 外网口 -o 内网口 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -t nat -A POSTROUTING -s 192.168.10.14 -j SNAT --to 192.168.10.15 #或直接如下配置 iptables -t nat -A POSTROUTING -o 外网口 -j MASQUERADE iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables-save /etc/iptables.up.rules #对于内网主机,可以外连内走windows,内访问走同网络域的带外Linux,尤其是同网段的,乳沟不指定带外主机转发,会出现同网段redirect重定向 #比如 192.168.10.2通过 192.168.10.4(带外)访问公网 #让 10.2 的流量通过 10.4 出去(自动使用 EIP) iptables -t nat -A POSTROUTING -s 192.168.10.2 -j MASQUERADE #实际只加一条即可 iptables -t nat -A PREROUTING -d 192.168.10.4 -j DNAT --to-destination 192.168.10.2 iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE #相比上面,10.4 本机也会被 MASQUERADE,导致本机发出的包源地址也被替换,云主机日志、监控、API 调用等可能因源地址变化而出问题 iptables -t nat -A POSTROUTING -s 192.168.10.0/24 ! -d 192.168.10.4 -j MASQUERADE #上面这样无法排除源地址为本机的情况 #或加一条规则让本机流量跳过 MASQUERADE iptables -t nat -A POSTROUTING -s 192.168.10.4 -j RETURN #跳过 MASQUERADE iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE #或,MASQUERADE性能略差(需要动态获取接口IP) iptables -t nat -A POSTROUTING -s 192.168.10.2 -j SNAT --to-source 192.168.10.4 # DNAT:访问 EIP 的流量 → 转发给 10.2 iptables -t nat -A PREROUTING -d 10.4的内网IP -j DNAT --to-destination 192.168.10.2 #带外主机上观察NAT 统计 iptables -t nat -L POSTROUTING -n -v另外,如果是云主机的需要关闭如下功能:
2.4、其他
iptables-tnat-nLiptables-nL--line-numbers-tnat iptables-tnat-DPOSTROUTING1iptables-PINPUT ACCEPT iptables-IFORWARD-s172.16.18.0/24-jACCEPT#检查路由器容器上的连接跟踪信息apt-getinstallconntrack#或yum install conntrack-toolsconntrack-L#为了实时输出信息,我们用 watch 命令来定期执行上面命令watch-n1conntrack-L#清空记录conntrack-D#iptables -m conntrack --ctstate NEW,ESTABLISHED,RELATED #-m state --statetcpdump-ieth0|grep"106.11.211.236"#示例1:A → B → 公网服务器 A发起SYN(Flags [S]),经B转发;2)公网服务器 → B 服务器返回SYN-ACK(Flags [S.])到B;3)公网服务器 → A#问题点:服务器尝试直接回复SYN-ACK到A(未通过B中转)---网卡未关闭源检查;默认网卡思华开启虚拟网卡的源目的地址检查的,系统会检查服务器发送的报文中源IP地址是否正确。源地址不正确或者属于不信任的地址范围,该数据包会被阻止。当服务器作网关、转发功能的时候,需要关闭源目的地址检查。IP A.60761>183.204.68.114.http: Flags[S],seq2684448681, win5840, options[mss1460,sackOK,TS val2517892865ecr0,nop,wscale2], length021:13:24.558737 IP B.60761>183.204.68.114.http: Flags[S],seq2684448681, win5840, options[mss1460,sackOK,TS val2517892865ecr0,nop,wscale2], length021:13:24.570849 IP183.204.68.114.http>B.60761: Flags[S.],seq3671354794, ack2684448682, win42340, options[mss1460,nop,nop,sackOK,nop,wscale9], length021:13:24.570878 IP