防火墙之Iptables与Firewalld

防火墙

  • 在REHL7系统中,firewalld防火墙取代了iptables防火墙
  • iptables与firewalld都不是真正的防火墙,它们都只是用来定义防火墙策略的防火墙管理工具或一种服务
  • iptabeles服务会把配置好的防火墙策略交由内核层面的netfilter网络过滤器处理
  • firewalld服务则是把配置好的防火墙策略交由内核层面的nftables包过滤框架来处理

Iptables

策略与规则链

  • 防火墙会从上至下的顺序来读取配置的策略规则,在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的行为(即放行或阻止)
  • 如果在读取完所有的策略规则之后没有匹配项,就去执行默认的策略
  • 一般而言,防火墙策略规则的设置有两种:一种是“通”(即放行),一种是“堵”(即阻止)
  • 当防火墙的默认策略为拒绝时(堵),就要设置允许规则(通),否则谁都进不来;如果防火墙的默认策略为允许时,就要设置拒绝规则,否则谁都能进来,防火墙也就失去了防范的作用

iptables服务把用于处理或过滤流量的策略条目称之为规则,多条规则可以组成一个规则链,而规则链则依据数据包处理位置的不同进行分类,具体如下:

在进行路由选择前处理数据包(PREROUTING)

处理流入的数据包(INPUT)

处理流出的数据包(OUTPUT)

处理转发的数据包(FORWARD)

在进行路由选择后处理数据包(POSTROUTING)

iptables常用参数及作用

参数 作用
-P 设置默认策略
-F 清空规则链
-L 查看规则链
-A 在规则链的末尾添加新的规则
-I num 在规则链的头部加入新规则
-D num 删除某一条规则
-s 匹配来源于地址IP/MASK,加叹号 “!” 表示除此IP
-d 匹配目标地址
-i 网卡名称 匹配从这块网卡流入的数据
-o 网卡名称 匹配从这块网卡流出的数据
-p 匹配协议,如TCP、UDP、ICMP
–dport num 匹配目标端口号
–sport num 匹配来源端口号

