iptables防火墙

1.iptables简介

netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火墙解决方案。

1.1 netfilter和iptables的区别

netfilter:指的是Linux内核中实现包过滤防火墙的内部结构,属于“内核态”(KernelSpace,又称内核空间)的防火墙功能体系;

Iptables:指的是用来管理Linux防火墙的命令程序,属于“用户态”(UserSpace,又称用户空间)的防火墙管理体系;

所以其实iptables只是Linux防火墙的管理工具而已,真正实现防火墙功能的是 netfilter,它是Linux内核中实现包过滤的内部结构。

1.2 iptables和firewalld的关系

Cetnos7以上版本中替换了iptables变为firewalld作管理工具,内核层面由nftables包过滤框架来处理,思路基本相同。

2.iptables的四表五链


|默认4个规则表|默认5种规则链|
| ---- | ---- | ---- |
|raw:一般用于确定是否对数据包进行状态跟踪;|INPUT:处理入站数据包;|
|mangle:一般用于数据包修改(修改TOS/TTL或设置Mark标记);|OUTPUT:处理出站数据包;|
|nat:一般用于网络地址转换(源地址转换和目的地址转换);|FORWARD:处理转发数据包;|
|filter:一般用于对数据包进行过滤;|PREROUTING:在进行路由选择前处理数据包(做目标地址转换);|
|表优先级关系: raw > mangle > nat > filter;|POSTROUTING:在进行路由选择后处理数据包(做源地址转换);|

入站数据 出站数据 转发数据
PREROUTING -> INPUT OUTPUT -> POSTROUTING PREROUTING -> FORWARD -> POSTROUTING
表优先级 链内匹配顺序
raw > mangle > nat > filter 至上向下依次检查、匹配到对应规则即停止(LOG日志策略例外)
若在链内找不到匹配规则、则按照该链默认策略处理
3.iptables命令语法

COMMAND:

MATCH:可使用 ! 符号进行条件取反
1).通用匹配:

-f/--fragment仅适用于IPv4不适用IPv6,!-f表示仅匹配头分片或没有被分片的数据包;
由于传输过程中当数据包大于MTU时会对数据报进行分分片、但只有第一个数据分片包含完整的头部信息、iptbales默认只会检查有完整头部信息的数据分片、导致后续分片无法通过:

假如有这样的一条规则:
#iptables -A FORWARD -s 192.168.10.0/24 -d 172.16.1.10 -p tcp --dport 80 -j ACCEPT
#FORWARD链的默认规则是:DROP
此时系统只会让第一个ip碎片通过,而余下的碎片因为包头信息不完整而无法通过;

解决办法,使用-f/--fragment选项检查第二个及后面分片并ACCEPT:
#iptables -A FORWARD -f -s 192.168.10.0/24 -d 172.16.1.10 -p tcp --dport 80 -j ACCEPT
注意:允许ip碎片通过是有安全隐患的(如DoS攻击),可以采用iptables的匹配扩展来进行限制;

2).隐含扩展:使用-p{tcp|udp|icmp}指定协议型后,自动能够对协议进行扩展;

3).显示扩展:必须要明确指定的扩展模块;

TARGET:

-j 和 -g 的区别:
-j/--jump target:其中target可以是自定义链,内建target,以及扩展;
-g/--goto chain:对象只能为自定义链,并且从自定义链返回时是返回到-g选项的上一层的那个-j链中;
4.iptbales配置参考
4.1 主机安全
#基本配置:
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT    #允许ESTABLISHED和RELATED流量;
-A INPUT -i lo -j ACCEPT    #允许本地环回接口;
-A INPUT -p icmp -j ACCEPT    #允许icmp协议;
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT    #允许端口22(ssh)访问;
-A INPUT -j REJECT --reject-with icmp-host-prohibited    #拒绝所有返回错误类型;

