防火墙
防火墙是基于安全规则来监视和控制传入和传出网络流量的网络安全系统。该计算机流入流出的所有网络通信均要经过此防火墙。防火墙对流经它的网络通信进行扫描,这样能够过滤掉一些攻击,以免其在目标计算机上被执行。防火墙还可以关闭不使用的端口。而且它还能禁止特定端口的流出通信,封锁特洛伊木马。最后,它可以禁止来自特殊站点的访问,从而防止来自不明入侵者的所有通信。
firewalld 与 iptables 都是 linux 中防火墙的管理程序,但其实其角色主要为对于防火墙策略的管理,真正的防火墙执行者是位于内核中的netfilter。
链的概念
iptables开启后,数据报文从进入服务器到出来会经过5道关卡,分别为Preouting(路由前),input(输入),outing(输出),Forward(转发),Postrouting(路由后);
每一道关卡中有多个规则,数据报文必须按顺序一个一个匹配这些规则,这些规则串起来就像一条链,所以我们把这些关卡都叫“链”;
- INPUT链:当接收到防火墙本机地址的数据包(入站)时,应用此链中的规则;
- OUTPUT链:当防火墙本机向外发送数据包(出站)时,应用此链中的规则;
- FORWARD链:当接收到需要通过防火墙发送给其他地址的数据包(转发)时,应用此链中的规则
PREROUTING链:(互联网进入局域网)在对数据包作路由选择之前,应用此链中的规则,如DNAT;
POSTROUTING链:(局域网出互联网)在对数据包作路由选择之后,应用此链中的规则,如SNAT。
其中INPUT,OUTPUT链更多的应用在“主机防火墙”中,即主要针对服务器本机进出数据的安全控制;而FORWARD,PREROUTING,POSTROUTIN链更多的应用在“网络防火墙”中,特别是防火墙服务器作为网关使用时的情况。
表的概念
每一条链上有多条规则,但有些规则的作用(功能)很相似,多条具有相同功能的规则在一起就组成了一个“表”,iptables提供了四种表;
filter表:主要用于对数据包进行过滤,更具具体的规则决定是否放行该数据包(如DROP,ACCEPT,REJECT,LOG),所谓的防火墙其实基本上是这张表上的过滤规则,对应内核模块iptables_filter;
nat表:network address translation,网络地址转换功能,主要用于修改数据包的IP地址,端口号等信息(网络地址转换,如SNAT,DNAT,MASQUERADE,REDIRECT)。属于一流的包(因为包的大小限制导致数据可能会被分成多个数据包)只会经过这个表一次,如果第一个包被允许做NAT或Masuqeraded,那么余下的包都自动地被做相同的操作,也就是说,余下的包不会在通过这个表。对应内核模块iptables nat;
mangle表:拆解报文,做出修改,并重新封装,主要用于修改数据包的TOS(Type Of Service,服务类型),TTL指数以及为数据包设置Mark标记,以实现Qos(Quality Of Service,服务质量)调整以及策略路由等应用,优于需要相应的路由设备支持,因此应用并不广泛。对应内核模块iptables_mangle;
raw表:是自1.2.9以后版本的iptables新增的表,主要用于决定数据包是否被状态跟踪机制处理,在匹配数据包时,raw表的规则要优先于其他表,对应内核模块iptables_raw。 最终我们定义的防火墙规则,都会添加到这四张表中的一张表。
表链关系
五条链(即五个关卡),并不是每条链路都能应用所有类型的表,事实上除了Output链能同时有四种表,其他链都只有两种或三种表;
实际上无论在那条链上,raw表永远在mangle表上边,而managle表永远在nat表上边,nat表有永远在filter表上边,这表明各表之间是有匹配顺序的。 因为数据报文必须按顺序匹配每条链上的一个一个规则,但其实同一类(即属于同同一种表)的规则是放在一起的,不同类的规则不会交叉着放,按上边的规律,每条链上各个表被匹配的顺序为:raw—>mangle—>nat—>filter。
最终我们定义的防火墙规则,都会添加到这四张表中的其中一张表中,所以我们实际操作是对“表”进行操作的,所以反过来说,每种表都能用于那些链:
表名 | 能应用的链 |
---|---|
raw | prerouting、output |
mangle | prerouting、input、forward、output、postrouting |
nat | prerouting、input(仅centos7)、output、postrouting |
filter | input、forward、output |
iptables配置
在了解清楚iptables的工作原理和每个表以及链的作用之后,我们就可以根据其特点进行针对性的配置。
iptables 的基本语法命令格式
iptables [-t 表名] 管理选项 [链名] [匹配条件] [-j 控制类型]
表名
、链名
:指定iptables
命令所操作的表
和链
,未指定表名时将默认使用filter
表;管理选项
:表示iptables
规则的操作方式,比如:插入
、增加
、删除
、查看
等;匹配条件
:指定要处理的数据包的特征,不符合指定条件的数据包不处理;控制类型
:指数据包的处理方式,比如:允许accept
、拒绝reject
、丢弃drop
、日志LOG
等;
iptables 命令的常用管理选项
-A:在指定链的末尾添加一条新的规则
-D:删除指定链中的某一条规则,可删除指定序号或具体内容
-I:在指定链中插入一条新规则,未指定序号时默认作为第一条规则
-R:修改、替换指定链中的某一条规则,可指定规则序号或具体内容
-L:列出指定链中所有的规则,未指定链名,则列出表中的所有链
-F:清空指定链中所有的规则,未指定链名,则清空表中的所有链
-P:设置指定链的默认策略
-n:使用数字形式显示输出结果
-v:查看规则列表时显示详细的信息
-h:查看命令帮助信息
--line-numbers:查看规则列表时,同时显示规则在链中的顺序号
Docker防火墙
Docker链
Docker环境下,Iptables规则的处理顺序:
Docker利用Linux iptables特性,会在PREROUTING链路创建DOCKER子链,运行 docker run -d -p 27111:80 nginx
时,会在DOCKER链 nat表上做转发。如图所示:
会把27111端口的请求转发到 172.17.0.11:80, 而172.17.0.11:80就是nginx container 的网络。( docker是通过创建docker0虚拟网卡然后通过veth pair绑定到宿主机网卡)
一个完整的访问docker bridge container 服务网络请求为:
- 请求打到PREROUTING链,PREROUTING nat表做转发到docker container的网络里
- 请求经过FORWARD链,进入container服务
- 请求从container出来后还会走FORWARD链
- 走POSTROUTING链离开
所以INPUT链路的过滤规则无法约束到docker bridge模式的容器服务,就是因为docker 桥模式是在PREROUTING链路做转发。
Docker官方文档提供DOCKER-USER链路来做辅助防火墙,DOCKER-USE链是挂载在FORWARD链上的子链,可以在DOCKER-USE做过滤规则。
Docker的iptables配置
# 查询
iptables -L DOCKER-USER -n --line-number
# 删除
iptables -D DOCKER-USER 序号
# 新增拦截
iptables -I DOCKER-USER -p tcp --dport 5601 -j DROP
# 新增放行
iptables -I DOCKER-USER -s 192.168.4.157 -p tcp --dport 5601 -j ACCEPT
iptables -I DOCKER-USER -s 192.168.42.0/24 -p tcp --dport 5601 -j ACCEPT
Docker的firewalld配置
Docker防火墙使用的是底层iptables,封装后的firewalld默认不生效,若是想要使用firewalld,须要作如下调整:
让firewalld移除DOCKER-USER并新建一个
# Removing DOCKER-USER CHAIN (it won't exist at first)
firewall-cmd --permanent --direct --remove-chain ipv4 filter DOCKER-USER
# Flush rules from DOCKER-USER chain (again, these won't exist at first; firewalld seems to remember these even if the chain is gone)
firewall-cmd --permanent --direct --remove-rules ipv4 filter DOCKER-USER
# Add the DOCKER-USER chain to firewalld
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER
加上你想要的规则,注意reject放在最后
## allows incoming from docker
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -i docker0 -j ACCEPT -m comment --comment "allows incoming from docker"
## allows docker to eth0
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -i docker0 -o eth0 -j ACCEPT
## allows docker containers to connect to the outside world
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "allows docker containers to connect to the outside world"
## allow internal docker communication
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -s 172.17.0.0/16 -j RETURN
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -s 192.168.4.157 -p tcp --dport 5601 -j ACCEPT
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 10 -p tcp --dport 5601 -j DROP
## 你能够直接允許來自特定 IP 的全部流量
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -s 61.222.3.133/32 -j ACCEPT
## reject all other traffic
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 100 -j REJECT --reject-with icmp-host-unreachable
## 删除规则
firewall-cmd --permanent --direct --remove-rule ipv4 filter DOCKER-USER 0 -s 61.222.3.133/32 -j ACCEPT
配置完毕能在文件 /etc/firewalld/direct.xml
中看到规则配置
最后reload,并经过iptables -L确认是否正确生效
firewall-cmd --reload
iptables -L DOCKER-USER