iptables实验

  1. 查看已有的防火墙规则链

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # iptables -L
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
    ACCEPT all -- anywhere anywhere
    INPUT_direct all -- anywhere anywhere
    INPUT_ZONES_SOURCE all -- anywhere anywhere
    INPUT_ZONES all -- anywhere anywhere
    ACCEPT icmp -- anywhere anywhere
    REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
    ......
  2. 清空已有的防火墙规则链

    1
    2
    3
    4
    5
    # iptables -F
    # iptables -L
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ......
  3. 把INPUT规则链的默认策略设置为拒绝(DROP)

    1
    2
    3
    4
    5
    # iptables -P INPUT DROP
    # iptables -L
    Chain INPUT (policy DROP)
    target prot opt source destination
    ......

    设置为允许

    1
    2
    3
    4
    5
    # iptables -P INPUT ACCEPT
    # iptables -L
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ......
  4. 向INPUT链中添加允许ICMP流量进入的策略规则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # iptables -I INPUT -p icmp -j ACCEPT
    # ping -c 4 192.168.40.131
    PING 192.168.40.131 (192.168.40.131) 56(84) bytes of data.
    64 bytes from 192.168.40.131: icmp_seq=1 ttl=64 time=0.219 ms
    64 bytes from 192.168.40.131: icmp_seq=2 ttl=64 time=0.047 ms
    64 bytes from 192.168.40.131: icmp_seq=3 ttl=64 time=0.043 ms
    64 bytes from 192.168.40.131: icmp_seq=4 ttl=64 time=0.105 ms

    --- 192.168.40.131 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3003ms
    rtt min/avg/max/mdev = 0.043/0.103/0.219/0.071 ms
  5. 将INPUT规则链设置为只允许指定网段的主机访问本机的22端口,拒绝来自其他所有主机的流量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # iptables -I INPUT -s 192.168.40.0/24 -p tcp --dport 22 -j ACCEPT
    # iptables -A INPUT -p tcp --dport 22 -j REJECT
    # iptables -L
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    ACCEPT tcp -- 192.168.40.0/24 anywhere tcp dpt:ssh
    ACCEPT icmp -- anywhere anywhere
    REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable
    ......

    测试:用192.168.40.0/24网段的IP地址访问服务器的22端口(ssh服务)

    1
    2
    3
    4
    5
    6
    7
    # ssh 192.168.40.131
    The authenticity of host '192.168.40.131 (192.168.40.131)' can't be established.
    ECDSA key fingerprint is 1f:b2:22:cb:dd:25:d5:4b:ff:99:77:6a:27:16:76:2d.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '192.168.40.131' (ECDSA) to the list of known hosts.
    root@192.168.40.131's password:
    Last login: Fri Aug 30 02:08:17 2019
  6. 向INPUT规则链中添加拒绝所有人访问本机12345端口的策略规则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # iptables -I INPUT -p tcp --dport 12345 -j REJECT
    # iptables -I INPUT -p udp --dport 12345 -j REJECT
    # iptables -L
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    REJECT udp -- anywhere anywhere udp dpt:italk reject-with icmp-port-unreachable
    REJECT tcp -- anywhere anywhere tcp dpt:italk reject-with icmp-port-unreachable
    ACCEPT tcp -- 192.168.40.0/24 anywhere tcp dpt:ssh
    ACCEPT icmp -- anywhere anywhere
    REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable
    ......
  7. 向INPUT规则链中添加拒绝192.168.10.5主机访问本机80端口(Web服务)的策略规则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # iptables -I INPUT -p tcp -s 192.168.40.5 --dport 80 -j REJECT
    # iptables -L
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    REJECT tcp -- 192.168.40.5 anywhere tcp dpt:http reject-with icmp-port-unreachable
    REJECT udp -- anywhere anywhere udp dpt:italk reject-with icmp-port-unreachable
    REJECT tcp -- anywhere anywhere tcp dpt:italk reject-with icmp-port-unreachable
    ACCEPT tcp -- 192.168.40.0/24 anywhere tcp dpt:ssh
    ACCEPT icmp -- anywhere anywhere
    REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable
    ......
  8. 向INPUT规则链中添加拒绝所有主机访问本机1000~1024端口的策略规则

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # iptables -A INPUT -p tcp --dport 1000:1024 -j REJECT
    # iptables -A INPUT -p udp --dport 1000:1024 -j REJECT
    # iptables -L
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    REJECT tcp -- 192.168.40.5 anywhere tcp dpt:http reject-with icmp-port-unreachable
    REJECT udp -- anywhere anywhere udp dpt:italk reject-with icmp-port-unreachable
    REJECT tcp -- anywhere anywhere tcp dpt:italk reject-with icmp-port-unreachable
    ACCEPT tcp -- 192.168.40.0/24 anywhere tcp dpt:ssh
    ACCEPT icmp -- anywhere anywhere
    REJECT tcp -- anywhere anywhere tcp dpt:ssh reject-with icmp-port-unreachable
    REJECT tcp -- anywhere anywhere tcp dpts:cadlock2:1024 reject-with icmp-port-unreachable
    REJECT udp -- anywhere anywhere udp dpts:cadlock2:1024 reject-with icmp-port-unreachable
    ......
  9. 执行保存命令,让配置的防火墙策略永久生效,否则系统重启后失效

    1
    2
    # service iptables save
    iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

Firewalld

  • firewalld(Dynamic Firewall Manager of Linux systems,Linux系统的动态防火墙管理器)
  • firewalld服务是默认的防火墙配置管理工具,它拥有基于CLI(命令行界面)和基于GUI(图形用户界面)的两种管理方式
  • 相较于传统的防火墙管理配置工具,firewalld支持动态更新技术并加入了区域(zone)的概念
  • 区域就是firewalld预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换

firewalld常用区域名称及策略规则

