【Linux安全系列教程】iptables防火墙
【Linux安全系列教程】iptables防火墙
下一期教程:Firewalld防火墙
一、防火墙的类型
- 硬件防火墙
- 软件防火墙
netfilter
内核模块Centos7.x
firewall-cmd命令
firewalld服务
iptables
命令
二、防火墙的作用
- 数据过滤
- 根据数据基本五元素
源IP
、目的IP
、协议
、源端口
、目的端口
- 根据数据基本五元素
三、关于四表五链
1.filler表中的链
INPUT
、FORWARD
、OUTPUT
2.NAT表中的链
PREROUTING
、INPUT
、OUTPUT
、POSTROUTING
3.mangle表中的链
PREROUTING
、INPUT
、FORWARD
、OUTPUT
、POSTROUTING
4.raw表中的链
PREROUTING
、OUTPUT
编写规则注意事项
- 自上而下,依次匹配
- 允许在要拒绝上面
- 访问频率高的服务规则尽量放在上面
- 链的默认行为
四、数据过滤规则管理(filter表)
1.关闭防火墙
Centos7
有2
个防火墙,一个现在的iptables
,还有一个是基于firewalld
服务的firewall
防火墙
[root@node4 ~]# systemctl stop firewalld
[root@node4 ~]# systemctl disable firewalld
[root@node4 ~]# systemctl mask firewalld
2.查看防火墙规则
A.查看规则
-L
列出规则-n
以阿拉伯数字显示
[root@node4 ~]# iptables -nL
Chain INPUT (policy ACCEPT) #防火墙默认规则,允许所有通过
target prot opt source destination
#默认是没有规则的
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
-t<表名>
查看指定表规则
如果不加
-t
参数,默认查看的是filter表
[root@node4 ~]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
--line-number
显示行号
[root@node4 ~]# iptables -nL -t filter -v --line-number
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 4247 374K ACCEPT tcp -- * * 192.168.140.1 192.168.140.14 tcp dpt:22
2 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 4028 packets, 647K bytes)
num pkts bytes target prot opt in out source destination
-v
查看详细信息
[root@node4 ~]# iptables -nL -t nat -v
Chain PREROUTING (policy ACCEPT 56 packets, 3092 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 8 packets, 424 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 216 packets, 16757 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 216 packets, 16757 bytes)
pkts bytes target prot opt in out source destination
3.删除规则
A.删除单条规则
命令格式
# iptables -D 链名 行号
查看所有规则
我这里加了
2
条测试规则
可以添加--line-number
参数,显示行号
[root@node4 ~]# iptables -nL -t filter -v --line-number
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 4247 374K ACCEPT tcp -- * * 192.168.140.1 192.168.140.14 tcp dpt:22
2 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 4028 packets, 647K bytes)
num pkts bytes target prot opt in out source destination
例:我想删除第2条数据
如果不添加
-t
参数,默认删除filter
表中的规则
[root@node4 ~]# iptables -t filter -D INPUT 2
[root@node4 ~]# iptables -D INPUT 2 #这是另外一种写法
查看规则
[root@node4 ~]# iptables -nL -t filter -v --line-number
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 7339 647K ACCEPT tcp -- * * 192.168.140.1 192.168.140.14 tcp dpt:22
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 72 packets, 12372 bytes)
num pkts bytes target prot opt in out source destination
B.删除所有规则
[root@node4 ~]# iptables -F
查看规则
[root@node4 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
#表中没有规则了
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
4.添加规则
A.命令格式
如果不写
-t
参数==指定表名==,默认添加到filter
表中
# iptables -t <表名> {-A|-I} <链名> [匹配数据的条件] -j <行为>
iptables
规则查询有默认的策略
从写的第一条
匹配规则开始,一直向后
匹配。
如果从第一条
开始就匹配到了
相应的规则,那么后面
的规则都不会继续
匹配,而是直接应用第一条
规则,所以合理
的规则是必要的!
-A
新的规则连续向后插入,也就是会插入到已有规则的后面-I
新的规则永远插入到第一个,当然-I
参数也可以指定你想插入到哪一行
行为
ACCEPT
允许DROP
拒绝REJECT
拒绝
匹配数据条件的常用选项
-s
源IP
地址-s 192.168.1.1
单独的IP
-s 192.168.1.0/24
网段! -s 192.168.2.1
取反
-d
目的IP
地址-d 10.1.1.1
-d 10.1.1.0/24
! -d 10.1.1.1
-i
流入网卡-i ens33
网卡名
-o
流出网卡-o ens33
-p {tcp|udp|icmp}
#icmp用于授权ping--sport
源端口--sport 22
--sport 22:80
连续的端口
--dport
目的端口--dport 80
--dport 80:3306
连续的端口
--icmp-type {8|0}
8
:ping请求
0
:ping响应
B.几个例子
a.仅允许Windows
访问服务器上的ssh
服务,并且拒绝其他所有服务
我的
windows
地址是192.168.140.1
,众所周知SSH
服务依靠TCP
协议的22
号端口
关于SSH
服务的教程:https://www.wsjj.top/archives/58
[root@node4 ~]# iptables -t filter -A INPUT -s 192.168.140.1 -d 192.168.140.14 -p tcp --dport 22 -j ACCEPT
拒绝所有服务,不需要指定源
IP
和目的IP
,也不需要指定协议和端口
[root@node4 ~]# iptables -t filter -A INPUT -j DROP #执行这条命令有风险,请确认上面的规则完全匹配你的环境
可以看到
2
条已经生效的规则
[root@node4 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.140.1 192.168.140.14 tcp dpt:22
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
测试其他机器能否通过SSH
连接服务器
[root@node5 ~]# ssh root@192.168.140.14
^C #可以看到无法建立连接
b.仅允许Windows
可以ping
通服务器,拒绝其他连接
-I<链名> 行号
用于插入规则到指定行数--icmp-type {8|0}
8
:ping请求
0
:ping响应
[root@node4 ~]# iptables -t filter -I INPUT 2 -s 192.168.140.1 -d 192.168.140.14 -p icmp --icmp-type 8 -j ACCEPT
查询规则
[root@node4 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.140.1 192.168.140.14 tcp dpt:22
ACCEPT icmp -- 192.168.140.1 192.168.140.14 icmptype 8
DROP all -- 0.0.0.0/0 0.0.0.0/0
Windows
测试
在添加规则之前,
Widnows
是无法ping
通服务器的
C:\Users\wangshengjj>ping 192.168.140.14
正在 Ping 192.168.140.14 具有 32 字节的数据:
来自 192.168.140.14 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.140.14 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.140.14 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.140.14 的回复: 字节=32 时间<1ms TTL=64
c.允许服务器ping
通其他主机,而其他主机(比如Windows)无法ping
通服务器
删除之前的ping
规则
[root@node4 ~]# iptables -t filter -D INPUT 2
新增规则
[root@node4 ~]# iptables -t filter -I INPUT 2 -d 192.168.140.14 -p icmp --icmp-type 0 -j ACCEPT
Windows
测试
C:\Users\wangshengjj>ping 192.168.140.14
正在 Ping 192.168.140.14 具有 32 字节的数据:
请求超时。
请求超时。
服务器这边测试
[root@node4 ~]# ping 192.168.140.1
PING 192.168.140.1 (192.168.140.1) 56(84) bytes of data.
64 bytes from 192.168.140.1: icmp_seq=1 ttl=128 time=0.104 ms
64 bytes from 192.168.140.1: icmp_seq=2 ttl=128 time=0.144 ms
64 bytes from 192.168.140.1: icmp_seq=3 ttl=128 time=0.159 ms
d.要求能ping
通自己
以目前的规则来说,我们是无法
ping
通自己的
添加规则
指定网卡为
io
Centos7
中,io
网卡为自己和自己通信的时候会用到
[root@node4 ~]# iptables -t filter -I INPUT 2 -i lo -p icmp -j ACCEPT
查看所有规则
[root@node4 ~]# iptables -t filter -nL -v --line-number
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 42850 3781K ACCEPT tcp -- * * 192.168.140.1 192.168.140.14 tcp dpt:22
2 6 504 ACCEPT icmp -- lo * 0.0.0.0/0 0.0.0.0/0
3 6 504 ACCEPT icmp -- * * 0.0.0.0/0 192.168.140.14 icmptype 0
4 91 7300 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
ping
测试
[root@node4 ~]# ping 192.168.140.14
PING 192.168.140.14 (192.168.140.14) 56(84) bytes of data.
64 bytes from 192.168.140.14: icmp_seq=1 ttl=64 time=0.015 ms
64 bytes from 192.168.140.14: icmp_seq=2 ttl=64 time=0.025 ms
64 bytes from 192.168.140.14: icmp_seq=3 ttl=64 time=0.026 ms
[root@node4 ~]# ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.015 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.061 ms
e.要求服务器可以正常上网,比如访问baidu
以目前的规则,服务器是无法正常
ping
通互联网服务器的,并且无法正常上网
添加规则,先能ping
通
众所周知,我们服务器想要
ping
通互联网上某个域名,需要依靠DNS
服务器把域名转换成公网地址
[root@node4 ~]# iptables -t filter -I INPUT -d 192.168.140.14 -p udp --sport 53 -j ACCEPT
[root@node4 ~]# iptables -t filter -I INPUT -d 192.168.140.14 -p tcp --sport 53 -j ACCEPT #有一部分DNS服务器基于TCP服务
测试ping
通baidu
[root@node4 ~]# ping baidu.com
PING baidu.com (39.156.66.10) 56(84) bytes of data.
64 bytes from 39.156.66.10 (39.156.66.10): icmp_seq=1 ttl=128 time=7.16 ms
64 bytes from 39.156.66.10 (39.156.66.10): icmp_seq=2 ttl=128 time=6.78 ms
继续添加规则,用于访问web
服务
开放源端口
80
和443
端口的访问
[root@node4 ~]# iptables -t filter -I INPUT -d 192.168.140.14 -p tcp --sport 80 -j ACCEPT
[root@node4 ~]# iptables -t filter -I INPUT -d 192.168.140.14 -p tcp --sport 443 -j ACCEP
使用curl
命令测试
[root@node4 ~]# curl www.baidu.com #正常访问
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
5.模块
-m <模块名><参数>
使用模块
A.multiport
模块
-m multiport
指定多个端口--sports
port1
,port2
,port3
源端口--dports
port1
,port2
,port3
目的端口
可以优化一下上面的规则
可以发现前面的三条规则,除了端口不一样,其他参数都是一样的,那么就可以调用这个模块
[root@node4 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 192.168.140.14 tcp spt:443
ACCEPT tcp -- 0.0.0.0/0 192.168.140.14 tcp spt:53
ACCEPT tcp -- 0.0.0.0/0 192.168.140.14 tcp spt:80
ACCEPT udp -- 0.0.0.0/0 192.168.140.14 udp spt:53
ACCEPT tcp -- 192.168.140.1 192.168.140.14 tcp dpt:22
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp -- 0.0.0.0/0 192.168.140.14 icmptype 0
DROP all -- 0.0.0.0/0 0.0.0.0/0
先删除旧的规则
[root@node4 ~]# iptables -t filter -D INPUT 1
[root@node4 ~]# iptables -t filter -D INPUT 1
[root@node4 ~]# iptables -t filter -D INPUT 1 #执行三遍,当删除第一条的时候,第二条会自动上位变成第一条,以此类推
[root@node4 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- 0.0.0.0/0 192.168.140.14 udp spt:53
ACCEPT tcp -- 192.168.140.1 192.168.140.14 tcp dpt:22
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp -- 0.0.0.0/0 192.168.140.14 icmptype 0
DROP all -- 0.0.0.0/0 0.0.0.0/0
添加规则
[root@node4 ~]# iptables -t filter -I INPUT 2 -d 192.168.140.14 -p tcp -m multiport --sports 53,80,443 -j ACCEPT
[root@node4 ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- 0.0.0.0/0 192.168.140.14 udp spt:53
ACCEPT tcp -- 0.0.0.0/0 192.168.140.14 multiport sports 53,80,443
ACCEPT tcp -- 192.168.140.1 192.168.140.14 tcp dpt:22
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp -- 0.0.0.0/0 192.168.140.14 icmptype 0
DROP all -- 0.0.0.0/0 0.0.0.0/0
B.iprange
模块
-m iprange
指定多个IP地址--src-range [ip-ip]
源地址--dst-range [ip-ip]
目的地址
允许
Windows
和node5
主机ping
通服务器
添加规则
[root@node4 ~]# iptables -t filter -I INPUT -m iprange --src-range 192.168.140.1-192.168.140.15 -d 192.168.140.14 -p icmp --icmp-type 8 -j ACCEPT
测试
C:\Users\wangshengjj>ping 192.168.140.14
正在 Ping 192.168.140.14 具有 32 字节的数据:
来自 192.168.140.14 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.140.14 的回复: 字节=32 时间<1ms TTL=64
[root@node5 ~]# ping 192.168.140.14
PING 192.168.140.14 (192.168.140.14) 56(84) bytes of data.
64 bytes from 192.168.140.14: icmp_seq=1 ttl=64 time=0.157 ms
64 bytes from 192.168.140.14: icmp_seq=2 ttl=64 time=0.180 ms
64 bytes from 192.168.140.14: icmp_seq=3 ttl=64 time=0.212 ms
C.state
状态模块
--state
NEW
- 首次访问
ESTABLISHED
- 服务后续所有访问
- 响应数据
RELATED
【FTP】- 相关联的连接
a.首次访问和后续访问
安装httpd
软件并启用
[root@node4 ~]# yum install -y httpd
[root@node4 ~]# systemctl enable --now httpd
编写防火墙规则
允许所有客户端首次访问和后续所有访问
[root@node4 ~]# iptables -t filter -I INPUT -d 192.168.140.14 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
Windows
测试
b.相关联的连接(FTP为例子)
安装FTP软件并启用
关于
FTP
服务教程:https://www.wsjj.top/archives/61
[root@node4 ~]# yum install -y vsftpd
[root@node4 ~]# systemctl enable --now vsftpd
随便放几个测试文件
[root@node4 ~]# touch /var/ftp/{1..5}.jpg
[root@node4 ~]# touch /var/ftp/{1..5}.mp3
[root@node4 ~]# ls /var/ftp/
1.jpg 1.mp3 2.jpg 2.mp3 3.jpg 3.mp3 4.jpg 4.mp3 5.jpg 5.mp3 pub
先释放TCP
协议21
号端口
[root@node4 ~]# iptables -t filter -I INPUT -d 192.168.140.14 -p tcp --dport 21 -j ACCEPT
使用node5
连接FTP
服务器
[root@node5 ~]# yum install -y ftp
[root@node5 ~]# ftp 192.168.140.14
Connected to 192.168.140.14 (192.168.140.14).
220 (vsFTPd 3.0.2)
Name (192.168.140.14:root): ftp #默认匿名用户是ftp
331 Please specify the password.
Password: #没有密码
关于
FTP
的默认行为
使用21
号端口传输命令,大于1024
以上的随机端口传输数据
我们并没有开放相应的端口,所以看不到数据
但是开放1024
以上的所有端口,并不合理
ftp> ls
227 Entering Passive Mode (192,168,140,14,199,133).
ftp: connect: 连接超时 #没有数据的
回到服务器配置防火墙规则
还是
FTP
默认行为
每次执行命令后,FTP
给我们返回结果的时候,每一次使用的端口都是大于1024
以上的随机端口
所以除了授权==相关连的连接==,还要保持==后续的连接==
[root@node4 ~]# iptables -t filter -I INPUT -d 192.168.140.14 -m state --state RELATED,ESTABLISHED -j ACCEPT
临时加载内核模块
没错,放行了相应的规则也不行
还需要让Linux
系统加载模块
[root@node4 ~]# modprobe ip_nat_ftp
[root@node4 ~]# modprobe ip_conntrack_ftp
回到node5
测试
[root@node5 ~]# ftp 192.168.140.14
Connected to 192.168.140.14 (192.168.140.14).
220 (vsFTPd 3.0.2)
Name (192.168.140.14:root): ftp
331 Please specify the password.
Password:
230 Login successful.
这次终于看到了,我们想要的数据
ftp> ls
227 Entering Passive Mode (192,168,140,14,165,81).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 May 24 12:35 1.jpg
-rw-r--r-- 1 0 0 0 May 24 12:35 1.mp3
-rw-r--r-- 1 0 0 0 May 24 12:35 2.jpg
-rw-r--r-- 1 0 0 0 May 24 12:35 2.mp3
-rw-r--r-- 1 0 0 0 May 24 12:35 3.jpg
-rw-r--r-- 1 0 0 0 May 24 12:35 3.mp3
-rw-r--r-- 1 0 0 0 May 24 12:35 4.jpg
-rw-r--r-- 1 0 0 0 May 24 12:35 4.mp3
-rw-r--r-- 1 0 0 0 May 24 12:35 5.jpg
-rw-r--r-- 1 0 0 0 May 24 12:35 5.mp3
drwxr-xr-x 2 0 0 6 Jun 09 2021 pub
226 Directory send OK.
6.保存、恢复规则
默认防火墙规则都是临时的,重启以后失效
[root@node4 ~]# iptables-save > /opt/iptables.rules
[root@node4 ~]# iptables-restore < /opt/iptables.rules
7.修改规则
-R
修改规则
[root@node4 ~]# iptables -R INPUT 2 -s 192.168.140.11 -d 192.168.140.14 -p tcp -m multiport --dports 3306,22 -j ACCEPT
8.修改默认规则
-P
修改默认规则
iptables
默认的链规则是允许
A.命令格式
iptables -t <表名> -P <链名> <行为>
行为
ACCEPT
允许DROP
拒绝REJECT
拒绝
B.修改默认output链,默认允许改为拒绝
请确保已经添加的
SSH
出口规则!
[root@node4 ~]# iptables -t filter -A OUTPUT -p tcp --sport 22 -j ACCEPT #出口允许22号端口
[root@node4 ~]# iptables -P OUTPUT DROP
C.再次查看规则
[root@node4 ~]# iptables -nL
Chain OUTPUT (policy DROP) #这里的默认行为已经变更为拒绝
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:22
[root@node4 ~]# ping baidu.com
ping: baidu.com: 未知的名称或服务 #已经断网了
[root@node4 ~]# ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
ping: sendmsg: 不允许的操作
ping: sendmsg: 不允许的操作
D.恢复默认允许策略
[root@node4 ~]# iptables -P OUTPUT ACCEPT
五、NAT表管理
1.NAT
的工作原理
- 转换源
IP
地址-j SNAT --to-source <公网地址>
-j MASQUERADE
- 转换目的
IP
地址-j DNAT --to-destination <内网地址>
2.SNAT
源地址转换
作用: 普通主机可以访问互联网
正常,==内网IP==是无法直接==访问互联网==的,都是通过NAT
的网络地址转换技术,把我们的==内网IP==地址临时转换成==公网IP==。
这一点,有点像家用的路由器一样,它会自动的把我们的内网IP
转换成拨号上号的那个公网IP
实验
主机名 | IP地址 | 作用 |
---|---|---|
client.linux.com | 192.168.233.10 | 模拟客户端 |
nat.linux.com | 192.168.233.100、30.30.30.128 | 模拟NAT |
server.linux.com | 30.30.30.10 | 模拟公网服务器 |
在配置之前,请提前准备好
httpd
的服务
A.先给NAT主机添加一块网卡
B.修改另外2台主机的网卡
C.配置IP地址和网关地址
[root@client ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
BROWSER_ONLY="no"
BOOTPROTO="none"
DEFROUTE="yes"
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"
ETHTOOL_OPTS="autoneg on"
IPADDR=192.168.233.10
NETMASK=255.255.255.0
GATEWAY=192.168.233.100
[root@nat ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
BROWSER_ONLY="no"
BOOTPROTO="none"
DEFROUTE="yes"
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"
ETHTOOL_OPTS="autoneg on"
IPADDR=192.168.233.100
#NETMASK=255.255.255.0
#GATEWAY=192.168.140.2
#DNS1=114.114.114.114
#DNS2=8.8.8.8
[root@nat ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens36
TYPE="Ethernet"
BROWSER_ONLY="no"
BOOTPROTO="none"
DEFROUTE="yes"
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"
ETHTOOL_OPTS="autoneg on"
IPADDR=30.30.30.128
[root@server ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet"
BROWSER_ONLY="no"
BOOTPROTO="none"
DEFROUTE="yes"
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"
ETHTOOL_OPTS="autoneg on"
IPADDR=30.30.30.10
NETMASK=255.255.255.0
D.在服务器上发布测试网页
[root@server ~]# rm -rf /etc/httpd/conf.d/welcome.conf
[root@server ~]# echo "<h1>30.30.30.10 webserver</h1>" > /var/www/html/index.html
[root@server ~]# systemctl enable --now httpd
E.配置NAT
先修改内核参数,开启路由地址转发功能
[root@nat ~]# sed -ri '$a \net.ipv4.ip_forward = 1' /etc/sysctl.conf
[root@nat ~]# sysctl -p
net.ipv4.ip_forward = 1
添加到规则到防火墙
指定网段的所有请求,都会被
NAT
转换成Wan
口的IP
也就是30.30.30.128
[root@nat ~]# iptables -t nat -A POSTROUTING -s 192.168.233.0/24 -j SNAT --to-source 30.30.30.128
或
指定网段的所有请求,都会被
NAT
自动转换成Wan
口的IP
[root@nat ~]# iptables -t nat -A POSTROUTING -s 192.168.233.0/24 -j MASQUERADE
[root@nat ~]# iptables -t nat -nL -v
Chain PREROUTING (policy ACCEPT 5 packets, 300 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
5 300 MASQUERADE all -- * * 192.168.233.0/24 0.0.0.0/0
F.客户端测试访问
[root@client ~]# curl 30.30.30.10
<h1>30.30.30.10 webserver</h1>
可以查看
server
端的访问日志
[root@server ~]# tail -f /var/log/httpd/access_log
30.30.30.128 - - [29/May/2023:14:18:35 +0800] "GET / HTTP/1.1" 200 31 "-" "curl/7.29.0"
30.30.30.128 - - [29/May/2023:14:20:50 +0800] "GET / HTTP/1.1" 200 31 "-" "curl/7.29.0"
30.30.30.128 - - [29/May/2023:14:20:50 +0800] "GET / HTTP/1.1" 200 31 "-" "curl/7.29.0"
30.30.30.128 - - [29/May/2023:14:20:51 +0800] "GET / HTTP/1.1" 200 31 "-" "curl/7.29.0"
30.30.30.128 - - [29/May/2023:14:20:52 +0800] "GET / HTTP/1.1" 200 31 "-" "curl/7.29.0"
这个
IP
很明显是NAT
上的wan
口IP
,相对于client
端就是他的公网IP
3.DNAT
发布服务(端口映射)
实验
模拟公网客户端,访问内网的服务器
注意:NAT
上面wan口
绑定的IP
必须是公网IP
端口映射的端口不可以冲突!
主机名 | IP地址 | 作用 |
---|---|---|
server.linux.com | 192.168.233.10 | 模拟服务端 |
nat.linux.com | 192.168.233.100、30.30.30.128 | 模拟NAT |
client.linux.com | 30.30.30.10 | 模拟客户端 |
A.服务端发布测试页面
[root@client ~]# rm -rf /etc/httpd/conf.d/welcome.conf
[root@client ~]# echo "192.168.233.10 webserver" > /var/www/html/index.html
[root@client ~]# systemctl enable --now httpd
B.公网客户端测试
[root@server ~]# curl 30.30.30.128 #这是正常现象,我们还没有做端口映射
curl: (7) Failed connect to 30.30.30.128:80; 拒绝连接
C.回到NAT服务器,配置防火墙策略
把内网
192.168.233.10
上的80
端口,映射到公网30.30.30.128
的8080
端口
[root@nat ~]# iptables -t nat -I PREROUTING -d 30.30.30.128 -p tcp --dport 8080 -j DNAT --to-destination 192.168.233.10:80
D.再次测试
[root@server ~]# curl 30.30.30.128:8080 #这次访问正常了
192.168.233.10 webserver