Netfilter/iptables模块有两部分组成:
Netfilter框架以及iptables,iptables又分为iptables(内核空间)和iptables命令行工具(用户空间);
Netfilter/iptables模块 在一般使用者眼里简称为iptables,但其实在相关开发者眼里更倾向于叫作Netfilter,从项目官网地址也看得出来: https://netfilter.org/
作用
用于数据包处理,比如:报文的转发、过滤、修改,网络地址转换等功能,是一种软件防火墙。
iptables基本原理 基本工作流程基本工作流程图
数据包沿着链传输,iptables有5个链:PREROUTING, INPUT, FORWORD, OUTPUT, POSTROUTING,可以想象成5个关卡,每个关卡都有很多规则,也可能没有规则。
工作流程流程如下:
1、当一个数据包进入网卡后,它会先进入PREROUTING,然后根据目的地址进行路由决策,如果目的地址是本机,则走INPUT,不是本机则走FORWARD,然后再走POSTROUTING转出去。
2、进入INPUT的数据包会转给本地进程,进程处理后,会发送新的数据包,走OUTPUT,然后经过POSTROUTING转出去。
3、当然上面的过程每经过一个链,都要按照链中的规则顺序来匹配链中的规则,只要遇到一个匹配的规则就按照这个规则进行处理,后面的规则对这个数据就不再起作用。
单的规则添加 只有本地socket是用户态,其余都是内核处理。平时我们加iptables规则,就是加到各个链中的,我们创建一个容器进行测试,容器中我已经安装好了iptables,直接使用iptables命令即可:
#首先启动一个容器 [root@kube-master ~]# docker run -itd --name "cos8_test" --cap-add=NET_ADMIN centos:base /bin/bash bd0c29186387b01ae64514050b3b4b804babc988f3dbc52c0cfe6eeac115d1b2注:要修改容器网络,容器启动时需加上 --cap-add=NET_ADMIN,不然容器中执行iptables命令会报错:
(nf_tables): Could not fetch rule set generation id: Permission denied (you must be root)
查看iptables规则,可以看到当前没有任何策略
[root@kube-master ~]# docker ps | grep cos8 bd0c29186387 centos:base "/bin/bash" 21 hours ago Up 21 hours cos8_test [root@kube-master ~]# docker exec -it bd0 bash [root@bd0c29186387 /]# [root@bd0c29186387 /]# 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创建一个规则:拒绝所有访问本机80端口的tcp数据包。
[root@bd0c29186387 /]# iptables -A INPUT -p tcp --dport 80 -j DROP [root@bd0c29186387 /]# [root@bd0c29186387 /]# iptables -nL Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 Chain FORWARD (policy ACCEPT) target prot opt source destination DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 Chain OUTPUT (policy ACCEPT) target prot opt source destination DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80这里有个小插曲:可以看到我只在INPUT链中添加了规则,但是怎么FORWARD和OUTPUT链中也有这条规则,随后我手动删了INPUT链中的规则,然后FORWARD和OUTPUT链中的规则也随之消失了,此容器的OS版本和内核信息如下
[root@bd0c29186387 /]# cat /etc/redhat-release CentOS Linux release 8.2.2004 (Core) [root@bd0c29186387 /]# [root@bd0c29186387 /]# uname -a Linux bd0c29186387 3.10.0-1127.13.1.el7.x86_64 #1 SMP Tue Jun 23 15:46:38 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux之前没用过centos8,考虑到可能是OS更新了netfilter模块,于是换成了一个centos7.8.2003的容器测试了一下,发现添加规则是符合预期的,如下
[root@kube-master /]# docker run -itd --name "cos7" --cap-add=NET_ADMIN centos7:base /bin/bash c951c0a9d34d8e43a56e43872294ab5ab6a1504b365721238178de134e8d3bde [root@kube-master /]# [root@kube-master /]# docker exec -it cos7 bash [root@c951c0a9d34d /]# [root@c951c0a9d34d /]# 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 [root@c951c0a9d34d /]# [root@c951c0a9d34d /]# iptables -A INPUT -p tcp --dport 80 -j DROP [root@c951c0a9d34d /]# [root@c951c0a9d34d /]# iptables -nL Chain INPUT (policy ACCEPT) target prot opt source destination DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination拒绝可以使用DROP,也可以使用REJECT关键字,DROP不会给客户端返回任何信息,所以客户端看到的情况就是连接超时,很难判断是防火墙原因还是网络设备故障等原因。
而REJECT则明确返回给客户端一个拒绝的信息,客户端会知道我是被防火墙拒绝了。
可根据场景使用,REJECT更适合调试,DROP抗攻击上面更安全些。
后面使用centos7的容器作为测试,先不管centos8更新了啥。
四表五链上面我添加的规则命令如下:
iptables -A INPUT -p tcp --dport 80 -j DROP但这只是简写后的,稍微写全些如下,其实还可以更全些,暂不说明。
iptables -t filter -A INPUT -s 0.0.0.0/0 -p tcp -d 0.0.0.0/0 --dport 80 -j DROP-t : 指定表,这里是filter表,规则会添加到filter表中。
-s : 指定源地址,0.0.0.0/0是指所有IP。
-d : 指定目的地址。
--dport : 指定目的端口。
-j : 指定处理动作,这里是DROP,也就是丢弃。
表的概念
上面提到了filter表,那什么是表呢?