Linux FireWall

Entropy Tree Lv4

记录关于 Linux 防火墙的一些简单使用和说明

Linux 防火墙可能在很多时候对初学者部署网络服务造成了一定的“阻碍”。由于不清楚防火墙的重要性,许多用户选择直接关闭防火墙。对于一些大型云服务商来说,他们在防火墙之外还提供了安全组,能类似地起到防火墙的作用,使得 Linux 自带的防火墙似乎没有使用的必要性。但是对于 VPS 服务来说,他们是不提供安全组服务的,这意味着用户需要自己为服务器的安全负责,这时就很有必要学习 Linux 自带的防火墙技术——iptables。

Linux 防火墙

以下内容大部分参考自iptables核心运作原理和数据包过滤方法 | 技术蛋老师

iptables 的由来

以常见的 linux 服务器为例,可以划分为硬件、内核空间、用户空间三部分。

流量的流动是先从网卡,再到 linux 内核,最后抵达到网络应用。

过滤就是先让流量从网卡进来,然后在 linux 内核里进行过滤处理,最后进入网络应用。这样网络应用前面就有一道防火墙,防火墙就位于 linux 内核的实现中。

在 linux 内核中存在一个叫 netfilter 的框架,一旦有流量进来,就会触发 netfilter的机制对流量进行过滤。

为了方便操作 netfilter 框架, iptables 工具应运而生,iptables 相当于 netfilter 的接口。使用 iptables 命令就可以执行 netfilter 的复杂流量过滤逻辑。

不过 iptables 对于初学者来说还是具有一定的学习难度。

tables 表格

iptables 具有多个 table (表格),即 filter、nat、mangle、raw、security,常见的是前 4 个表格,最常用的则是 filternat

这两个表中,filter 负责过滤,nat 负责网络地址转换。nat 表可以支持负载均衡等强大功能。不过,绝大多数用户可能只需要关心 filter 表。

chains 链路

数据包抵达网络应用程序,最简单的链路就是一进一出。

但实际上 linux 系统本身也可以作为路由器存在,有些数据包会经过这台 linux 主机,并且被转发到其它设备,这样就会多一条转发链路,加上前面的一进一出链路,就可能发生很多情况。

不过处于内核的 netfilter 已经对链路的各个部分进行了管理。

当数据包一抵达到系统时,就由 PREROUTING 链负责。

如果数据包的目标是本机,就由 INPUT 链负责。

数据包如果从本机出去,就由 OUTPUT 链负责。

数据包如果不是要到本机,只是经过本机路由,就由 FORWARD 链负责。

数据包如果要离开本机,或者路由后,还有个 POSTROUTING 链负责。

单从过滤数据包的使用需求上,用户不需要了解所有的链。如果使用 filter 表,只需要管理 INPUT、OUTPUT 和 FORWARD 链。

filter 链路简单来说就是数据包的目标是本机可以过滤、数据包的转发可以过滤、数据包的目标是主机以外的其它地址可以过滤。

具体实现过滤就是在对应的链里加入规则。

iptables 含有不同的表,表里面有着不同的链,链里面可以制定不同的规则。

命令使用

使用 iptables 命令通常需要 root 权限,测试时为了方便可以切换到 root 操作。

查看表内容

iptables --table filter --list 这个命令会列出 filter 表里面的内容,不使用 --table 指定任何表,则默认选用 filter 表。

可以看到这里的三条链,这里初始没有设置任何规则。使用另一台处于同一局域网内的主机可以 ping 通。

接下来,使用 iptables 阻止另一台主机直接访问。

设置规则

先指定表格,再指定链,然后设置具体的规则

1
2
3
4
5
iptables \
--table filter \
--append INPUT \
--source 192.168.3.20 \
--jump REJECT

上面的命令在 filter 表的 INPUT 链中添加了规则:所有来自 192.168.3.20 (同一局域网的另一台主机 IP) 源地址的数据包,会被 INPUT 链拒绝处理。