区域 默认规则策略
trusted 允许所有的数据包
home 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、mdns、ipp-client、amba-client与dhcpv6-client服务相关,则允许流量
internal 等同于home区域
work 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、ipp-client与dhcpv6-client服务相关,则允许流量
public 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、dhcpv6-client服务相关,则允许流量
external 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh服务相关,则允许流量
dmz 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh服务相关,则允许流量
block 拒绝流入的流量,除非与流出的流量相关
drop 拒绝流入的流量,除非与流出的流量相关

终端管理工具——firewall-cmd

  • firewall-cmd是firewalld防火墙配置管理工具的CLI(命令行界面)版本
  • 可以用Tab键来补齐firewall-cmd命令中的长格式参数

firewall-cmd命令中使用的参数以及作用

参数 作用
–get-default-zone 查询默认的区域名称
–set-default-zone=<区域名称> 设置默认的区域,使其永久生效
–get-zones 显示可用的区域
–get-services 显示预先定义的服务
–get-active-zones 显示当前正在使用的区域与网卡名称
–add-source= 将源自此IP或子网的流量导向指定的区域
–remove-source= 不再将源自此IP或子网的流量导向某个指定区域
–add-interface=<网卡名称> 将源自该网卡的所有流量都导向某个指定区域
–change-interface=<网卡名称> 将某个网卡与区域进行关联
–list-all 显示当前区域的网卡配置参数、资源、端口以及服务等信息
–list-all-zones 显示所有区域的网卡配置参数、资源、端口以及服务等信息
–add-service=<服务名> 设置默认区域允许该服务的流量
–add-port=<端口号/协议> 设置默认区域允许该端口的流量
–remove-service=<服务名> 设置默认区域不再允许该服务的流量
–remove-port=<端口号/协议> 设置默认区域不再允许该端口的流量
–reload 让“永久生效”的配置规则立即生效,并覆盖当前的配置规则
–panic-on 开启应急状况模式
–panic-off 关闭应急状况模式
–permanent 永久模式(当前不生效,系统重启或reload后才自动生效)

