iptables之NAT
2016-10-23 22:49
92 查看
iptables之NAT==============================================================================
概述:
==============================================================================
⊙静态转换:外网地址是固定的;⊙动态转换:外网地址不固定;★定义方法:iptables -t nat A POSTROUTING -s 内网网络主机或地址 -j SNAT --to-source NAT服务器上的某外网地址
图解如下:
★PAT:Port Address Translati:端口映射(了解即可)
SNAT实验测试如下:
实验描述:
实验环境是基于上一篇网络防火墙的环境,这里不再过多赘述;
1.实验操作之前,内网主机是可以访问外网主机,也可以ping通,如下:
通过外网的日志查看和请求ping报文清楚的知道源地址是内网主机,内网主机没有做任何的转换
2.接下来我们要把内网地址转换成网关主机的外网地址,已达到伪装隐藏之源地址的目的。
1)定义规则源地址转换为网关主机的外网地址10.1.252.161,允许内网的所有主机访问外网的所有服务
为了验证是在哪个环节发生的地址转换,我们在网关主机的内网网卡和外网网卡分别抓包,如下:
2.[b]MASQUERADE:地址伪装[/b]★地址伪装,能自行判断该转换为哪个源地址This target is only valid in the nat table, in the POSTROUTING chain. It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.(这一目标只能在nat表的POSTROUTING链上定义。它适用于动态分配的地址,IP(拨号)连接,会自动去寻找可用的ip地址:如果你有一个静态IP地址,应该使用SNAT目标。)
3.[b]目标地址转换(DNAT)[/b]★目标地址转换(DNAT):PREROUTING⊙使用场景:主要用于发布内部服务器,让内网中的服务器在外网中可以被访问到,要定义在PREROUTING链;
★定义方法:iptables -t nat -A PREROUTING -d NAT服务器的某外网地址 -p 某协议 --dport 某端口 -j DNAT --to-destination 内网某服务器地址[:PORT]
★图解过程如下:
DNAT目标地址转换实验如下:
实验前环境准备:
1.因为DNAT为目标地址转换,即让内网中的服务器在外网中可以被访问到,所以,为了增加实验的说服力,我这里在内网的同一块网卡上再添加一个ip地址,让每一个ip地址对应一个服务,如下:
2.如上,地址已经添加成功,假设22地址对应的是web服务,23的地址对应的是ssh服务(这里可以想象成两个主机,但实际上是一个主机,为了演示效果);为了不影响实验效果这里我先把上例中定义的SNAT规则清空,如下:
1.假设内网地址192.168.22.2上提供了web服务,我们希望外网用户把对网关主机外网网卡请求的web服务的80端口全都转化到内网的192.168.22.2上,设置如下:
2.如上,我们只是把web服务转发到了一个内网服务上,是有选择性的。如果我们现在用外网去ping网关主机的外网地址,是不通的,要想通定义如下:
3.如果我们现在想把外网访问网关主机的外网地址的80端口(web服务)通过目标地址转换为内网地址的8080端口,那就需要做端口映射了(PAT)
上图为主配置文件中的,下图为定义的虚拟主机中监听地址的修改
如上定义好之后在内网主机上使用ss -tnl查看是否监听在8080端口,然后重启服务即可(因为是修改了监听地址,所以要重启,重载可能没用)
然后重新在网关主机上添加规则使网关主机的80端口映射为内网主机的8080端口即可,如下:
4.现在我们用外网去访问网关主机外网地址的ssh服务,可以顺利的远程登录到网关主机的外网地址,这里不做演示,那如果我在网关主机添加一条规则,使外网用户访问网关主机的外网地址的ssh服务时映射到内网主机上(即ssh远程登录内网主机)能否实现呢?
1)首先,在网关主机添加一条规则,指明要映射的ip(因为有两个ip所以映射到另一个主机上)和端口,如下:
这是什么原因,难道登录不了么,查看信息猜测是外网主机之前远程登录网关主机的外网地址信息全都记录在/root/.ssh/know_hosts 的文件中,因为端口转换所以与之前那记录的信息不匹配,所以报错,这里我把/root/.ssh/know_hosts文件中的记录信息清空,然后在次登录,果然可以顺利登录到内网主机上了,如下:
可是这样就有了一个问题,那就是网关主机外网的22号端口被内网给占用了,如果远程登录的话直接登录的就为内网主机,这样对内网服务器很不安全;为了安全起见,我们在网关主机上重新定义一个端口(22022)映射到内网主机,如下:
4.[b]REDIRECT:重定向[/b]★定义:This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. 仅在当前主机上完成端口映射★用法:--to-ports port[-port]
使用REDIRECT仅可完成本机端口的映射转换,实验如下:
内网主机上现在httpd的端口为8080,添加规则如下:
在网关主机上测试如下:
如此一来,在前端网关主机上添加的目标地址转化的端口映射80到8080端口的规则,就可以把8080端口去掉,这样还是网关主机的80端口到内网主机的80端口,如下:
注意:在应用当中,我们可以综合nat表和filter表来完成控制访问,比如,我们可以通过定义nat表来完成地址转换,通过filter表来完成过滤功能。因为nat表仅负责完成地址转换,转换完成之后,这个报文到底能不能出去就要靠filter表的定义了。
还有一种场景,假如我们发布的内部服务器是一个web服务,允许外网用户通过DNAT来访问我们的内网web服务器,但是有一个外网用户经常对我们的主机发起攻击的操作,我们要拒绝这个外网用户的访问,可以有两种方法来控制其访问,一种是在内网主机上添加防火墙起到控制作用,另一种也可以在网关主机添加防火墙规则控制其访问。
5.RETURE★功能:从调用的链上返回到原来的链上
6.自定义链
自定义连只有在被调用时才会生效
概述:
==============================================================================
NAT:SNAT和DNAT
1.[b]源地址转换(SNAT)[/b]★源地址转换(SNAT):POSTROUTING⊙使用场景:主要用于实现让内网客户端访问外部主机地址时使用,要定义在POSTROUTING链或INPUT链;⊙静态转换:外网地址是固定的;⊙动态转换:外网地址不固定;★定义方法:iptables -t nat A POSTROUTING -s 内网网络主机或地址 -j SNAT --to-source NAT服务器上的某外网地址
图解如下:
★PAT:Port Address Translati:端口映射(了解即可)
SNAT实验测试如下:
实验描述:
实验环境是基于上一篇网络防火墙的环境,这里不再过多赘述;
1.实验操作之前,内网主机是可以访问外网主机,也可以ping通,如下:
通过外网的日志查看和请求ping报文清楚的知道源地址是内网主机,内网主机没有做任何的转换
2.接下来我们要把内网地址转换成网关主机的外网地址,已达到伪装隐藏之源地址的目的。
1)定义规则源地址转换为网关主机的外网地址10.1.252.161,允许内网的所有主机访问外网的所有服务
# 定义规则前查看 [root@centos7 ~]# iptables -vnL Chain INPUT (policy ACCEPT 16 packets, 1130 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 12 packets, 1008 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 6 packets, 1160 bytes) pkts bytes target prot opt in out source destination # 定义规则,指明源内网地址,因为访问的是外网的所有服务所以地址和端口不用指定,指明源地址转化为网关 主机的外网地址 [root@centos7 ~]# iptables -t nat -A POSTROUTING -s 192.168.22.0/24 -j SNAT --to-source 10.1.252.161 # 指明nat表查看定义的规则 [root@centos7 ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 59 packets, 6309 bytes) pkts bytes target prot opt in out source destination Chain INPUT (policy ACCEPT 21 packets, 3188 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 1 packets, 156 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 1 packets, 156 bytes) pkts bytes target prot opt in out source destination 1 84 SNAT all -- * * 192.168.22.0/24 0.0.0.0/0 to:10.1.252.161接下来,内网主机再次访问外网的web服务和ping操作,外网抓包和访问日志已经伪装成网关主机的外网地址,如下:
为了验证是在哪个环节发生的地址转换,我们在网关主机的内网网卡和外网网卡分别抓包,如下:
2.[b]MASQUERADE:地址伪装[/b]★地址伪装,能自行判断该转换为哪个源地址This target is only valid in the nat table, in the POSTROUTING chain. It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.(这一目标只能在nat表的POSTROUTING链上定义。它适用于动态分配的地址,IP(拨号)连接,会自动去寻找可用的ip地址:如果你有一个静态IP地址,应该使用SNAT目标。)
3.[b]目标地址转换(DNAT)[/b]★目标地址转换(DNAT):PREROUTING⊙使用场景:主要用于发布内部服务器,让内网中的服务器在外网中可以被访问到,要定义在PREROUTING链;
★定义方法:iptables -t nat -A PREROUTING -d NAT服务器的某外网地址 -p 某协议 --dport 某端口 -j DNAT --to-destination 内网某服务器地址[:PORT]
★图解过程如下:
DNAT目标地址转换实验如下:
实验前环境准备:
1.因为DNAT为目标地址转换,即让内网中的服务器在外网中可以被访问到,所以,为了增加实验的说服力,我这里在内网的同一块网卡上再添加一个ip地址,让每一个ip地址对应一个服务,如下:
2.如上,地址已经添加成功,假设22地址对应的是web服务,23的地址对应的是ssh服务(这里可以想象成两个主机,但实际上是一个主机,为了演示效果);为了不影响实验效果这里我先把上例中定义的SNAT规则清空,如下:
[root@centos7 ~]# iptables -t nat -F [root@centos7 ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination实验如下:
1.假设内网地址192.168.22.2上提供了web服务,我们希望外网用户把对网关主机外网网卡请求的web服务的80端口全都转化到内网的192.168.22.2上,设置如下:
分析:这里一定是在nat表的PREROUTING链上定义,指明目标IP为网关主机的外网地址10.1.252.161 ,指明协议为tcp协议(如果不指明的话所有的服务会统统转到一台内网主机之上),指明目标端口 为网关主机外网地址的80端口(实际上根本没有,因为网关主机跟本就没有提供服务),指明转换的 目标地址为提供服务的内网主机地址192.168.22.2,这里没指明端口,默认就是网关主机的端口80,也 可以不相同,也就是端口映射; [root@centos7 ~]# iptables -t nat -A PREROUTING -d 10.1.252.161 -p tcp --dport 80 -j DNAT --to-destination 192.168.22.2 [root@centos7 ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 3 packets, 675 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- * * 0.0.0.0/0 10.1.252.161 tcp dpt:80 to:192.168.22.2 Chain INPUT (policy ACCEPT 3 packets, 675 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination查看网关主机确认是没有开通web服务的80端口
[root@centos7 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 25 *:514 *:* LISTEN 0 128 *:22 *:* LISTEN 0 128 127.0.0.1:631 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 127.0.0.1:6010 *:* LISTEN 0 25 :::514 :::* LISTEN 0 128 :::22 :::* LISTEN 0 128 ::1:631 :::* LISTEN 0 100 ::1:25 :::* LISTEN 0 128 ::1:6010 :::*使用外网主机请求网关主机的web服务,如下:
2.如上,我们只是把web服务转发到了一个内网服务上,是有选择性的。如果我们现在用外网去ping网关主机的外网地址,是不通的,要想通定义如下:
[root@centos7 ~]# iptables -t nat -F # 清空服务 把上例中指定的协议和端口去掉即可,即外网用户的所有任意服务访问,全都转到内网主机为192.168.22.2的主机 [root@centos7 ~]# iptables -t nat -A PREROUTING -d 10.1.252.161 -j DNAT --to-destination 192.168.22.2 [root@centos7 ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT all -- * * 0.0.0.0/0 10.1.252.161 to:192.168.22.2 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination外网主机去ping网关主机的10.1.252.161,在内网主机上抓包如下:
3.如果我们现在想把外网访问网关主机的外网地址的80端口(web服务)通过目标地址转换为内网地址的8080端口,那就需要做端口映射了(PAT)
# 首先修改内网服务器httpd服务的配置文件修改监听端口(LISTEN)为8080,重启httpd服务即可,我这 # 里的httpd服务是建立的一个虚拟主机,所以要同时修改主配置文件/etc/httpd/conf/httpd.conf中的 # Listen 80修改为 Listen 8080,以及虚拟主机的配置文件的监听端口80改为8080,如下:
上图为主配置文件中的,下图为定义的虚拟主机中监听地址的修改
如上定义好之后在内网主机上使用ss -tnl查看是否监听在8080端口,然后重启服务即可(因为是修改了监听地址,所以要重启,重载可能没用)
然后重新在网关主机上添加规则使网关主机的80端口映射为内网主机的8080端口即可,如下:
[root@centos7 ~]# iptables -t nat -F [root@centos7 ~]# iptables -t nat -A PREROUTING -d 10.1.252.161 -p tcp --dport 80 -j DNAT --to-destination 192.168.22.2:8080 [root@centos7 ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 10 packets, 931 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- * * 0.0.0.0/0 10.1.252.161 tcp dpt:80 to:192.168.22.2:8080 Chain INPUT (policy ACCEPT 1 packets, 229 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination测试外网主机访问内网主机的web服务如下:
4.现在我们用外网去访问网关主机外网地址的ssh服务,可以顺利的远程登录到网关主机的外网地址,这里不做演示,那如果我在网关主机添加一条规则,使外网用户访问网关主机的外网地址的ssh服务时映射到内网主机上(即ssh远程登录内网主机)能否实现呢?
1)首先,在网关主机添加一条规则,指明要映射的ip(因为有两个ip所以映射到另一个主机上)和端口,如下:
[root@centos7 ~]# iptables -t nat -A PREROUTING -d 10.1.252.161 -p tcp --dport 22 -j DNAT --to-destination 192.168.22.3:22 [root@centos7 ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 133 packets, 14198 bytes) pkts bytes target prot opt in out source destination 1 60 DNAT tcp -- * * 0.0.0.0/0 10.1.252.161 tcp dpt:80 to:192.168.22.2:8080 1 60 DNAT tcp -- * * 0.0.0.0/0 10.1.252.161 tcp dpt:22 to:192.168.22.3:22 Chain INPUT (policy ACCEPT 35 packets, 5937 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 2 packets, 120 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 6 packets, 360 bytes) pkts bytes target prot opt in out source destination现在测试,使用外网用户远程登录网关主机的外网地址如下:
这是什么原因,难道登录不了么,查看信息猜测是外网主机之前远程登录网关主机的外网地址信息全都记录在/root/.ssh/know_hosts 的文件中,因为端口转换所以与之前那记录的信息不匹配,所以报错,这里我把/root/.ssh/know_hosts文件中的记录信息清空,然后在次登录,果然可以顺利登录到内网主机上了,如下:
可是这样就有了一个问题,那就是网关主机外网的22号端口被内网给占用了,如果远程登录的话直接登录的就为内网主机,这样对内网服务器很不安全;为了安全起见,我们在网关主机上重新定义一个端口(22022)映射到内网主机,如下:
# 修改第二条规则,使网关主机的端口为22022 [root@centos7 ~]# iptables -t nat -R PREROUTING 2 -d 10.1.252.161 -p tcp --dport 22022 -j DNAT --to-destination 192.168.22.3:22 [root@centos7 ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1 60 DNAT tcp -- * * 0.0.0.0/0 10.1.252.161 tcp dpt:80 to:192.168.22.2:8080 0 0 DNAT tcp -- * * 0.0.0.0/0 10.1.252.161 tcp dpt:22022 to:192.168.22.3:22 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination测试访问如下:
4.[b]REDIRECT:重定向[/b]★定义:This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. 仅在当前主机上完成端口映射★用法:--to-ports port[-port]
使用REDIRECT仅可完成本机端口的映射转换,实验如下:
内网主机上现在httpd的端口为8080,添加规则如下:
在网关主机上测试如下:
如此一来,在前端网关主机上添加的目标地址转化的端口映射80到8080端口的规则,就可以把8080端口去掉,这样还是网关主机的80端口到内网主机的80端口,如下:
[root@centos7 ~]# iptables -t nat -R PREROUTING 1 -d 10.1.252.161 -p tcp --dport 80 -j DNAT --to-destination 192.168.22.2 [root@centos7 ~]# iptables -t nat -vnL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- * * 0.0.0.0/0 10.1.252.161 tcp dpt:80 to:192.168.22.2 1 60 DNAT tcp -- * * 0.0.0.0/0 10.1.252.161 tcp dpt:22022 to:192.168.22.3:22 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination用外网主机访问网关主机的外网地址还是可以转换为内网地址的8088端口
[root@CentOS6 ~]# curl http://10.1.252.161/test.html 192.168.22.2
注意:在应用当中,我们可以综合nat表和filter表来完成控制访问,比如,我们可以通过定义nat表来完成地址转换,通过filter表来完成过滤功能。因为nat表仅负责完成地址转换,转换完成之后,这个报文到底能不能出去就要靠filter表的定义了。
还有一种场景,假如我们发布的内部服务器是一个web服务,允许外网用户通过DNAT来访问我们的内网web服务器,但是有一个外网用户经常对我们的主机发起攻击的操作,我们要拒绝这个外网用户的访问,可以有两种方法来控制其访问,一种是在内网主机上添加防火墙起到控制作用,另一种也可以在网关主机添加防火墙规则控制其访问。
5.RETURE★功能:从调用的链上返回到原来的链上
6.自定义链
自定义连只有在被调用时才会生效
相关文章推荐
- iptables之NAT基础
- 【Linux 驱动】Netfilter/iptables (八) Netfilter的NAT机制
- 配置iptables NAT端口转发 实现内网服务器端口提供公网接入
- 防火墙、Iptables、netfilter/iptables、NAT 概述
- iptables nat 测试
- iptables 详解(NAT)
- 如何用iptables实现NAT
- iptables常用规则:屏蔽IP地址、禁用ping、协议设置、NAT与转发、负载平衡、自定义链
- IPtables之四:NAT原理和配置
- linux-iptables nat设置路由转换
- iptables 做NAT代理上网
- iptables的nat的简单设置
- iptables的NAT设置
- Linux下iptables的工作机制图解以及在NAT的应用
- 一个可以直接使用的可用iptables配置的stateless NAT实现
- iptables 的NAT使用实验
- iptables的NAT功能设置和linux升级内核后遇到 can't initialize iptables table `nat': Table does not exist 问题
- iptables 实现nat转发
- Docker NAT iptables实现 及网络配置 (网络二)