重新查看 filter 表的信息如下

这里还需要注意 prot (protocol 协议),因为没有指定具体协议,所以默认为 all。

此时另一台主机应该无法顺利 ping 通,当本机去 ping 该主机也会收不到来自该主机的响应。

除了使用 REJECT 拒绝处理,还可以使用 DROP 进行丢弃。

可以在上面命令的基础上将 REJECT 替换为 DROP 执行。不过需要注意此时 INPUT 链中会先后包含 REJECT 和 DROP 两条规则,并且会根据先后顺序依次执行,但是 REJECT 规则会直接拒绝掉,导致 DORP 规则无法执行。需要先删除 REJECT 规则才能让 DROP 顺利执行。

查看表内容时可以加上 –line-numbers 参数方便查看规则

删除规则

iptables --table filter --delete INPUT 1

上面的命令会删除 INPUT 链的第一条规则,即 REJECT 规则。删除之后,原来的 DROP 会成为新的第一条规则

因此,使用序号连续删除规则的时候需要注意。

重新 ping 会出现另外的失败提示。

批量屏蔽 IP 地址

可以在 https://ipdeny.com 上找到对应的地址段,使用 wget 下载对应的文件,查看文件内容,有大量的 IP 段。这里使用命令手动添加和普通的脚本添加都不是最推荐的方式。

使用 ipset 指令就可以将大量的 IP 段单独汇集为一个集合,生成唯一 的哈希值。

当为 iptables 添加 IP 地址时,只需要使用该哈希值来代表背后的 IP 地址段集合。

1
ipset create asan hash:net

上面的命令会创建一个名为 asan 的集合,使用 net 表示网络号,而非主机号。

1
ipset list asan

上面的命令会列出 asan 集合的信息,此时集合里面还没有添加 IP 地址段。

接下来是将 IP 地址段添加到集合中,使用 iptables 和 ipset 编写脚本。

首先,创建一个名为 block-india.sh 的文件,然后在脚本里填入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash

ipset create asan hash:net -exist # -exist 避免重复创建导致失败
ipset flush asan # 清除旧地址
[ -f "in-aggregated.zone" ] && rm in-aggregated.zone # 删除旧文件

wget .... # 下载 url 对应的文件

if [ $? -eq 0 ] # 判断是否下载成功
then
echo "********** Downloaded **************"
for address in `cat in-aggregatd.zone`
do
ipset add asan $address # 循环添加到 asan 集合中
done
else
echo "********** Failed to download **************"
fi

iptables \
--table filter \
--append INPUT \
--match set --match-set asan src \
--jump DROP

脚本编写完成,赋予文件可执行权限。

在执行之前先 ping 一下集合中的一个 IP 确认没有问题。

执行完脚本后,可以执行 ipset list asan | less 或结合 grep 查看是否添加成功。

重新 ping 之前测试用的 IP 发现 ping 不通,表示设置成功。

持久化规则

重启服务器后一般会自动清空 iptables 和 ipset 的设置。可以使用以下命令

1
2
ipset save > /etc/rules.ipset
iptables-save > /etc/rules.iptables

对于 ipset 可以使用 ipset save > /etc/rules.ipset 将规则保存到 rules.ipset 文件。

对于 iptables 可以使用 iptables-save > /etc/rules.iptables 将规则保存到 rules.iptables 文件。

重启服务器,使用以下命令分别恢复设置

1
2
ipset restore < /etc/rules.ipset
iptables-restore < /etc/rules.iptables

如果在恢复设置之前还添加了新的设置,不想在恢复时被覆盖掉,可以在 iptables-restore 后面加上 --noflush 或者 -n,在 ipset restore 后加上 -exist。

其它永久保存规则和集合的方法:deb 系提供了 iptables-persistent 包,rehl 系提供了iptables-services 包。