#限制速率:{Ping包超过5次,限制为每分钟允许6次}
-A INPUT -p icmp --icmp-type 8 -m limit --limit 6/m --limit-burst 5 -j ACCEPT
-A INPUT -p icmp --icmp-type 8 -j REJECT --reject-with icmp-host-prohibited
#限制并发会话数:
iptables -A INPUT -i eth0 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP      #限制外网网卡每个IP最多15个初始连接,防止DDOS攻击;
iptables -A INPUT -p tcp --port 80 -m connlimit --connlimit-above 50 -j REJECT --reject-with icmp-port-reachable      #限制单个IP的最大并发连接数;
4.2 防火墙安全
#filter包过滤配置:
-A FORWARD -i eth0 -d 210.15.113.0/28 -p icmp -j ACCEPT
-A FORWARD -i eth0 -d 210.15.113.0/28 -p tcp -g FWTCP
-A FORWARD -i eth0 -d 210.15.113.0/28 -p udp -g FWUDP
-A FORWARD -i eth0 -d 210.15.113.0/28 -j LOG --log-prefix "iptables: FW-OTH " --log-level 7
-A FORWARD -i eth0 -d 210.15.103.0/28 -j DROP
-A FWTCP -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FWTCP -p tcp -m multiport --dports 22,53,80,443 -j ACCEPT
-A FWTCP -p tcp -j DROP
-A FWUDP -p udp -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FWUDP -p udp -m multiport --dports 53,123 -j ACCEPT
-A FWUDP -p udp -j DROP

#nat地址转换配置
##POSTROUTING_SNAT/MASQUERADE:
-A POSTROUTING -o eth0 -s 192.168.10.0/24 -p icmp -j MASQUERADE
-A POSTROUTING -o eth0 -s 192.168.10.0/24 -p tcp -g PRTCP
-A POSTROUTING -o eth0 -s 192.168.10.0/24 -p udp -g PRUDP
-A POSTROUTING -o eth0 -s 192.168.10.0/24 -j LOG --log-prefix "iptables: PR-OTH " --log-level 7
-A PRTCP -o eth0 -p tcp -s 192.168.10.0/24 -m multiport --dports 22,53,80,443 -j MASQUERADE
-A PRTCP -o eth0 -p tcp -s 192.168.10.0/24 -m multiport --dports 25,465,587,110,995,143,993 -j MASQUERADE
-A PRUDP -o eth0 -p udp -s 192.168.10.0/24 -m multiport --dports 53,123 -j MASQUERADE
##PREROUTING_DNAT:
-A PREROUTING -i eth0 -p tcp -d 210.15.113.1 -m multiport --dports 8000 -j DNAT --to-destination 192.168.10.11:80
-A PREROUTING -i eth0 -p tcp -d 210.15.113.1 -m multiport --dports 110,995,143,993 -j DNAT --to-destination 192.168.10.12

#mangle标记Mark
-A PREROUTING -i eth1 -p tcp -m set ! --match-set intexclude src -m set ! --match-set dstexclude dst -m multiport --dports 80,443 -j MARK --set-xmar
k 0x3/0xffffffff
#将标记的流量进行策略路由配置:
ip rule add fwmark 0x3 lookup swg
ip route add default via 192.168.20.1 tables swg

#raw跳过{nf_conntrack}状态跟踪
-A PREROUTING -i eth0 -p tcp -d x.x.x.x --dport 80 -j NOTRACK
附1.iptables安装和服务管理

Centos6中iptables默认已经安装可直接使用,Centos7中安装iptables替换默认firewalld步骤如下:

yum install -y iptables-services
systemctl stop firewalld
systemctl disable firewalld
systemctl start iptables
systemctl enable iptables

iptables配置文件,服务管理:

/etc/sysconfig/iptables      #iptbales规则存放文件
iptables-save > /etc/sysconfig/iptables      #保存规则到配置文件
iptables-restore < /etc/sysconfig/iptables      #恢复iptables配置文件
service iptables start/stop/restart/status/reload/save      #Centos6/7中服务管理
systemctl start/stop/restart/status/reload iptables      #Centos7中服务管理
/etc/init.d/iptables start/stop/restart/status/reload/save      #Centos6中服务管理

