Iptables
firewall 防火墙
- 从逻辑上讲,可以分为服务器防火墙和主机防火墙。网络防火墙和主机防火墙不存在冲突。
- 网络防火墙位于网络边界,如路由器或专用硬件设备。用于监控和控制进出网络的数据包,主要职责是在网络层过滤数据包,以保护网络免受攻击。(公司的防火墙就是一种网络防火墙)
- 主机防火墙安装在单个主机上,如常见的iptables和firewalld。用于保护该主机免受未经授权的网络访问,监控并控制进出主机的数据包,以防止未经授权的访问。
- 从物理上讲,防火墙可以分为硬件防火墙和软件防火墙。
- 硬件防火墙:在硬件级别实现部分防火墙功能,一部分功能仍需基于软件实现,性能高,成本高。
- 软件防火墙:应用软件处理逻辑运行于通用硬件平台之上的防火墙,性能低,成本低。
Linux防火墙体系主要工作在网络层,针对TCP/IP数据包实施过滤和限制,属于包过滤防火墙,并且基于内核编码的实现具有非常稳定的性能和高效率。
Iptables简述
iptables 是 Linux 系统中用于设置、维护和检查网络层数据包过滤规则表的工具。这些规则表定义了哪些数据包应该被允许通过,哪些应该被拒绝或丢弃。
- 封端口、IP
- 实现NAT功能
- 共享网络
- 端口映射(转发),IP映射
Iptables已被写入到Linux内核中,并且在Dcoker中提供了相当重要的服务。
Iptables相关概念:
- 表(table):存放链的容器,防火墙最大的概念。
- 链(chain):存放规则的容器
- 规则(policy):准许或拒绝规则,定义的是防火墙的通行规则
工作流详解: - 防火墙是层层过滤的,实际执行的规则顺序是从上到下,即Rule1到默认规则,不过这条规则是拒绝服务还是允许,都完成一次规则匹配。
- 规则匹配成功,即明确标识是DROP还是ACCEPT,数据包就不再向下匹配新的规则。
- 如果规则没有明确表示是阻止还是通过,也就是没有匹配该条规则,则继续向下匹配,直到匹配默认规则得到明确的DROP或ACCEPT。
- 防火墙默认规则是所有规则都匹配完成才会匹配的。
考虑到匹配规则是从上往下的,因此在设计防火墙规则的适合顺序十分重要。
在只允许一些特定的ip通过防火墙时,把filter-允许某些IP通过的规则放前边,Drop-禁止所有IP的规则放后边。
一、Iptables的四表五链
- 四表: filter、nat、raw、mangle
- 五链:
- INPUT:处理入站数据包
- OUTPUT:处理出站数据包
- FORWARD:处理转发数据包
- POSTROUTING链:在进行路由选择后处理数据包(对数据链进行源地址修改转换)
- PREROUTING链:在进行路由选择前处理数据包(做目标地址转换)
Tip:此处只介绍最常用的filter和Nat表!
1.filter表
实现防火墙功能,屏蔽或是准许IP端口。
- iptalbes默认操作表,不指定表制定规则时,操作的是filter表
- 真正负责主机防火墙功能的表(过滤流入流出主机的数据包)
链名 | 功能 |
---|---|
INPUT | 负责过滤所有目标地址是本机的数据包(是否准许外部数据包进入服务器) |
FORWARD | 负责转发流经主机的数据包,转发作用 |
OUTPUT | 负责处理所有源地址是本地的数据包(处理从本机发出的数据包) |
2.nat表
实现nat功能,共享网络(内外网服务器上网),端口映射和IP映射。
- 负责网络地址转换,即来源与目的IP地址的port的转换。
- 一般用于局域网共享上网或者特殊的端口转换服务相关。
1.用于企业路由(zebra)或网关(iptables),共享上网(POSTROUTING)
2.做内部外部IP地址一对一映射(dmz),硬件防火墙映射IP到内部服务器,ftp服务(PREROUTING)
3.WEB,单个端口的映射,直接映射80端口,这个表定义了3个链,nat功能相当于网络的acl控制。和网络交换机acl类似。
链名 | 功能 |
---|---|
OUTPUT | 负责过滤所有目标地址是本机的数据包(是否准许外部数据包进入服务器) |
PREROUTING | 负责转发流经主机的数据包,转发作用 |
POSTROUTING | 负责处理所有源地址是本地的数据包(处理从本机发出的数据包) |
3.raw表
raw 表用于处理连接跟踪(connection tracking)的例外情况,即那些不应该被连接跟踪机制处理的流量。raw 表通常用于配置不需要进行连接跟踪的流量,比如某些类型的初始数据包或特定类型的流量,以避免不必要的资源消耗,例如 ICMP 请求,可以将其标记为 raw 类型,以提高处理效率。
链名 | 功能 |
---|---|
OUTPUT | 用于处理从本地系统发出的流量。 |
PREROUTING | 用于处理到达接口之前的流量。 |
4. mangle表
mangle 表用于修改数据包的内容或其元数据,而不直接决定数据包的命运(如接受或丢弃)。mangle 表主要用于数据包的标记、修改 TTL(生存时间)值、修改标志位等操作。它可以用来做一些高级的网络功能,比如负载均衡、QoS(Quality of Service)配置、路由选择等。
链名 | 功能 |
---|---|
PREROUTING | 用于处理到达接口之前的流量。 |
INPUT | 用于处理到达本地系统接口的流量。 |
FORWARD | 用于处理转发的流量。 |
OUTPUT | 用于处理从本地系统发出的流量。 |
POSTROUTING | 用于处理离开接口之后的流量。 |
5.数据包的流通过程
- 请求到达服务器前先经过PREROUTING链,进行规则匹配,决定是否访问本机。
- 如果数据包目标地址不是本机,需要经过FORWARD链进行转发,最后经过POSTROUTING链离开。
- 如果数据包的目标地址是本机,需要经过INPUT链上制定的规则,符合的才能进入服务系统,不符合的则经过OUTPUT链离开。
二、快速上手
iptables 命令的基本语法如下:
iptables [-t 表名] 命令 [选项] [链名] [条件] [-j 目标]
- -t 表名:指定要操作的表,默认为 filter 表。iptables 有几个内置表,如 filter、nat、mangle、raw、security 等。
- 命令:指定要执行的操作,如 -A(追加)、-D(删除)、-L(列出规则)等。
- 选项:一些命令可能需要额外的选项来指定操作的具体细节。
- 链名:指定规则所在的链,如 INPUT、OUTPUT、FORWARD 等,或是自定义的链。
- 条件:用于匹配数据包的条件,如源地址、目的地址、端口号等。
- -j 目标:指定匹配到的数据包的处理方式,如 ACCEPT(接受)、DROP(丢弃)、REJECT(拒绝)等。
具体命令详细可以使用iptalbes --help查看,此处只列举常用命令。
1. 查看规则
查看所有 iptables 规则:
iptables -nL
解析: -n 选项告诉iptables不要对地址进行 DNS 解析,而 -L 选项则是列出所有链中的规则。
查看指定表的规则:
iptables -t 表名 -nL
2. 规则详细
根据配置好的指定规则匹配每个流经此处的数据包。如果匹配成功,则由规则后面指定的处理动作进行处理,如果该条规则匹配失败,则数据包流入下一规则进行匹配,直至所有规则匹配失败,最后按照该链的默认规则处理。
- target : 处理动作,该条规则匹配成功后按照指定动作进行处理。
- ACCEPT:允许数据包通过
- DROP:丢弃数据包,不给任何回应信息,客户端会收到Connect time out,连接超时。
- REJECT:拒绝数据包,给请求端一个响应的信息,客户端会收到unreachable,请求不可达。
- SNAT:源地址转换,根据指定的条件,将数据包源IP进行更改转发,可以解决内网用户用同一个公网地址上网的问题。
- MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip。
- DNAT:目标地址转换,将数据包的目标地址变更,如访问Docker服务时,目标地址会由主机变更到Docker容器。
- REDIRECT:在本机做端口映射
- LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配
- prot: 通信协议,例如TCP、UDP、ICMP。
- opt: 选项,通常在建立规则的时候可以指定。
- source: 源地址,指的是数据包的来源IP。
- destination: 目标地址,指的是数据包想要发送的目的地。
3. 添加规则
Tip: 规则的匹配是从上到下的,哪个先匹配就执行哪个,后面就算有一模一样的也不会执行,因此在设计规则的时候顺序是十分重要的!!!
添加规则:
iptables -t 表名 -A 链名 匹配条件 -j 处理动作
例如:
允许源地址192.168.10.152的数据包通过:
iptables -t filter -I INPUT -s 192.168.10.152 -j ACCEPT
禁止所有的数据包,不接收任何网络访问:
iptables -t filter -I INPUT -j ACCEPT
设置指定链的默认策略:
iptables -t nat -P FORWARD ACCEPT
根据索引删除指定链的规则:
iptables -t nat -D FORWARD 1
iptables命令使用iptables开头,以下是一些常用参数:
参数 | 作用 |
---|---|
-t [表名] | 指定要操作的表,默认是filter表 |
-A [链名] | 指定要操作的链,append,在该链的末尾添加规则 |
-I [链名] | 指定要操作的链,Insert,在该链的首部添加规则 |
-D [链名] | 指定要操作的链,delete,根据索引删除规则 |
-s [源地址] | source,设置数据包的源地址要求 |
-d [目标地址] | destination,设置数据包的目标地址要求 |
-p [通信协议] | prot,设置数据包的通信协议要求 |
- -dport [目标地址端口] | destination port,设置目标地址的端口要求 |
-j [处理动作] | jump,设置数据包匹配要求时的处理动作 |
其他参数可以通过iptables --help 查看哈,太多了就不列举了。
关于设置防火墙策略:
白名单:把指定链的默认策略设置为DROP,只设置允许数据包通过的规则,实现只有匹配规则的数据包才能进行通信,其余通信将被拒绝或是屏蔽。
黑名单:把链的默认策略设置为ACCEPT,只设置禁止数据包通过的规则,实现只有匹配规则的数据包不能够进行通信,其余通信将会允许通过。
Tip:iptables重启的时候默认会清空规则,可以要做好相应的重启策略,对应白名单,通常不建议更改链的默认策略为DROP,一旦规则清空,所有的数据包都不能够通过,包括自己,如果是服务器,那么将会无法进行ssh远程连接。因此可以利用从上到下的匹配规则,白名单可以在最后一条规则设置为拒绝所有数据包。
关于设置一连串的ip地址:
- –src-range: 取代-s参数,可以设置一串连续的ip,例如 --src-range 192.168.1.127-192.168.1.146
- –dst-range: 取代-d参数,可以设置一串连续的ip,例如 --dst-range 192.168.1.127-192.168.1.146
4. 自定义链
除了iptables提供的链,我们可以通过自定义链管理更多的规则,值得一提的是自定义链并不能直接使用和删除。需要被默认的链引用才能使用,只有当链中没有规则并且没有被引用时才能进行删除。
创建自定义链: iptables -t filter -N NEW_CHAIN
在默认链中引用自定义链: iptables -t filter -I INPUT -j NEW_CHAIN
重命名自定义链: iptables -E NEW_CHAIN RENAME_CHIAN
删除一个符合规则的自定义链: iptables -X RENAME_CHAIN
三、关于iptables和docker
1. 背景
在实际开发过程中,Docker服务默认使用iptables作为端口、地址转发和映射,并且Docker桥接模式使用的Docker0网卡在iptables中不受常用的filter表下的INPUT链控制,因此做好Docker服务的安全策略十分必要。
- 外部网络在访问Docker容器服务时,先通过iptables中的NAT表的PREROUTING链,Docker会在iptables中添加转发规则。因此目标地址为宿主机,端口为映射端口的数据包,会被FORWARD进行转发。
- 经过NAT的DNAT(目标地址转换)操作后,目标地址以及端口可能发生改变,因此不再经过FILTER表的INPUT链(通常在此处设置规则拦截数据包),而是由FILTER表的FORWARD链处理。
- 最后会在FILTER表中还会经过Docker创建的自定义链处理,最后发送到对应的容器当中。
2. 解决方案
根据上述的描述,iptables设置在FILTER表的INPUT链中的规则不在能够限制Docker服务的访问,除了对上述背景中提到的相关链进行修改,Docker提供了一条DOCKER-USER的链供用户进行规则设置,因此需要在Filter表中的DOCKER-USER链进行规则设定。
Docker服务在启动的时候会自动在iptables中创建相应的链,并设立规则。
iptables -I DOCKER-USER -p tcp --dport 80 -j DROP
iptables -I DOCKER-USER -s 10.10.181.201 -p tcp --dport 80 -j ACCEPT
上述规则只允许源地址为 10.10.181.201 ,目标端口为80的数据包访问Docker服务,其余目标端口为80,协议类型为TCP的数据包将会被屏蔽。
在实际开发过程中,情况可能更复杂,可以根据iptables中链的转发跳转情况进行设定,可能会存在数据包经过NAT表的转发后目标地址和端口发生改变的情况,因此DOCKER-USER表规则的设置应该视情况而定!!!
3. Demo
生产场景下希望Docker容器服务只能由指定的服务器访问,因此需要在iptables中添加一些规则。
小技巧:
iptables -t 表名 -I 链名 -j LOG --log-prefix=“logNamePrefix”
添加一条日志规则,当数据包通过这条规则的时候会记录到日志中,并以logNamePrefix为前缀。
日志默认存放路径:/var/log/messages
上文提到已经提及数据包流转顺序,不再强调哈。
下边介绍外部是如何访问Docker服务的。
NAT表的PREROUTING链:
- 数据包经过LOG规则会被记录,其余的自定义链只需关注DOCKER这条即可(其余两条规则为empty)。
- DOCKER这条自定义链作为规则被引用,ADDRTYPE match dst-type LOCAL表示只有目标地址为本机相关的才符合规则进入自定义链中。
NAT表的DOCKER链:
- 该链为Docker服务创建的自定义链,会根据容器启动/创建时的指定参数进行配置。
- 只有目标地址为本机相关,才能进入这条链中进行匹配。
例如: 第二条规则的匹配含义。
将通信协议为tcp且目标端口为8443的的数据包进行DNAT(目标地址转换),目标地址变换为172.17.0.2,目标端口变换为443
FILTER表的FORWARD链:
LOG规则顺序插入错误了,应该在第一条哈。 and 只关注第一条DOCKER-USER的自定义链就好
- DOCKER-USER链为docker预留给用户进行修改编辑的链,用户自定义网络配置可以在这里实现。
FILTER表的DOCKER-USER链:
- 此处设置相应的规则,因为生产环境地址保密哈.
- 172.17.0.x通常为桥接模式下Docker容器的内部地址,不只要允许外部访问,还要允许内部相应。
/var/log/messages文件相关内容,有兴趣的可以研究一下数据包流动情况。
具体问题具体分析,配置不一样的可能需要做相应更改,以上仅作参照。