iptables 在 Linux 服务器发展中有着很重要的地位。到了现代,即使已经出现了 nftables (iptables 的现代化替代),还是有大量的服务器依旧使用 iptables 管理防火墙。

以下是一些补充资料的整理说明,简单地介绍为了简化 Linux 防火墙管理的一些工具。这些工具基本都是基于 iptables/nftables 实现的,本质上是对底层的 iptables/nftables 的抽象化实现,使得非专业用户也能很好地管理防火墙,满足日常需求。

防火墙简化管理

ufwfirewalldiptablesnftables都是Linux防火墙工具,它们可以独立使用,也有一些底层联系。

  • ufw:全称 Uncomplicated Firewall,是 Ubuntu 提供的一个 iptables 的接口,因为原生的 iptables 配置麻烦,学习成本较高。ufw 支持 IPv4 和 IPv6,最新版的 UFW 默认启用了 IPv6 配置。
  • firewalld:Centos7 及以上的发行版自带了 firewalld 防火墙,firewalld 带有 iptables 防火墙。其原因是 iptables 的防火墙策略是交由内核层面的 netfilter 网络过滤器来处理的,而 firewalld 则是交由内核层面的 nftables 包过滤框架来处理。相较于 iptables 防火墙而言,firewalld 支持动态更新技术并加入了区域(zone)的概念。
  • iptables:iptables 是最底层、最古老的防火墙系统,所有系统都会存在此防火墙,但一般而言使用其它上层管理工具的时候,只需保证该防火墙处于完全开放状态即可。
  • nftables:nftables 是用于替换 iptables 的工具。

一些历史发展:iptables 是最早的防火墙工具,后来出现了 ufw 和 firewalld,这两个工具都是对 iptables 进行了封装,使得管理员在配置防火墙时可以通过执行相对简单,更容易理解的命令配置防火墙,而不是通过执行复杂难懂的 iptables 命令。最后,nftables 出现,作为 iptables 的替代品。

iptables 迁移到 nftables

可以按照以下步骤从 iptables 过渡到 nftables

  1. 停用 iptables:首先,需要停用 iptables 相关服务。

    可以使用以下命令来停用 iptables、ip6tables

    1
    2
    3
    4
    sudo systemctl stop iptables
    sudo systemctl disable iptables
    sudo systemctl stop ip6tables
    sudo systemctl disable ip6tables

    这些命令会停止 iptables 服务,并禁止它在系统启动时自动启动。

  2. 设置 iptables:然后,选择将其配置为允许所有流量,这样它就不会干扰 nftables 的操作。

    要让 iptables 允许所有流量,可以使用以下命令

    1
    2
    3
    4
    sudo iptables -P INPUT ACCEPT
    sudo iptables -P FORWARD ACCEPT
    sudo iptables -P OUTPUT ACCEPT
    sudo iptables -F

    这一步看起来似乎是多余的,但这实际上是一个谨慎的做法,旨在确保在迁移到 nftables 的过程中网络流量不会受到意外的中断或干扰。

  3. 安装并启用 nftables:最后,安装并启用 nftables。

    可以使用以下命令来安装 nftables

    1
    sudo apt install nftables

    使用以下命令来启用 nftables 服务

    1
    2
    sudo systemctl enable nftables
    sudo systemctl start nftables

    这些命令会启动nftables服务,并设置它在系统启动时自动启动。

  4. 验证 nftables 规则

    查看当前的规则集来验证 nftables 的配置是否按预期工作。

    1
    sudo nft list ruleset
  5. 规则集转换

    redhat 官方推出以下参考的资料,用于将 iptabls 的规则集转换为 nftables 的规则集。

    配置和管理网络——nftables 入门 | Red Hat

    安全网络——nftables 入门 | Red Hat

注意:这些步骤通常都需要root权限才能执行。在执行这些步骤时,请确保已经备份了系统和数据,以防万一。

firewalld 使用

firewalld支持nftables后端。