Dbian中iptables:

apt install iptables-persistent      #安装iptables持久存储插件
/etc/iptables/rules.v4      #iptbales规则存放文件
/etc/init.d/iptables-persistent save      #老版本debian系统
/etc/init.d/netfilter-persistent save      #新版本debian系统
附2.ipset集合
yum install ipset      #安装ipset

ipset create SETNAME TYPENAME    #新建一个集合,常用类型hash:net;
ipset add SETNAME ENTRY      #向集合内添加条目
ipset del SETNAME ENTRY      #删除集合内条目
ipset list [SETNAME]      #查看集合内容
ipset flush [SETNAME]      #清空条目,但集合还在
ipset destroy [SETNAME]      #删除所有集合
ipset save [SETNAME]      #保存到文件
ipset restore      #从文件恢复

#centos6
/etc/init.d/ipset save
#centos7
修改iptables服务文件,/usr/lib/systemd/system/iptables.service,使用ExecStartPre或Before实现;
#debian
apt install ipset-persistent   
/etc/init.d/netfilter-persistent save

附3.nf_conntrack模块

nf_conntrack是一个内核模块,用于跟踪一个连接的状态,iptbales的state模块则是直接使用nf_conntrack里记录的连接的状态来匹配用户定义的相关规则;
nf_conntrack会话表是有上限的,当会话数量超出上限会导致丢包,影响网络质量,严重时甚至导致网络不可用;

nf_conntrack模块常用命令:

cat /proc/sys/net/netfilter/nf_conntrack_count      #查看nf_conntrack表当前连接数         
cat /proc/sys/net/netfilter/nf_conntrack_max        #查看nf_conntrack表最大连接数,默认65535 
cat /proc/sys/net/netfilter/nf_conntrack_buckets      #查看存储conntrack条目的哈希表大小,文件只读,默认16384
cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established      #查看nf_conntrack表的TCP连接记录时间,默认432000秒(5天)
sysctl -a | grep nf_conntrack      #查看内核中nf_conntrack所有参数配置

如何判断会话表是否占满:

cat /var/log/messages|grep nf_conntrack 或 dmesg |grep nf_conntrack    #结果中存在nf_conntrack: table full, dropping packet错误即为占满;

会话表占满该如何处理:

1.重启iptables防火墙会自动清空会话表;
2.使用raw表,对特定流量不进行状态跟踪{NO_TRACK};
3.加大防火墙跟踪表的大小,优化对应的系统参数;

修改参数

计算公式:
对于 CONNTRACK_MAX,其计算公式:
CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (ARCH / 32)
以40G的64位操作系统为例,CONNTRACK_MAX = 64*1024*1024*1024/16384/2 = 1310720
对于大于 1G 内存的系统,默认的 CONNTRACK_MAX 是 65535。

对于 HASHSIZE,默认的有这样的转换关系:
CONNTRACK_MAX = HASHSIZE * 8
这表示每个链接列表里面平均有 8 个 conntrack 条目。其真正的计算公式如下:
HASHSIZE = CONNTRACK_MAX / 8 = RAMSIZE (in bytes) / 131072 / (ARCH / 32)
比如一个 64 位 40G 的机器可以存储 40*1024*1024*1024/131072/2 = 163840
对于大于 1G 内存的系统,默认的 HASHSIZE 是 8192。

通过sysctl命令进行修改{临时生效}:
$ sysctl -w net.netfilter.nf_conntrack_max=1048576
$ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600
通过sysctl.conf文件修改{永久生效}:
vi /etc/sysctl.conf  
net.netfilter.nf_conntrack_max=1048576
net.netfilter.nf_conntrack_tcp_timeout_established=3600  
$ sysctl -p #使生效

对于nf_conntrack_buckets的参数:
新建 /etc/modprobe.d//nf_conntrack.conf,添加以下内容,重新加载模块/重启系统生效:
options nf_conntrack hashsize=262144
posted @ 2020-06-10 23:41  Beavan  阅读(275)  评论(0编辑  收藏  举报