3. iptables防火墙
1. iptables简介
netfilter/iptables IP 信息包过滤系统是一种功能强大的工具,可用于添加、编辑和除去规则,这些规则是在做信息包过滤决定时,防火墙所遵循和组成的规则。这些规则存储在专用的信息包过滤表中,而这些表集成在 Linux 内核中。在信息包过滤表中,规则被分组放在我们所谓的链(chain)中。
虽然 netfilter/iptables IP 信息包过滤系统被称为单个实体,但它实际上由两个组件netfilter 和 iptables 组成。
netfilter 组件也称为内核空间(kernelspace),是内核的一部分,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。
iptables 组件是一种工具,也称为用户空间(userspace),它使插入、修改和除去信息包过滤表中的规则变得容易。
netfilter/iptables 的最大优点是它可以配置有状态的防火墙。有状态的防火墙能够指定并记住为发送或接收信息包所建立的连接的状态。防火墙可以从信息包的连接跟踪状态获得该信息。在决定新的信息包过滤时,防火墙所使用的这些状态信息可以增加其效率和速度。
netfilter/iptables 的另一个重要优点是,它使用户可以完全控制防火墙配置和信息包过滤。您可以定制自己的规则来满足您的特定需求,从而只允许您想要的网络流量进入系统。
2. iptables 基础部分
1. 语法
iptables [-t 要操作的表] <操作命令> [要操作的链] [规则号码] [匹配条件] [-j 匹配后的动作]
小写 大写 大写 小写 大写
2. 表及应用顺序
raw —> mangle —> nat —> filter
3. 常见的操作命令
-L 查看,v详细,n不反解 --line-number
-A 追加,放置最后一条
-I 插入,默认插入成第一条
-D 删除
-F 清空flush
-R 替换
-X 删除空的自定义链
-P 设置默认策略
1. 基本匹配
-s 192.168.2.0/24 源地址
-d 192.168.2.1 目标地址
-p tcp|upd|icmp 协议
-i eth0 input 从eth0接口进入的数据包
-o eth0 output 从eth0出去的数据包
-p tcp --sport 80 源端口是80的数据包
-p tcp --dport 80 目标端口是80,必须和-p tcp|udp 连用
2. 基本动作 Target
-j ACCEPT 接受 filter
-j REJECT 拒绝 filter
-j DROP 丢弃 filter
-j SNAT 源地址转换 nat
-j MASQUERADE 伪装 nat
-j DNAT 目标地址转换 nat
-j MARK 标记 mangle
-j LOG
3. 查询
iptables -L 默认 filter表
iptables -L -t filter
iptables -L -t nat
iptables -L -t mangle
Filter表 centos6
service iptables start
service iptables stop
service iptables save 保存规则
保存规则的路径:/etc/sysconfig/iptables
centos7
#保存规则
[root@robin ~]# iptables-save > /tmp/iptables.rule
#恢复规则
[root@robin ~]# iptables-restore < /tmp/iptables.rule
iptables -t filter -A INPUT -j DROP
# 清除filter表所有规则
iptables -t filter -F
# 清除filter表INPUT链
iptables -t filter -F INPUT
# 添加规则
iptables -t filter -A INPUT -j DROP
iptables -t filter -A INPUT -j ACCEPT
# 指定位置插入规则
iptables -t filter -I INPUT 1 -j ACCEPT
iptables -t filter -I INPUT 2 -j ACCEPT
# 修改规则
iptables -t filter -R INPUT 3 -j ACCEPT
# 删除规则
iptables -t filter -D INPUT -j ACCEPT
# 指定删除规则的行号
iptables -t filter -D INPUT 3
# 查询规则行号
iptables -L --line-numbers
# 修改默认值
iptables -t filter -P INPUT DROP
4. 根据IP地址
# -s 表示源地址
# -d 表示目标地址
# 限制一个ip地址不允许链接访问
iptables -t filter -A INPUT -s 172.16.110.92 -j DROP
# 限制目的地址不允许链接访问
iptables -t filter -A INPUT -d 172.16.110.1 -j DROP
# 除了这个地址以外别的地址都可以连接访问
iptables -t filter -A INPUT ! -s 172.16.110.92 -j DROP
# 限制一个网段不允许链接
iptables -t filter -A INPUT -s 172.16.110.0/24 -j DROP
【注】
每次使用iptables -L回显速度慢,说明防火墙在解析、
使用iptables -L -n可以增加解析速度
5. 练习1
禁止你的同桌对你的访问(在INPUT和OUTPUT各写出规则) 几条?
1.根据源地址和目的地址
iptables -t filter -A INPUT -s 192.168.100.202 -j DROP
iptables -t filter -A OUTPUT -d 192.168.100.202 -j DROP
2.根据协议
iptables -A INPUT -s 172.16.110.92 -p icmp -j DROP
iptables -A INPUT -s 172.16.110.92 -p tcp -j DROP
iptables -A INPUT -s 172.16.110.92 ! -p tcp -j DROP
3.根据端口
# --sport 源端口
# --dport 目的端口
iptables -A INPUT -s 172.16.110.92 -p tcp --dport 22 -j DROP
iptables -A INPUT -s 172.16.110.92 -p tcp ! --dport 22 -j DROP
# 22号端口到80端口
iptables -A INPUT -s 172.16.110.92 -p tcp --dport 22:80 -j DROP
# 22号端口到最后端口
iptables -A INPUT -s 172.16.110.92 -p tcp --dport 22: -j DROP
# 0到80端口
iptables -A INPUT -s 172.16.110.92 -p tcp --dport :80 -j DROP
4.根据网卡
iptables -A INPUT -i eth0 -j DROP
iptables -A OUTPUT -o eth0 -j DROP
6. 练习2
禁止同桌访问你的80端口在(INPUT 和 OUTPUT)
iptables -A INPUT -s 172.16.110.92 -p tcp --dport 80 -j DROP
iptables -A OUTPUT -d 172.16.110.92 -p tcp --sport 80 -j DROP
7. 练习3
写一个脚本
只允许别人访问你的http服务 sshd服务 vsftpd服务
4. 自定义链
# 创建
iptables -N lian1
# 添加链接
iptables -A INPUT -j lian1
# 自定义链动作
iptables -A lian1 -j DROP
# 修改链名
iptables -E lian1 newlian
删除自已定义链
# 清除链接
iptables -D INPUT 1
# 删除自定义链内规则
iptables -F newlian
# 删除自定义链
iptables -X newlian
注
1.从INPUT链进来的包包括其它主机访问本机的数据包,本机访问其它主机时,其它主机给本机回的数据包
2.从OUTPUT链出去的包包括本机访问访其它主机的数据包,其它主机访问本机时,本机给其它主机回的数据包
1. 问题
本机要访问其他主机的其他服务端口?
如果有人用自己的22和80端口来不友好访问怎么办?
不希望别人ping通自己,但是自己可以ping其他主机怎么办?
3. iptables 高级部分
1. 扩展匹配 MATCH EXTENSIONS
man iptables /MATCH EXTENSIONS //每一种功能必须有相应的的内核模块支持
[root@tianyun ~]# ls /lib/modules/`uname -r`/kernel/net/netfilter/
[root@tianyun ~]# ls /lib/modules/`uname -r`/kernel/net/ipv4/netfilter/
man iptables-extensions
1. 查帮助的方法
[root@tianyun ~]# iptables -m icmp -h
[root@tianyun ~]# iptables -m icmp -h //从后往前看
[root@tianyun ~]# iptables -m iprange -h //从后往前看
-m icmp
[root@tianyun ~]# iptables -t filter -A INPUT -p icmp -m icmp --icmp-type echo-reply -j ACCEPT //回应
[root@tianyun ~]# iptables -t filter -A INPUT -p icmp -m icmp --icmp-type echo-request -j ACCEPT //请求
如果我想ping通别的主机 不想别的主机ping通我怎么办?
-m iprange
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@localhost ~]# iptables -t filter -A FORWARD -m iprange --src-range 172.16.1.10-172.16.1.20 -j DROP
[root@localhost ~]# iptables -t filter -A INPUT -p tcp --dport 80 -m iprange --src-range 172.16.1.10-172.16.1.20 -j DROP
-m mac
iptables -A INPUT -p icmp -m mac --mac-source 00:0C:29:AA:7A:ED -j DROP
-m multiport
[root@localhost ~]# iptables -t filter -A INPUT -p tcp -m multiport --source-ports 22,80,21 -j ACCEPT
2. state 基于链接状态
这里有四种有效状态:名称分别为 ESTABLISHED 、 INVALID 、 NEW 和 RELATED 。
NEW 意味着该信息包已经或将启动新的连接,或者它与尚未用于发送和接收信息包的连接相关联。
ESTABLISHED 指出该信息包属于已建立的连接,该连接一直用于发送和接收信息包并且完全有效。
RELATED 表示该信息包正在启动新连接,以及它与已建立的连接相关联。
INVALID 状态指出该信息包与任何已知的流或连接都不相关联,它可能包含错误的数据或头。
我们再这里测试的时候要用到防火墙的日志,依赖于内核日志,这里把日志打开
vim /etc/rsyslog.conf
kern.* /var/log/iptables.log
1. 开启日志记录INPUT四种状态
iptables -A INPUT -s 192.168.116.150 -p icmp -m icmp --icmp-type echo-request -m state --state NEW -j LOG --log-prefix " IN_ICMP_NEW "
iptables -A INPUT -s 192.168.116.150 -p icmp -m icmp --icmp-type echo-request -m state --state ESTABLISHED -j LOG --log-prefix " IN_ICMP_ES "
iptables -A INPUT -s 192.168.116.150 -p icmp -m icmp --icmp-type echo-request -m state --state RELATED -j LOG --log-prefix " IN_ICMP_RE "
iptables -A INPUT -s 192.168.116.150 -p icmp -m icmp --icmp-type echo-request -m state --state INVALID -j LOG --log-prefix " IN_ICMP_IN "
2. 开启日志记录OUTPUT四种状态
iptables -A OUTPUT -d 192.168.116.150 -p icmp -m icmp --icmp-type echo-reply -m state --state NEW -j LOG --log-prefix " OUT_ICMP_NEW "
iptables -A OUTPUT -d 192.168.116.150 -p icmp -m icmp --icmp-type echo-reply -m state --state ESTABLISHED -j LOG --log-prefix " OUT_ICMP_ES "
echo
iptables -A OUTPUT -d 192.168.116.150 -p icmp -m icmp --icmp-type echo-reply -m state --state RELATED -j LOG --log-prefix " OUT_ICMP_RE "
iptables -A OUTPUT -d 192.168.116.150 -p icmp -m icmp --icmp-type echo-reply -m state --state INVALID -j LOG --log-prefix " OUT_ICMP_IN "
1. ICMP
ping -c 1 192.168.116.100
查看日志
A----- PING ------->B
echo-request---------------------> NEW
<---------------------echo-reply ESTABLISHED
A----- PING ------->B
echo-request-----------------------> NEW
<----XXXXXXX------ RELATED
iptables -t filter -A OUTPUT -p icmp -m icmp --icmp-type echo-request -m state --state NEW -j LOG --log-prefix " ICMP_NEW "
iptables -t filter -A INPUT -p icmp -m icmp --icmp-type host-unreachable -m state --state RELATED -j LOG --log-prefix " ICMP_RELATED
2. tcp
A B
------------SYN----------> NEW
<--------syn+ack------- ESTABLISHED
------------ack-----------> ESTABLISHED
. . .
--------data--------------> ESTABLISHED
<-----------ack----------- ESTABLISHED
. . .
-------------fin-----------> ESTABLISHED
<-----------ack----------- ESTABLISHED
<------------fin------------ ESTABLISHED
-------------ack-----------> ESTABLISHED
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix " IN_80_NEW "
iptables -A OUTPUT -p tcp --sport 80 -m state --state NEW -j LOG --log-prefix " OUT_80_NEW "
3. ftp
A 30000 ----------syn-----------> B 21 NEW
<------syn+ack--------- ESTABLISHED
-----------ack----------> ESTABLISHED
. . .
--------data--------------> ESTABLISHED
<-----------ack----------- ESTABLISHED
. . .
-------------fin-----------> ESTABLISHED
<-----------ack----------- ESTABLISHED
<------------fin------------ ESTABLISHED
-------------ack-----------> ESTABLISHED
30001 <----------syn---------- B 20 NEW/RELATED #modprobe nf_conntrack_ftp 有了这个模块被识别为RELATED
-------syn+ack-------> ESTABLISHED
<-----------ack--------- ESTABLISHED
. . .
--------data--------------> ESTABLISHED
<-----------ack----------- ESTABLISHED
. . .
-------------fin-----------> ESTABLISHED
<-----------ack----------- ESTABLISHED
<------------fin------------ ESTABLISHED
-------------ack-----------> ESTABLISHED
4. nmap 端口扫描
nmap 1.1.1.1 -p 80
A--------syn--------->B 80 NEW
<-----syn+ack----- ESTABLISHED
----------RST---------> ESTABLISHED
nmap -sA 1.1.1.1 -p 80
A--------ack--------->B 80 NEW
<--------RST---------- ESTABLISHED
nmap -sF 1.1.1.1 -p 80
A--------fin-----------> B 80 INVALID
--------fin-----------> INVALID
A--------FIN-------> B INVALID
<----RST+ACK----- INVALID
UDP
A------------------->B port 53 NEW
<------------------- ESTABLISHED
3. 实验
1. 实验一
使用状态防火墙,放行本机HTTP服务:
iptables -P INPUT DROP
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
2. 实验二
使用状态防火墙,放行本机FTP服务:
iptables -P INPUT DROP
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 21 -j ACCEPT //放行控制端口
modprobe nf_conntrack_ftp
小结: 该内核模块的作用是在<连接数据端口时>,将第一次握手的数据包状态由原来的 NEW 识别成 RELATED
4. 其他扩展
RHEL5: ip_conntrack_ftp
其他扩展匹配
-m tos //type of service
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
tcpdump -i eth0 -nn port 22 -vvv //抓取远程主机访问本机ssh数据包,分别于输入密码前和后观察TOS值
tcpdump -i eth0 -nn port 22 -vvv //抓取远程从本机scp复制文件,分别于输入密码前和后观察TOS值
小结:都是使用22/tcp,但可以通过TOS值来区分应用
ssh: tos 0x0 0x10
scp: tos 0x0 0x8
rsync: tos 0x0 0x8
iptables -m tos -h
iptables -t filter -A INPUT -p tcp --dport 22 -m tos --tos 0x10 -j DROP //仅拒绝客户端ssh到本机
-m ttl //TTL是IP首部的一部分
cat /proc/sys/net/ipv4/ip_default_ttl
iptables -t filter -A FORWARD -m ttl --ttl-eq 128 -j DROP //不帮windows转发,本机作为网关role
iptables -t filter -A FORWARD -m ttl --ttl-gt 64 -j DROP //大于64
-m limit 限制主机访问
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
实验:从客户端ping本机,观察序列号
iptables -t filter -A INPUT -p icmp -m icmp --icmp-type echo-request -m limit --limit 20/minute -j ACCEPT
iptables -t filter -A INPUT -p icmp -m icmp --icmp-type echo-request -j REJECT
进入本机INPUT链的ICMP Request,如果匹配第一条则放行,不匹配的将被第二条拒绝,默认前5个不限
16/second
16/minute
16/hour
16/day
iptables -t filter -A INPUT -p tcp --syn --dport 80 -m limit --limit 50/second -j ACCEPT
iptables -t filter -A INPUT -p tcp --syn --dport 80 -j DROP
-m connlimit 限制主机连接数
iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 2 -j REJECT //仅允许每个客户端有两个ssh连接
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit ! --connlimit-above 16 -j REJECT //仅允许每个客户端有16个requests
iptables -A INPUT -j REJECT
-j REJECT
[root@robin ~]# iptables -P INPUT ACCEPT
[root@robin ~]# iptables -P OUTPUT ACCEPT
[root@robin ~]# iptables -P FORWARD ACCEPT
[root@robin ~]# iptables -F
[root@robin ~]# iptables -t filter -A INPUT -s 192.168.2.110 -p tcp --dport 22 -j REJECT
[root@robin ~]# tcpdump -i eth0 -nn host 192.168.2.110
小结: 结果给客户端使用icmp返回一个TCP端口不可达的数据包。但正常情况访问一个未开启的TCP端口时,应该返回一个带有RST标记的数据包,从而客户端会知道并不是未开启该端口,而是被拒绝了。因此…
[root@robin ~]# iptables -j REJECT -h
[root@robin ~]# iptables -t filter -A INPUT -s 192.168.2.110 -p tcp --dport 22 -j REJECT --reject-with tcp-reset //返回一个自定义原因
[root@robin ~]# tcpdump -i eth0 -nn host 192.168.2.110
小结: 客户将会看到带有RST标记的数据包,从而认为服务器该端口没有开启
-j MARK
[root@robin ~]# iptables -t mangle -L
[root@robin ~]# iptables -j MARK -h
[root@robin ~]# iptables -t mangle -A PREROUTING -p icmp -s 192.168.2.110 -j MARK --set-mark 1
[root@robin ~]# iptables -t mangle -A PREROUTING -p icmp -s 192.168.2.25 -j MARK --set-mark 2
[root@robin ~]# iptables -t filter -A INPUT -m mark --mark 1 -j ACCEPT //按照标记匹配
[root@robin ~]# iptables -t filter -A INPUT -m mark --mark 2 -j DROP
LVS端口亲缘性打标记
5. NAT表
POSTROUTING: SNAT, MASQUERADE
PRETROUTING: DNAT
OUTPUT: DNAT,针对本机
1. 源地址转换
-j SNAT 地址已经被写死,当地址发生变化时,就不能继续进行访问网络。
-j MASQUERADE 伪装(公司或家里用的基本都是这个规则)即使是客户端的ip改变了也没事,可以继续进行访问网络
Client:(192.168.2.25)---------> (eth0: 192.168.2.110) NAT Server (eth1: 1.1.1.1)----------> 1.1.1.10(Internet web)
[root@nat_server ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@nat_server ~]# iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth1 -j SNAT --to-source 1.1.1.1 //外网网卡eth1
[root@client ~]# iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j SNAT --to 10.10.10.254
[root@nat_server ~]# iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth1 -j MASQUERADE
2. 目的地址转换
-j DNAT //以SNAT为基础
web server(192.168.2.25)<--------(eth0: 192.168.2.110) NAT Server (eth1: 1.1.1.1)<---------- 1.1.1.10(Internet client)
[root@nat_server ~]# iptables -t nat -A PREROUTING -i eth1 -d 1.1.1.1 -p tcp --dport 80 -j DANT --to-destination 192.168.0.25:80
[root@nat_server ~]# iptables -t nat -A OUTPUT -d 1.1.1.1 -p tcp --dport 80 -j DNAT --to 192.168.2.25:80 //从本机访问1.1.1.1:80
-j REDIRECT //端口重定向
[root@nat_server ~]# iptables -t nat -A PREROUTING -s 192.168.2.0/24 -p tcp --dport 80 -j REDIRECT --to 192.168.2.110:3128 //本机端口重定向
三台虚拟机进行SNAT测试
SNAT 只能放在PREROUTING上
三台服务器需要处于同一模式下,在不同模式下不能进行相关实验
一台作为客户端
ens33
客户端的IP地址为
IPADDR=192.168.100.144
NETMASK=255.255.255.0
GATEWAY=192.168.100.10
测试的时候使用curl命令进行测试服务器端通不通即可。
一台作为网关
# 网关需要两个网卡,一个为ens33 一个为ens37
# 相关地址配置为
ens33
IPADDR=192.168.43.140
NETMASK=255.255.255.0
GATEWAY=192.168.43.1
ens37
IPADDR=192.168.100.10
NETMASK=255.255.255.0
#GATEWAY=192.168.100.1
# 清除防火墙的相关规则,然后添加规则
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j SNAT --to 192.168.43.140
从客户端进的地址是从192.168.100.144走ens37网卡走100网段,.
开启路由转发功能
echo 1 /proc/sys/net/ipv4/ip_forward
将目的地址指向ens33的网卡地址,不能直接指向服务器的IP地址
不要在防火墙规则中添加-o ens网卡选项。
一台作为服务器
ens33
IPADDR=192.168.43.110
NETMASK=255.255.255.0
GATEWAY=192.168.43.1
三台虚拟机进行DNAT实验
DNAT只能放在POSTROUTING上
一台作为客户端
ens33
客户端的IP地址为
IPADDR=192.168.100.144
NETMASK=255.255.255.0
测试的时候使用curl命令进行测试服务器端通不通即可。
curl命令测试的是网关的100网段的ip
curl 192.168.100.10
一台作为网关
# 网关需要两个网卡,一个为ens33 一个为ens37
# 相关地址配置为
ens33
IPADDR=192.168.43.140
NETMASK=255.255.255.0
GATEWAY=192.168.43.1
ens37
IPADDR=192.168.100.10
NETMASK=255.255.255.0
#GATEWAY=192.168.100.1
# 清除防火墙的相关规则,然后添加规则
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to 192.168.43.110
从客户端进的地址是从192.168.100.144走ens37网卡走100网段,.
开启路由转发功能
echo 1 /proc/sys/net/ipv4/ip_forward
直接指向服务器的IP地址
不要在防火墙规则中添加-o ens网卡选项。
一台作为服务器
ens33
IPADDR=192.168.43.110
NETMASK=255.255.255.0
GATEWAY=192.168.43.140
将中间的网关作为服务器的网关地址
3. SNAT和DNAT区别
1.SNAT 是源地址转换 主要用于客户端上网 访问时 访问web服务器的ip地址
2.DNAt 是目标地址转换, 放置在web服务器的前边,过滤数据包,阻挡恶意攻击 访问时 访问的是DNAT的公网ip