firewalld实验

  1. 查看firewalld服务当前所使用的区域

    1
    2
    # firewall-cmd --get-default-zone
    public
  2. 查询网卡eno16777728在firewalld服务中的区域

    1
    2
    # firewall-cmd --get-zone-of-interface=eno16777728
    public
  3. 将firewalld服务中网卡eno16777728的默认区域修改为external(系统重启后才生效)。分别查看当前与永久模式下的区域名称

    1
    2
    3
    4
    5
    6
    # firewall-cmd --permanent --zone=external --change-interface=eno16777728
    success
    # firewall-cmd --get-zone-of-interface=eno16777728
    public
    # firewall-cmd --permanent --get-zone-of-interface=eno16777728
    external
  4. 将firewalld服务的当前默认区域设置为public

    1
    2
    3
    4
    # firewall-cmd --set-default-zone=public
    Warning: ZONE_ALREADY_SET: public
    # firewall-cmd --get-default-zone
    public
  5. 启动/关闭firewalld防火墙服务的应急状况模式,阻断一切网络连接(远程控制服务器时 慎用!

    1
    2
    3
    4
    # firewall-cmd --panic-on
    success
    # firewall-cmd --panic-off
    success
  6. 查询public区域是否允许请求SSH和HTTPS协议的流量

    1
    2
    3
    4
    # firewall-cmd --zone=public --query-service=ssh
    yes
    # firewall-cmd --zone=public --query-service=https
    no
  7. 将firewalld服务中请求HTTPS协议的流量设置为永久允许,并立即生效

    1
    2
    3
    4
    5
    6
    # firewall-cmd --zone=public --add-service=https
    success
    # firewall-cmd --permanent --zone=public --add-service=https
    success
    # firewall-cmd --reload
    success
  8. 将firewalld服务中请求HTTP协议的流量设置为永久拒绝,并立即生效

    1
    2
    3
    4
    # firewall-cmd --permanent --zone=public --remove-service=http
    success
    # firewall-cmd --reload
    success
  9. 将在firewalld服务中访问8080和8081端口的流量策略设置为允许,但仅限当前生效

    1
    2
    3
    4
    # firewall-cmd --zone=public --add-port=8080-8081/tcp
    success
    # firewall-cmd --zone=public --list-ports
    69/udp 8080-8081/tcp

    69/udp是TFTP的端口号

  10. 将原本访问本机888端口的流量转发到22端口,且要求当前和长期有效

    流量转发命名格式:firewall-cmd --permanent --zone=<区域> --add-forward-port=port=<源端口号>:proto=<协议>:toport=<目标端口号>:toaddr=<目标IP地址>

    1
    2
    3
    4
    # firewall-cmd --permanent --zone=public --add-forward-port=port=888:proto=tcp:toport=22:toaddr=192.168.40.131
    success
    # firewall-cmd --reload
    success

    在Windows10中用Xshell 6访问192.168.40.131主机的888端口,成功

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [C:\~]$ ssh root@192.168.40.131 888

    Connecting to 192.168.40.131:888...
    Connection established.
    To escape to local shell, press 'Ctrl+Alt+]'.

    Last failed login: Fri Aug 30 20:39:36 CST 2019 from 192.168.40.1 on ssh:notty
    There was 1 failed login attempt since the last successful login.
    Last login: Fri Aug 30 20:36:01 2019 from 192.168.40.1
    [root@localhost ~]#
  11. 配置一条富规则,使其拒绝192.168.40.0/24网段的所有用户访问本机的ssh服务(22端口)

    1
    2
    3
    4
    # firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.40.0/24" service name="ssh" reject"
    success
    # firewall-cmd --reload
    success

    在Windows10中用Xshell 6访问192.168.40.131主机的ssh服务( 22端口),失败

    1
    2
    3
    4
    [C:\~]$ ssh 192.168.40.131

    Connecting to 192.168.40.131:22...
    Could not connect to '192.168.40.131' (port 22): Connection failed.

服务的访问控制列表

  • TCP Wrappers是RHEL7系统中默认启用的一款流量监控程序
  • 它能够根据来访主机的地址与本机的目标服务程序作出允许或拒绝的操作
  • TCP Wrappers服务的防火墙策略由两个控制列表文件所控制,用户可以编辑允许控制列表文件来放行对服务的请求流量,也可以编辑拒绝控制列表文件来阻止对服务的请求流量
  • 控制列表文件修改后会立即生效,系统将会先检查允许控制列表文件(/etc/hosts.allow)
  • 如果匹配到相应的允许策略规则放行流量;如果没有匹配,则去进一步匹配拒绝控制列表文件(/etc/hosts.deny),若找到匹配项则拒绝该流量。如果这两个文件全都没有匹配到,则默认放行流量

TCP Wrappers服务控制列表文件的常用参数

客户端类型 示例 满足示例的客户端列表
单一主机 192.168.40.131 IP地址为192.168.40.131的主机
指定网段 192.168.40. 或 192.168.40.0/255.255.255.0 IP段为192.168.40.0/24的主机
指定DNS后缀 .zengzhilai.com 所有DNS后缀为.zengzhilai.com的主机
指定主机名称 www.zengzhilai.com 主机名称为www.zengzhi.com的主机
指定所有客户端 ALL 所有主机全部包括在内

配置TCP Wrappers服务需遵循的两个原则

  • 编写拒绝策略规则时,填写的是服务名称,而非协议名称
  • 建议先编写拒绝策略规则,测试后再编写允许策略规则,这样可直观地看到相应的效果
  1. 编辑拒绝策略规则文件:禁止访问本机sshd服务的所有流量

    1
    2
    3
    4
    5
    # vim /etc/hosts.deny
    ......
    sshd:*
    # ssh 192.168.40.131
    ssh_exchange_identification: read: Connection reset by peer
  2. 编辑允许策略规则文件:放行源自192.168.40.0/24网段访问本机sshd服务的所有流量

    1
    2
    3
    4
    5
    6
    7
    # vim /etc/hosts.allow
    ......
    sshd:192.168.40.
    # ssh 192.168.40.131
    root@192.168.40.131's password:
    Last login: Fri Aug 30 20:39:41 2019 from 192.168.40.1
    #