Ubuntu系统默认的UFW防火墙足够应付单机场景,但一旦服务器承担网关角色,或者内部网络划分了多个安全域,UFW的基于主机的过滤逻辑就完全不够用了。你需要的是区域化防火墙策略,把不同信任级别的网络隔离开来,对流量进行精细控制。Shorewall正是为此而生,它不替换iptables,而是把iptables复杂的规则语法抽象成几个配置文件,让你用描述性的方式定义区域、策略和规则。

理解Shorewall的核心抽象:区域、策略和规则

Shorewall把网络接口划分到不同的“区域”(Zone),每个区域代表一个信任级别。典型划分是:外网(net)完全不信任,内网(loc)高度信任,DMZ区(dmz)部分信任,无线网络(wifi)低信任。区域之间默认没有流量通过,你必须显式定义“策略”(Policy)来允许或拒绝区域间的流量。策略定义了从源区域到目标区域的默认动作,比如从内网到外网的流量通常允许,从外网到内网的流量通常拒绝。更细粒度的控制则通过“规则”(Rules)实现,规则可以精确到源IP、目标IP、协议和端口。

安装与环境准备

在Ubuntu 22.04或24.04上,Shorewall已包含在官方仓库中。安装前务必确认系统已禁用其他防火墙管理工具,避免规则冲突。执行以下命令进行安装:

sudo apt update
sudo apt install shorewall shorewall6

安装完成后,Shorewall默认处于禁用状态。不要急于启动,先检查网络接口配置,确认哪个接口连接外网,哪个连接内网。假设eth0连接外网,eth1连接内网,eth2连接DMZ区,后续配置都将基于这个拓扑。同时建议安装shorewall-doc包获取完整文档,里面的示例配置文件是极好的参考。

基础配置文件详解

Shorewall的配置文件集中在/etc/shorewall目录。初次安装时该目录为空,需要从/usr/share/doc/shorewall/examples/复制示例配置。选择two-interfaces或three-interfaces示例作为起点,根据实际网络拓扑决定。核心配置文件有六个,每个都承载着不同的逻辑层面。

zones文件定义区域。每一行声明一个区域的名称、类型和关联的网络接口。类型决定了该区域是否启用连接跟踪、是否允许DHCP等特性。标准写法如下:

fw    firewall
net   ipv4
loc   ipv4
dmz   ipv4

注意fw是保留区域名,代表防火墙主机本身。ipv4类型表示该区域启用IPv4连接跟踪,这是有状态过滤的基础。

interfaces文件将物理网络接口映射到区域。格式为“区域 接口 地址检测方式 选项”。地址检测通常使用dhcp或detect,静态IP环境用detect即可。如果某个接口使用DHCP获取地址,必须指定dhcp,否则Shorewall无法正确处理动态IP变化。示例:

net    eth0    detect    dhcp,routeback
loc    eth1    detect    routeback
dmz    eth2    detect    routeback

routeback选项允许来自该接口的流量被路由回同一接口,这在某些VPN或代理场景下是必需的,但一般内网接口不建议开启。

policy文件是Shorewall的精髓。它定义了区域间流量的默认处理方式。策略从上到下匹配,找到第一个匹配的策略即停止。最常见的配置是:防火墙自身允许任何出站流量,内网到外网允许,外网到内网拒绝,外网到DMZ的特定端口在rules文件中放行。示例:

fw          all         ACCEPT
loc         net         ACCEPT
loc         dmz         ACCEPT
dmz         net         ACCEPT
net         all         DROP
all         all         REJECT    info

最后一行是兜底策略,确保未明确允许的流量都被拒绝并记录日志。info参数表示以info级别记录日志,便于排错。生产环境建议将最后一条的REJECT改为DROP,减少对外暴露信息。

rules文件是策略的补充,用于定义例外规则。格式为“动作 源区域 目标区域 协议 端口 源IP 目标IP”。例如,允许外网访问DMZ区的Web服务器:

ACCEPT    net    dmz    tcp    80,443

允许内网某台管理主机SSH到防火墙:

ACCEPT    loc    fw     tcp    22    -    192.168.1.100

规则中源IP和目标IP字段可以使用CIDR表示法,也可以写主机IP或网络段。留空或写“-”表示任意。Shorewall还支持宏(Macro),预定义了常见服务的规则模板,比如Web、SSH、Ping等,用起来很方便。

masq文件与源地址转换

如果Ubuntu服务器充当网关,内网主机需要通过它访问外网,就必须配置源地址转换。masq文件定义哪些流量需要做SNAT。格式为“接口 源地址 目标地址 协议 端口”。最简配置是让所有内网流量从外网接口出去时做地址伪装:

eth0    eth1

这表示从eth1(内网)发出的流量,通过eth0(外网)出去时自动进行SNAT。Shorewall会自动检测eth0的IP地址作为伪装地址,无需手动指定。如果外网IP是动态获取的,这种写法比iptables手动指定接口IP要可靠得多。

