当前位置:  首页>> 技术小册>> Linux应该怎么学(中)

在早期的Linux系统中,默认使用的是iptables防火墙管理服务来配置防火墙。尽管新型的firewalld防火墙管理服务已经被投入使用多年,但是大量的企业在生产环境中依然出于各种原因而继续使用iptables。考虑到iptables在当前生产环境中还具有顽强的生命力,以及为了使大家在求职面试过程中被问到iptables的相关知识时能胸有成竹,刘遄老师觉得还是有必要在本书中好好地讲解一下这项技术。更何况前文也提到,各个防火墙管理工具的配置思路是一致的,在掌握了iptables后再学习其他防火墙管理工具时,也有借鉴意义。
8.2.1 策略与规则链
防火墙会从上至下的顺序来读取配置的策略规则,在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的行为(即放行或阻止)。如果在读取完所有的策略规则之后没有匹配项,就去执行默认的策略。一般而言,防火墙策略规则的设置有两种:一种是“通”(即放行),一种是“堵”(即阻止)。当防火墙的默认策略为拒绝时(堵),就要设置允许规则(通),否则谁都进不来;如果防火墙的默认策略为允许时,就要设置拒绝规则,否则谁都能进来,防火墙也就失去了防范的作用。
iptables服务把用于处理或过滤流量的策略条目称之为规则,多条规则可以组成一个规则链,而规则链则依据数据包处理位置的不同进行分类,具体如下:
在进行路由选择前处理数据包(PREROUTING);
处理流入的数据包(INPUT);
处理流出的数据包(OUTPUT);
处理转发的数据包(FORWARD);
在进行路由选择后处理数据包(POSTROUTING)。
一般来说,从内网向外网发送的流量一般都是可控且良性的,因此我们使用最多的就是INPUT规则链,该规则链可以增大黑客人员从外网入侵内网的难度。
比如在您居住的社区内,物业管理公司有两条规定:禁止小商小贩进入社区;各种车辆在进入社区时都要登记。显而易见,这两条规定应该是用于社区的正门的(流量必须经过的地方),而不是每家每户的防盗门上。根据前面提到的防火墙策略的匹配顺序,可能会存在多种情况。比如,来访人员是小商小贩,则直接会被物业公司的保安拒之门外,也就无需再对车辆进行登记。如果来访人员乘坐一辆汽车进入社区正门,则“禁止小商小贩进入社区”的第一条规则就没有被匹配到,因此按照顺序匹配第二条策略,即需要对车辆进行登记。如果是社区居民要进入正门,则这两条规定都不会匹配到,因此会执行默认的放行策略。
但是,仅有策略规则还不能保证社区的安全,保安还应该知道采用什么样的动作来处理这些匹配的流量,比如“允许”、“拒绝”、“登记”、“不理它”。这些动作对应到iptables服务的术语中分别是ACCEPT(允许流量通过)、REJECT(拒绝流量通过)、LOG(记录日志信息)、DROP(拒绝流量通过)。“允许流量通过”和“记录日志信息”都比较好理解,这里需要着重讲解的是REJECT和DROP的不同点。就DROP来说,它是直接将流量丢弃而且不响应;REJECT则会在拒绝流量后再回复一条“您的信息已经收到,但是被扔掉了”信息,从而让流量发送方清晰地看到数据被拒绝的响应信息。
我们来举一个例子,让各位读者更直观地理解这两个拒绝动作的不同之处。比如有一天您正在家里看电视,突然听到有人敲门,您透过防盗门的猫眼一看是推销商品的,便会在不需要的情况下开门并拒绝他们(REJECT)。但如果您看到的是债主带了十几个小弟来讨债,此时不仅要拒绝开门,还要默不作声,伪装成自己不在家的样子(DROP)。
当把Linux系统中的防火墙策略设置为REJECT拒绝动作后,流量发送方会看到端口不可达的响应:

  1. [root@linuxprobe ~]# ping -c 4192.168.10.10
  2. PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
  3. From 192.168.10.10 icmp_seq=1 Destination Port Unreachable
  4. From 192.168.10.10 icmp_seq=2 Destination Port Unreachable
  5. From 192.168.10.10 icmp_seq=3 Destination Port Unreachable
  6. From 192.168.10.10 icmp_seq=4 Destination Port Unreachable
  7. ---192.168.10.10 ping statistics ---
  8. 4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3002ms

而把Linux系统中的防火墙策略修改成DROP拒绝动作后,流量发送方会看到响应超时的提醒。但是流量发送方无法判断流量是被拒绝,还是接收方主机当前不在线:

  1. [root@linuxprobe ~]# ping -c 4192.168.10.10
  2. PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
  3. ---192.168.10.10 ping statistics ---
  4. 4 packets transmitted, 0 received, 100% packet loss, time 3000ms

