Like
Like Love Haha Wow Sad Angry

文章内容为学习整理笔记,绝大部分来源于 倪朋飞 老师的 Linux性能优化实战

一、NAT原理

  NAT 技术可以重写数据包的源 IP 或者目的 IP,被普遍地用来解决公网 IP 地址短缺的问题。它的主要原理就是,网络中的多台主机,通过共享同一个公网 IP 地址,来访问外网资源。同时,由于 NAT 屏蔽了内网网络,自然也就为局域网中的机器提供了安全隔离。
  你既可以在支持网络地址转换的路由器(称为 NAT 网关)中配置 NAT,也可以在 Linux 服务器中配置 NAT。如果采用第二种方式,Linux 服务器实际上充当的是“软”路由器的角色。
  NAT 的主要目的,是实现地址转换。根据实现方式的不同,NAT 可以分为三类:

• 静态 NAT,即内网 IP 与公网 IP 是一对一的永久映射关系。
• 动态 NAT,即内网 IP 从公网 IP 池中,动态选择一个进行映射。
• 网络地址端口转换 NAPT(Network Address and Port Translation),即把内网 IP 映射到公网 IP 的不同端口上,让多个内网 IP 可以共享同一个公网 IP 地址。

  NAPT 是目前最流行的 NAT 类型,我们在 Linux 中配置的 NAT 也是这种类型。而根据转换方式的不同,我们又可以把 NAPT 分为三类:
  第一类是源地址转换 SNAT,即目的地址不变,只替换源 IP 或源端口。SNAT 主要用于,多个内网 IP 共享同一个公网 IP ,来访问外网资源的场景。
  第二类是目的地址转换 DNAT,即源 IP 保持不变,只替换目的 IP 或者目的端口。DNAT 主要通过公网 IP 的不同端口号,来访问内网的多种服务,同时会隐藏后端服务器的真实 IP 地址。
  第三类是双向地址转换,即同时使用 SNAT 和 DNAT。当接收到网络包时,执行 DNAT,把目的 IP 转换为内网 IP;而在发送网络包时,执行 SNAT,把源 IP 替换为外部 IP。双向地址转换,其实就是外网 IP 与内网 IP 的一对一映射关系,所以常用在虚拟化环境中,为虚拟机分配浮动的公网 IP 地址。

二、iptables 和 NAT

  Linux 内核提供的 Netfilter 框架,允许对网络数据包进行修改(比如 NAT)和过滤(比如防火墙)。在这个基础上,iptables、ip6tables、ebtables 等工具,又提供了更易用的命令行接口,以便系统管理员配置和管理 NAT、防火墙的规则。其中,iptables 就是最常用的一种配置工具。
  下面,我们来看下如何在Linux服务器上配置NAT。
  要实现 NAT 功能,主要是在 nat 表进行操作。而 nat 表内置了三个链:

• PREROUTING,用于路由判断前所执行的规则,比如,对接收到的数据包进行 DNAT。
• POSTROUTING,用于路由判断后所执行的规则,比如,对发送或转发的数据包进行 SNAT 或 MASQUERADE。
• OUTPUT,类似于 PREROUTING,但只处理从本机发送出去的包。

在使用 iptables 配置 NAT 规则时,Linux 需要转发来自其他 IP 的网络包,需要开启 Linux 的 IP 转发功能。

# 查看是否打开转发功能。1表示开启,0表示关闭的
root@cp1:~# sysctl net.ipv4.ip_forward      
net.ipv4.ip_forward = 1

# 临时有效
root@cp1:~# sysctl -w net.ipv4.ip_forward=1     
net.ipv4.ip_forward = 1

# 永久生效
root@cp1:~# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
root@cp1:~# sysctl -p

1、SNAT

  SNAT 需要在 nat 表的 POSTROUTING 链中配置。我们常用两种方式来配置它:
  第一种方法,是为一个子网统一配置 SNAT,并由 Linux 选择默认的出口 IP,这实际上就是经常说的 MASQUERADE(地址伪装,可以实现自动化的SNAT):

iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j MASQUERADE

第二种方法,是为具体的 IP 地址配置 SNAT,并指定转换后的源地址:

iptables -t nat -A POSTROUTING -s 192.168.0.2 -j SNAT --to-source 100.100.100.100

2、DNAT

  DNAT 需要在 nat 表的 PREROUTING 或者 OUTPUT 链中配置,其中, PREROUTING 链更常用一些(因为它还可以用于转发的包)。

iptables -t nat -A PREROUTING -d 100.100.100.100 -j DNAT --to-destination 192.168.0.2

3、双向地址转换

双向地址转换,就是同时添加 SNAT 和 DNAT 规则,为公网 IP 和内网 IP 实现一对一的映射关系,即:

iptables -t nat -A POSTROUTING -s 192.168.0.2 -j SNAT --to-source 100.100.100.100
iptables -t nat -A PREROUTING -d 100.100.100.100 -j DNAT --to-destination 192.168.0.2

三、示例

1、端口转发

# 将本机5555的端口的流量转发到本机的22上
[root@web1 ~]# iptables -t nat -A PREROUTING -d 10.0.0.7 -p tcp --dport 5555 -j DNAT --to-destination 10.0.0.7:22
[root@web1 ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  0.0.0.0/0            10.0.0.7             tcp dpt:5555 to:10.0.0.7:22
......

# 将10.0.0.8:5555的流量转发到10.0.0.7:22上
[root@m1 ~]# iptables -t nat -A PREROUTING -d 10.0.0.8 -p tcp --dport 5555 -j DNAT --to-destination 10.0.0.7:22
[root@m1 ~]# iptables -t nat -A POSTROUTING -d 10.0.0.7 -p tcp -j SNAT --to-source 10.0.0.8
[root@m1 ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  0.0.0.0/0            10.0.0.8            tcp dpt:5555 to:10.0.0.7:22
......
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       tcp  --  0.0.0.0/0            10.0.0.7             to:10.0.0.8

2、内部共享上网

环境:
    web01处于内网环境,没有公网ip,其内网ip地址为172.16.1.7
    web02有两块网卡,一块地址为内网172.16.1.8,一块地址为公网10.0.0.8

此时web01通过将网关指向10.0.0.8共享上网,iptables规则设置如下:

[root@web2 ~]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf   //开启内核转发参数
[root@web2 ~]# sysctl -p
[root@web2 ~]# iptables -t nat -A POSTROUTING -s 172.16.1.7 -j SNAT --to-source 172.16.1.8
[root@web2 ~]# iptables -t nat -nL
......
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  172.16.1.7           0.0.0.0/0            to:172.16.1.8

或者:
[root@web2 ~]# iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j MASQUERADE
[root@web2 ~]# iptables -t nat -nL 
......
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.16.1.0/24        0.0.0.0/0  

Like
Like Love Haha Wow Sad Angry

发表评论