纸上得来终觉浅,绝知此事要躬行。
iptables
是运行在用户空间的应用软件,通过控制 Linux
内核 netfilter
模块,来管理网络数据包的处理和转发。在大部分 Linux
发行版中,可以通过手册页 或 man iptables
获取用户手册。通常 iptables
需要内核模块支持才能运行,此处相应的内核模块通常是 Xtables
。
报文在经过 iptables
的链时会匹配链中的规则,遇到匹配的规则时就执行对应的动作,如果链中的规则都无法匹配到当前报文,则使用链的默认策略(默认动作),链的默认策略通常设置为 ACCEPT
或者 DROP
。
- 当链的默认策略设置为
ACCEPT
时(黑名单机制)- 如果对应的链中没有配置任何规则,就表示接受所有的报文
- 如果对应的链中存在规则,但是这些规则没有匹配到报文,报文还是会被接受
- 对应链中的动作应该设置为 DROP 或者 REJECT
- 当链的默认策略设置为
DROP
时(白名单机制)- 如果对应的链中没有配置任何规则,就表示拒绝所有报文
- 如果对应的链中存在规则,但是这些规则没有匹配到报文,报文还是会被拒绝
- 对应链中的规则对应的动作应该为 ACCEPT
我们就来做一个简单的白名单,只放行被规则匹配到的报文,其他报文一律拒绝。
# 清空防火墙规则
$ sudo iptables -t filter -F INPUT
# 设置默认规则为DROP,拒绝所有请求
$ sudo iptables -t filter -P INPUT DROP
# 设置白名单防火墙机制,开放指定端口
$ sudo iptables -t filter -I INPUT -p tcp --dport 22 -j ACCEPT
$ sudo iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT
在当前 ssh
远程工具中执行 iptables -F
命令后,由于 INPUT
链中已经不存在任何规则,所有报文都被拒绝了,包括当前的 ssh
远程连接。
这就是默认策略设置为 DROP
的缺点,在对应的链中没有设置任何规则时,这样使用默认策略为 DROP
是非常不明智的。所以,我们如果想要使用白名单机制,最好将链的默认策略保持为 ACCEPT
,然后将拒绝所有请求这条规则放在链的尾部,将放行规则放在前面,这样做,既能实现白名单机制,又能保证在规则被清空时,管理员还有机会连接到主机
# 清空防火墙规则
$ sudo iptables -t filter -F INPUT
# 设置默认规则为ACCEPT,接受所有请求
$ sudo iptables -t filter -P INPUT ACCEPT
# 设置白名单防火墙机制,开放指定端口
$ sudo iptables -t filter -I INPUT -p tcp --dport 22 -j ACCEPT
$ sudo iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT
# 拒绝所有请求规则放在链的尾部
$ sudo iptables -t filter -A INPUT -j REJECT
既将 INPUT
链的默认策略设置为了 ACCEPT
,同时又使用了白名单机制,因为如果报文符合放行条件,则会被前面的放行规则匹配到,如果报文不符合放行条件,则会被最后一条拒绝规则匹配到,此刻,即使我们误操作,执行了 iptables -F
操作,也能保证管理员能够远程到主机上进行维护,因为默认策略仍然是 ACCEPT
。