8.2.2 iptables中基本的命令参数
iptables是一款基于命令行的防火墙策略管理工具,具有大量参数,学习难度较大。好在对于日常的防火墙策略配置来讲,大家无需深入了解诸如“四表五链”的理论概念,只需要掌握常用的参数并做到灵活搭配即可,这就足以应对日常工作了。
iptables命令可以根据流量的源地址、目的地址、传输协议、服务类型等信息进行匹配,一旦匹配成功,iptables就会根据策略规则所预设的动作来处理这些流量。另外,再次提醒一下,防火墙策略规则的匹配顺序是从上至下的,因此要把较为严格、优先级较高的策略规则放到前面,以免发生错误。表8-1总结归纳了常用的iptables命令参数。再次强调,我们无需死记硬背这些参数,只需借助下面的实验来理解掌握即可。

在iptables命令后添加-L参数查看已有的防火墙规则链:

  1. [root@linuxprobe ~]# iptables -L
  2. Chain INPUT (policy ACCEPT)
  3. target prot opt source destination
  4. ACCEPT all -- anywhere anywhere ctstate RELATED, ESTABLISHED
  5. ACCEPT all -- anywhere anywhere
  6. INPUT_direct all -- anywhere anywhere
  7. INPUT_ZONES_SOURCE all -- anywhere anywhere
  8. INPUT_ZONES all -- anywhere anywhere
  9. ACCEPT icmp -- anywhere anywhere
  10. REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
  11. ………………省略部分输出信息………………

在iptables命令后添加-F参数清空已有的防火墙规则链:

  1. [root@linuxprobe ~] # iptables -F
  2. [root@linuxprobe ~] # iptables -L
  3. Chain INPUT (policy ACCEPT)
  4. target prot opt source destination
  5. Chain FORWARD (policy ACCEPT)
  6. target prot opt source destination
  7. Chain OUTPUT (policy ACCEPT)
  8. target prot opt source destination
  9. ………………省略部分输出信息………………

把INPUT规则链的默认策略设置为拒绝:

  1. [root@linuxprobe ~]# iptables -P INPUT DROP
  2. [root@linuxprobe ~]# iptables -L
  3. Chain INPUT (policy DROP)
  4. target prot opt source destination
  5. …………省略部分输出信息………………

前文提到,防火墙策略规则的设置有两种:通和堵。当把INPUT链设置为默认拒绝后,就要在防火墙策略中写入允许策略了,否则所有到来的流量都会被拒绝掉。另外,需要注意的是,规则链的默认拒绝动作只能是DROP,而不能是REJECT。
向INPUT链中添加允许ICMP流量进入的策略规则:
在日常运维工作中,经常会使用ping命令来检查对方主机是否在线,而向防火墙的INPUT规则链中添加一条允许ICMP流量进入的策略规则就默认允许了这种ping命令检测行为。

  1. [root@linuxprobe ~]# iptables -I INPUT -p icmp -j ACCEPT
  2. [root@linuxprobe ~]# ping -c 4192.168.10.10
  3. PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
  4. 64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.156 ms
  5. 64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.117 ms
  6. 64 bytes from 192.168.10.10: icmp_seq=3 ttl=64 time=0.099 ms
  7. 64 bytes from 192.168.10.10: icmp_seq=4 ttl=64 time=0.090 ms
  8. ---192.168.10.10 ping statistics ---
  9. 4 packets transmitted, 4 received, 0% packet loss, time 2999ms
  10. rtt min/avg/max/mdev = 0.090/0.115/0.156/0.027 ms

删除INPUT规则链中刚刚加入的那条策略(允许ICMP流量),并把默认策略设置为允许:

  1. [root@linuxprobe ~]# iptables -D INPUT 1
  2. [root@linuxprobe ~]# iptables -P INPUT ACCEPT

将INPUT规则链设置为只允许指定网段的主机访问本机的22端口,拒绝来自其他所有主机的流量:

  1. [root@linuxprobe ~]# iptables -I INPUT -s 192.168.10.0/24-p tcp --dport 22-j
  2. ACCEPT
  3. [root@linuxprobe ~]# iptables -A INPUT -p tcp --dport 22-j REJECT
  4. [root@linuxprobe ~]# iptables -L
  5. Chain INPUT (policy ACCEPT)
  6. target prot opt source destination
  7. ACCEPT tcp --192.168.10.0/24 anywhere tcp dpt:ssh
  8. REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable
  9. ………………省略部分输出信息………………