更精细的控制可以限定源地址范围,比如只允许特定子网通过:

eth0    192.168.1.0/24

这样其他内网段即使路由可达,也不会被NAT,从而实现了访问控制与地址转换的联动。

黑名单与动态阻断

Shorewall内置了动态黑名单功能,可以自动封禁触发特定规则的IP地址。这比手动维护黑名单高效得多。配置文件是blrules,格式与rules类似,但动作字段使用动态动作。例如,对频繁扫描SSH端口的外部IP自动封禁:

ACCEPT    net    fw    tcp    22    -    -    -    s:ssh-bruteforce

然后在/etc/shorewall/actions文件中定义ssh-bruteforce动作:

ssh-bruteforce    DROP    info

还需要在/etc/shorewall/blvars中设置阈值,比如60秒内新建连接超过5次即触发封禁,封禁持续600秒。这种机制对抵御暴力破解和端口扫描非常有效,且完全在iptables层面实现,性能开销极低。

流量整形与QoS

Shorewall对流量整形的支持也很成熟,通过tcdevices和tcrules两个文件实现。tcdevices定义网络接口的带宽参数,tcrules定义具体的分类和限速规则。例如,限制内网P2P流量占用的上行带宽:

tcdevices文件:

eth0    inet    100mbit    10mbit

tcrules文件:

MARK    loc    net    tcp    6881:6889
RATE    1:10    loc    net    512kbit    64kbit

这套机制基于Linux内核的HTB队列规则,可以将流量划分为不同优先级,保证关键业务带宽。虽然配置稍显复杂,但在带宽紧张的环境下效果显著。

日志、排错与状态查看

Shorewall的所有日志默认写入/var/log/syslog,前缀为Shorewall。如果规则未按预期工作,首先检查日志。使用shorewall status命令可以查看当前加载的iptables规则和连接状态,输出非常直观。shorewall show zones显示区域配置,shorewall show policies显示策略顺序,shorewall show connections列出当前活动连接。这些命令是日常运维的利器。

修改配置文件后,必须执行shorewall check检查语法,确认无误后再用shorewall restart应用新规则。如果是远程操作,务必使用shorewall safe-restart,它会在重启后等待用户确认,如果超时未确认则自动回滚,防止把自己锁在服务器外面。这个安全机制对于远程管理至关重要。

常见问题包括接口区域映射错误、策略顺序不当导致规则被提前匹配、以及忘记配置回程路由。内网主机能出去但收不到回包,多半是策略只放了出站没考虑入站,或者masq配置有误。Shorewall的有状态过滤会自动放行已建立连接的返回流量,但前提是初始方向策略允许。这一点新手容易混淆。

高级场景:多出口负载均衡与故障切换

当服务器有多条外网链路时,Shorewall配合iproute2可以实现出站负载均衡和链路故障切换。在providers文件中定义多个外网接口及其网关、权重,Shorewall会自动生成相应的路由表和iptables标记规则。配置示例如下:

ISP1    1    1    main    eth0    192.168.0.1    track    eth0
ISP2    2    1    main    eth1    10.0.0.1       track    eth1

然后在tcrules或rules中根据标记选择出口,或者使用use选项让Shorewall自动分配。这种方案适合中小企业的低成本多线接入,比专业负载均衡设备灵活且成本低得多。故障检测通过track选项实现,Shorewall会监控链路状态,一旦检测到对端不可达即自动切换流量到备用链路。

安全加固建议

区域化防火墙的边界定义必须严谨。不要把所有内网接口都划入同一个区域,应该根据部门、业务或安全级别细分。比如财务部门单独一个区域,只允许特定主机访问。DMZ区的主机如果被攻破,攻击者可能以内网为跳板进一步渗透,因此DMZ到内网的策略应该严格限制,只开放必要的数据库端口,且限定源IP。

防火墙主机自身的安全也不能忽视。在rules文件中明确限制哪些IP可以SSH登录防火墙,不要对所有区域开放。定期审计/etc/shorewall目录下的配置文件,删除注释掉的旧规则,保持配置整洁。使用版本控制管理配置文件变更,便于回滚和审计。

Shorewall的配置文件是声明式的,可读性远强于原始iptables规则。这种特性使得安全审计变得简单,第三方可以快速理解防火墙策略全貌,这是iptables脚本难以做到的。对于需要合规审计的环境,Shorewall是比手写iptables更合适的选择。

Shorewall在Ubuntu上的部署并不复杂,但它提供的区域化抽象、策略引擎和配套工具链,使得复杂防火墙策略的维护成本大幅降低。从单网关场景到多出口负载均衡,从静态规则到动态黑名单,Shorewall都能胜任。关键是理解它的区域模型和策略匹配逻辑,一旦掌握,你就能用几行配置替代数百条iptables规则,且逻辑清晰、不易出错。