firewalld 是一个动态管理防火墙规则的守护进程,使用 zonesservices 的概念来简化防火墙管理。它提供了更直观的方式来组织规则和管理网络流量的访问权限。以下是 firewalld 的一些基本用法:

安装和启动 firewalld

在大多数基于 RPM 的发行版(如 Fedora、CentOS、RHEL)上,firewalld 默认已安装。如果没有,可以使用包管理器进行安装:

1
2
3
sudo yum install firewalld    # CentOS/RHEL
sudo dnf install firewalld # Fedora
sudo apt install firewalld # Ubuntu/Debian

基本管理

启动和停止 firewalld

  • 启动

    1
    sudo systemctl start firewalld
  • 停止

    1
    sudo systemctl stop firewalld
  • 使 firewalld 服务在系统启动时自动启动

    1
    sudo systemctl enable firewalld
  • 禁用自动启动

    1
    sudo systemctl disable firewalld

重载 firewalld:不中断当前连接的情况下,应用更改。

1
sudo firewall-cmd --reload

查看 firewalld 状态

1
sudo firewall-cmd --state

区域管理

firewalld 使用 zones 来定义网络的安全级别。每个 zone 都有一套规则,用于决定哪些流量可以进入。默认 zone 通常是 public

  • 查看所有可用的 zones:

    1
    sudo firewall-cmd --get-zones
    • 这个命令用于列出 firewalld 所知的所有可用防火墙区域。
    • 这些区域包括预定义的区域和用户自定义的区域。
    • 输出只是区域的名称列表,不包括每个区域的具体规则或配置详情。
    • 这个命令非常有用,当你想要快速查看所有可用的防火墙区域时,比如在创建新规则或者修改现有规则时确定要使用哪个区域。
  • 详细查看所有的 zones 和配置:

    1
    sudo firewall-cmd --list-all-zones
    • 这个命令用于详细列出所有防火墙区域及其当前配置,包括每个区域的规则、服务、接口、源地址等。
    • 输出会显示每个区域的完整配置,这对于审查当前防火墙的配置和确定各个区域的作用非常有帮助。
    • 因为输出可能会很长(取决于有多少区域以及它们的配置如何),所以通常在需要详细了解防火墙设置时使用这个命令。
  • 查看默认的 zones:

    1
    firewall-cmd --get-default-zone
    • 这个命令用于查询当前的默认防火墙区域。
    • 默认区域是新加入网络接口或源未被指定为其他区域的情况下所使用的区域。
    • 它是系统上所有未明确分配到其他区域的网络流量的默认处理区域。
  • 查看当前接口所属的 zone:

    1
    sudo firewall-cmd --get-active-zones
    • 这个命令用于列出当前所有活跃的防火墙区域及其关联的网络接口和源地址。
    • 活跃区域是指当前已经有网络接口或源地址被分配的区域。这表示这些区域正在被用于管理进出这些接口或源地址的网络流量。
    • 这个命令提供了一个快照,展示了哪些区域是配置中的,以及它们是如何关联到特定的网络接口或源地址的。
  • 设置默认的 zones:

    1
    firewall-cmd --set-default-zone=[zonename]

修改区域配置:临时(直到下次重启或重载)或永久(持久化存储)修改防火墙规则

  • 临时添加服务:

    1
    sudo firewall-cmd --zone=<zone> --add-service=<service>
  • 永久添加服务:

    1
    sudo firewall-cmd --permanent --zone=<zone> --add-service=<service>

    还可以使用以下命令对当前修改过的规则即时保存为永久配置,不过是截止到这条命令执行的时间点之前,后续添加新的规则不会受影响。

    1
    sudo fiewall-cmd --runtime-to-permanent

    该命令可以在确定当前的运行时配置满足需求后,快速将其保存为永久配置,避免了手动重新添加规则的麻烦。

    对于任何新的规则更改,如果希望它们即刻生效并持久化,应该继续使用 --permanent 参数并在需要时使用 --reload 命令来应用更改。

规则管理

允许/禁止服务:启用或禁用特定的服务。

  • 允许服务:sudo firewall-cmd --zone=<zone> --add-service=<service>

  • 禁止服务:sudo firewall-cmd --zone=<zone> --remove-service=<service>

    1
    2
    sudo firewall-cmd --zone=public --add-service=http
    sudo firewall-cmd --zone=public --remove-service=http

    添加 --permanent 参数以使更改永久。

允许/禁止端口:开放或关闭特定的端口。

  • 允许端口:sudo firewall-cmd --zone=<zone> --add-port=<port>/<protocol>

  • 禁止端口:sudo firewall-cmd --zone=<zone> --remove-port=<port>/<protocol>

    1
    2
    sudo firewall-cmd --zone=public --add-port=8080/tcp
    sudo firewall-cmd --zone=public --remove-port=8080/tcp

    同样,添加 --permanent 参数以使更改永久。

查看配置

  1. 列出区域中的服务和端口:查看区域中当前允许的服务和端口。

    1
    2
    sudo firewall-cmd --zone=<zone> --list-services
    sudo firewall-cmd --zone=<zone> --list-ports
  2. 列出所有配置:查看特定区域或所有区域的详细配置。

    列出特定区域的所有配置:

    1
    sudo firewall-cmd --zone=<zone> --list-all

    列出所有区域的配置:

    1
    sudo firewall-cmd --list-all-zones

高级功能

直接规则:直接操作 iptables/nftables 规则。

  • 添加直接规则:

    1
    sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 80 -j ACCEPT
  • 删除直接规则:

    1
    sudo firewall-cmd --permanent --direct --remove-rule ipv4 filter INPUT 0 -p tcp --dport 80 -j ACCEPT

重新加载配置

更改 firewalld 的配置后,尤其是对于使用--permanent参数的配置,需要显式地重新加载规则,以便更改生效:

1
sudo firewall-cmd --reload

使用 --list-all 参数定期检查区域配置,确保规则按预期工作。

查看和添加服务

firewalld 使用服务(services)来简化管理。服务是预定义的端口和协议的组合,这使得开放对特定类型网络服务的访问变得简单。每个服务都有一个与之关联的配置文件,定义了所需的端口和协议。

查看所有预定义的服务(这里不指定zone会使用默认的设置,如public):

1
sudo firewall-cmd --get-services

查看特定服务的详细信息:

1
sudo firewall-cmd --info-service=http

添加自定义服务:

  1. 创建一个 XML 文件定义服务。例如,为自定义应用myapp创建/etc/firewalld/services/myapp.xml

    1
    2
    3
    4
    5
    6
    <?xml version="1.0" encoding="utf-8"?>
    <service>
    <short>MyApp</short>
    <description>This is my custom application.</description>
    <port protocol="tcp" port="8080"/>
    </service>
  2. 重新加载firewalld以识别新服务:

    1
    sudo firewall-cmd --reload
  3. 将新服务添加到防火墙规则中:

    1
    sudo firewall-cmd --zone=public --add-service=myapp

    添加--permanent参数以使更改永久

    1
    sudo firewall-cmd --permanent --zone=public --add-service=myapp

    当使用--permanent参数时,规则会被保存在配置文件中,即使firewalld服务重启也会保留这些规则。不使用--permanent参数的更改仅在当前会话中有效,重启firewalld服务后会丢失。

富规则(Rich Rules)

firewalld 的富规则(Rich Rules)提供了更复杂的规则定义方式,允许创建包含源地址、端口、协议等多种条件的细致规则。

  • 添加富规则

    例如,拒绝来自特定 IP 地址的所有访问:

    1
    sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" drop' --permanent

恐慌模式

firewalld 提供了一个非常有用的功能,即“恐慌模式”(panic mode),它允许管理员在遇到网络安全威胁时,快速地切断所有外部网络通信,有效防止潜在的攻击。这个功能对于紧急情况下保护系统免受进一步损害非常有帮助。

  1. 启用恐慌模式

    1
    sudo firewall-cmd --panic-on

    启用恐慌模式会立即阻断所有进出的网络流量,这相当于一个紧急的“断网”开关。

  2. 禁用恐慌模式

    1
    sudo firewall-cmd --panic-off

    当安全威胁已经被处理,或者确定网络可以安全恢复时,可以使用此命令禁用恐慌模式,恢复正常的网络通信。

  3. 查询恐慌模式状态

    1
    sudo firewall-cmd --query-panic

    这个命令可以让你查询当前防火墙是否处于恐慌模式。这对于确认防火墙的当前状态非常有用。

注意事项

  • 恐慌模式的使用场景:只有在确信系统正遭受攻击,且需要立即切断所有网络连接以保护系统和数据安全时,才应该启用恐慌模式。这是一个极端措施,会影响到所有网络服务和通信。
  • 恢复网络通信:在禁用恐慌模式后,系统的网络通信会恢复正常。但是,根据攻击的性质和系统的配置,可能需要进一步的检查和修复工作,以确保系统的安全性。
  • 规划应急响应:将恐慌模式作为应急响应计划的一部分,确保相关人员了解如何正确使用这一功能,并了解启用和禁用恐慌模式后的后续步骤。

恐慌模式是 firewalld 提供的一个强大工具,能够在遭受攻击时提供即时的保护措施。然而,它应该谨慎使用,并伴随着全面的安全策略和事后分析。

锁闭机制

firewalld 提供了一个锁闭机制(lockdown mode),这是一种安全特性,用于限制本地程序比如 KVM 虚拟机组件或一些代理服务组件对防火墙配置的修改。当启用锁闭模式时,通常只有 root 用户才能修改防火墙规则。

  1. 查询防火墙的锁闭状态

    1
    sudo firewall-cmd --query-lockdown

    这个命令会返回当前防火墙的锁闭状态,如果启用了锁闭模式,它会返回 yes,否则返回 no

  2. 启用锁闭模式

    1
    sudo firewall-cmd --lockdown-on

    执行这个命令后,防火墙将进入锁闭模式,限制未授权的防火墙配置更改。

  3. 禁用锁闭模式

    1
    sudo firewall-cmd --lockdown-off

    使用这个命令可以禁用锁闭模式,恢复到允许更改防火墙配置的状态。

注意事项

  • 使用场景:锁闭模式特别适用于生产环境,或者任何对安全性要求较高的环境,它可以帮助确保防火墙配置不会被未授权的更改所破坏。
  • 权限:这些操作需要 root 用户权限,这意味着只有系统管理员和有适当权限的用户可以启用或禁用锁闭模式。
  • 影响:启用锁闭模式可能会影响那些需要修改防火墙规则的合法程序和服务,因此在启用之前需要仔细考虑。

firewalld 的锁闭机制提供了一个额外的安全层,帮助防止未授权的防火墙配置更改。管理员可以根据需要启用或禁用锁闭模式,以适应不同的安全需求和操作环境。在启用锁闭模式时,确保考虑到对合法服务和应用程序的潜在影响。

参考资料

iptables核心运作原理和数据包过滤方法 | 技术蛋老师

nftables wiki

Nftables HOWTO 中文翻译

配置和管理网络——nftables 入门 | Red Hat

安全网络——nftables 入门 | Red Hat

Documentation | firewalld.org

FirewallD 防火墙使用概述 | Linux 中国

  • 标题: Linux FireWall
  • 作者: Entropy Tree
  • 创建于 : 2024-02-27 23:18:08
  • 更新于 : 2024-03-04 13:15:12
  • 链接: https://www.entropy-tree.top/2024/02/27/linux-firewall/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论