再次重申,防火墙策略规则是按照从上到下的顺序匹配的,因此一定要把允许动作放到拒绝动作前面,否则所有的流量就将被拒绝掉,从而导致任何主机都无法访问我们的服务。另外,这里提到的22号端口是ssh服务使用的(有关ssh服务,请见下一章),刘遄老师先在这里挖坑,等大家学完第9章后可再验证这个实验的效果。
在设置完上述INPUT规则连之后,我们使用IP地址在192.168.10.0/24网段内的主机访问服务器(即前面提到的设置了INPUG规则链的主机)的22端口,效果如下:

  1. [root@Client A ~]# ssh 192.168.10.10
  2. The authenticity of host '192.168.10.10 (192.168.10.10)' can't be established.
  3. ECDSA key fingerprint is 70:3b:5d:37:96:7b:2e:a5:28:0d:7e:dc:47:6a:fe:5c.
  4. Are you sure you want to continue connecting (yes/no)? yes
  5. Warning: Permanently added '192.168.10.10' (ECDSA) to the list of known hosts.
  6. root@192.168.10.10's password: 此处输入对方主机的root管理员密码
  7. Last login: Sun Feb 12 01:50:252017
  8. [root@Client A ~]#

然后,我们再使用IP地址在192.168.20.0/24网段外的主机访问服务器的22端口,效果如下,就不会提示连接请求被拒绝了(Connection failed):

  1. [root@Client B ~]# ssh 192.168.10.10
  2. Connecting to 192.168.10.10:22...
  3. Could not connect to '192.168.10.10' (port 22): Connection failed.

向INPUT规则链中添加拒绝所有人访问本机12345端口的策略规则:

  1. [root@linuxprobe ~]# iptables -I INPUT -p tcp --dport 12345-j REJECT
  2. [root@linuxprobe ~]# iptables -I INPUT -p udp --dport 12345-j REJECT
  3. [root@linuxprobe ~]# iptables -L
  4. Chain INPUT (policy ACCEPT)
  5. target prot opt source destination
  6. REJECT udp -- anywhere anywhere udp dpt:italk reject-with icmp-port-unreachable
  7. REJECT tcp -- anywhere anywhere tcp dpt:italk reject-with icmp-port-unreachable
  8. ACCEPT tcp --192.168.10.0/24 anywhere tcp dpt:ssh
  9. REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable
  10. ………………省略部分输出信息………………

向INPUT规则链中添加拒绝192.168.10.5主机访问本机80端口(Web服务)的策略规则:

  1. [root@linuxprobe ~] # iptables -I INPUT -p tcp -s 192.168.10.5--dport 80-j REJECT
  2. [root@linuxprobe ~] # iptables -L
  3. Chain INPUT (policy ACCEPT)
  4. target prot opt source destination
  5. REJECT tcp --192.168.10.5 anywhere tcp dpt:http reject-with icmp-port-unreachable
  6. REJECT udp -- anywhere anywhere udp dpt:italk reject-with icmp-port-unreachable
  7. REJECT tcp -- anywhere anywhere tcp dpt:italk reject-with icmp-port-unreachable
  8. ACCEPT tcp --192.168.10.0/24 anywhere tcp dpt:ssh
  9. REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable
  10. ………………省略部分输出信息………………

向INPUT规则链中添加拒绝所有主机访问本机1000~1024端口的策略规则:

  1. [root@linuxprobe ~]# iptables -A INPUT -p tcp --dport 1000:1024-j REJECT
  2. [root@linuxprobe ~]# iptables -A INPUT -p udp --dport 1000:1024-j REJECT
  3. [root@linuxprobe ~]# iptables -L
  4. Chain INPUT (policy ACCEPT)
  5. target prot opt source destination
  6. REJECT tcp --192.168.10.5 anywhere tcp dpt:http reject-with icmp-port-unreachable
  7. REJECT udp -- anywhere anywhere udp dpt:italk reject-with icmp-port-unreachable
  8. REJECT tcp -- anywhere anywhere tcp dpt:italk reject-with icmp-port-unreachable
  9. ACCEPT tcp --192.168.10.0/24 anywhere tcp dpt:ssh
  10. REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable
  11. REJECT tcp -- anywhere anywhere tcp dpts:cadlock2:1024 reject-with icmp-port-
  12. unreachable
  13. REJECT udp -- anywhere anywhere udp dpts:cadlock2:1024 reject-with icmp-port-
  14. unreachable
  15. ………………省略部分输出信息………………

有关iptables命令的知识讲解到此就结束了,大家是不是意犹未尽?考虑到Linux防火墙的发展趋势,大家只要能把上面的实例吸收消化,就可以完全搞定日常的iptables配置工作了。但是请特别注意,使用iptables命令配置的防火墙规则默认会在系统下一次重启时失效,如果想让配置的防火墙策略永久生效,还要执行保存命令:

  1. [root@linuxprobe ~]# service iptables save
  2. iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]

该分类下的相关小册推荐: