Zero-To-Awall
Awall 傻瓜教程
本指南旨在帮助那些对 iptables 和其他防火墙框架(如 Shorewall)没有(或只有少量)经验的用户。
本指南将分为 5 个部分。
- 定义我们的基本 json 文件,其中包含我们的区域和基本策略。
- 创建服务策略。
- 使用别名和自定义服务。
- 启用和测试策略。
- 完成并使其启动(在启动时)
注意:请注意,所有配置文件都存储为 JSON 文件。JSON 不是一种人类友好的标准,例如,它不支持注释,因此您必须将注释移到 json 结构之外。初学者应使用带有 JSON 高亮显示支持的体面文本编辑器,这将使您的生活更轻松。自最近版本的 awall 以来,也可以使用 yaml 代替 json,但这超出了本指南的范围。
基本策略
创建区域取决于您的防火墙的功能。它是安装在端点(服务器)上,还是将充当路由器并进行过滤/转发。在本指南中,我们假设您将设置路由器并使用 NAT 将服务(端口)转发到网络上的不同主机。
对于路由器上的每个接口,我们将设置一个区域并为其分配一个区域名称。我们通过创建以下文件来完成此操作:/etc/awall/private/base.json
{ "description": "Base zones and policies", "zone": { "WAN": { "iface": "eth0" }, "LAN": { "iface": "eth1" }, "VPN": { "iface": "tun+" } }, "policy": [ { "in": "VPN", "action": "accept" }, { "out": "VPN", "action": "accept" }, { "in": "LAN", "action": "accept" }, { "out": "LAN", "action": "accept" }, { "in": "_fw", "action": "accept" }, { "in": "_fw", "out": "WAN" , "action": "accept" }, { "in": "WAN", "action": "drop" } ], "snat": [ { "out": "WAN" } ], "clamp-mss": [ { "out": "WAN" } ] }
让我们将其分解为几个部分
描述
此处的描述仅供参考,将由 awall list
使用。
区域
这是定义区域的位置。区域基于接口定义,并分配一个名称,以便在您的策略中使用。在我们的示例中,您可以看到我们有两个真实的接口 eth0 和 eth1 以及一个或多个虚拟接口 tun+(加号代表任何数字,如 tun0 tun1 等)。如果您在端点(服务器)上安装 awall,那么您很可能没有 eth1 接口,可以将其省略。在我们的示例中,添加 tun+ 接口是因为它非常常用,例如在使用 openvpn 时。
策略
这些是我们的主要策略。它将告诉我们的防火墙当数据包从其中一个区域(接口)进入或离开时该怎么做。您会注意到一个特殊的 _fw
名称,它表示内部防火墙(本地机器),这意味着数据包不会通过另一个接口离开防火墙,而应发送到本地服务之一。您可以看到,默认情况下,我们不会过滤来自或去往我们的 VPN 区域/接口的任何数据包。您可以改为将默认操作更改为丢弃所有数据包,并创建单独的策略以允许特定流量,但这超出了本指南的范围。
snat
对传出的数据包应用源地址转换 (SNAT)。仅当您的防火墙充当路由器并且路由器后面的流量需要修改源地址(从本地 IP 转换为公网 IP)时,才需要这样做。
clamp-mss
https://github.com/alpinelinux/awall#mss-clamping-rules
服务策略
现在我们已经有了基本的防火墙,我们可以开始定义特定的策略,以便我们的服务可以从外部世界访问。\ 默认情况下,我们阻止所有进入 WAN 接口的流量 (action=drop)。我们要打开的第一个是我们的 SSH 端口/服务。为此,我们需要在“optional”目录中创建一个新策略。您可能想知道为什么是 optional 名称,那是因为强制策略存储在 /usr/share/awall/mandatory
中,不可触摸,而我们的可选策略可以在运行时启用/禁用。
SSH 服务
要添加我们的 SSH 策略,我们创建一个新文件:/etc/awall/optional/ssh.json
{ "description": "Allow rate-limited SSH on WAN", "filter": [ { "in": "WAN", "out": "_fw", "service": "ssh", "action": "accept", "conn-limit": { "count": 3, "interval": 20 } } ] }
描述
这对于任何策略都是类似的
过滤器
这是当前设置为丢弃到达或离开接口的数据包的实际过滤器。
入站
数据包到达的接口,在本例中是 WAN 接口。
出站
数据包离开的接口,在本例中是 _fw,这意味着它不会离开我们的防火墙/设备,而是针对我们的本地 SSH 服务。
服务
这是 awall 提供的服务定义或自定义服务,我们稍后将讨论。
动作
对数据包执行的动作,这会反转默认的丢弃动作并接受数据包。
连接数限制
这是我们的防火墙/iptables 的一个特殊功能,允许在一定时间内只允许一定数量的数据包。有关更多信息,请查看我们的 awall 手册。
SSH 到另一主机
编辑以下文件:/etc/awall/optional/ssh-to-hostname.json
{ "description": "Forward SSH to hostname", "filter": [ { "in": "WAN", "service": { "proto": "tcp", "port": 22001 }, "action": "accept", "conn-limit": { "count": 3, "interval": 20 } } ], "dnat": [ { "in": "WAN", "dest": "$SERVER", "service": { "proto": "tcp", "port": 22001 }, "to-port": "22" } ] }
让我们讨论此策略与之前的 SSH 策略之间的区别。
过滤器
服务
由于端口 22 已被我们自己的防火墙使用,我们需要监听不同的端口。在本例中,我们监听端口 22001。并且由于我们未使用默认端口 22,我们需要定义我们自己的服务规范。
dnat
也称为目标地址转换 (DNAT)。
目标
数据包将转发到的目标。在本例中,我们使用名为 $HOSTNAME 的变量。在您的策略中的任何位置,您都可以定义自己的变量并使用它们。在我们的例子中,我们使用了 /etc/awall/private/aliases.json 中的文件,稍后会详细介绍。
目标端口
这是目标目标端口号。数据包将从 22001 转发到 $hostname 上的 22
OpenVPN 服务
这是最通用的可用配置。它只是打开为我们的 openvpn 服务定义的端口,定义在 /etc/awall/private/custom-services.json 中
{ "description": "Allow local OpenVPN", "filter": [ { "in": "WAN", "out": "_fw", "service": "openvpn", "action": "accept" } ] }
允许 WAN 口 ping
允许对 WAN 口进行速率限制的 ping。它具有与我们之前的 SSH 策略相同的流量限制。
{ "description": "Allow rate-limited ping on WAN", "filter": [ { "in": "WAN", "out": "_fw", "service": "ping", "action": "accept", "flow-limit": { "count": 10, "interval": 6 } } ] }
使用别名和自定义服务
别名
为了在防火墙规则增加时更轻松,将特定主机映射到名称可能会很好。Awall 支持称为 变量扩展 的功能,它是值和变量之间的映射。当您的防火墙/路由器后面有很多设备时,您的策略可能更难阅读。此外,当您的设备之一的 IP 地址更改时,您将必须更新所有策略。使用 awalls 变量,您可以将设备的 IP 地址分配给变量名。编辑以下文件:/etc/awall/private/aliases.json
{ "description": "Hostname aliases", "variable": { "PRINTER": "192.168.1.1", "SERVER": "192.168.1.2" } }
查看上面的示例,其中 $SERVER 用于将端口 22001 转发到端口 22。
注意:您不仅限于将 IP 地址分配给变量。您可以随意使用它。更多信息可以在 awall 手册中找到。
自定义服务
Awall 包含 服务 的预定义列表。如果您尝试在策略中定义的服务不存在于 awalls 服务列表中,您可以自己定义服务。
创建文件:/etc/awall/private/custom-services.json
{ "service": { "mqtt": [ { "proto": "udp", "port": 1883 }, { "proto": "tcp", "port": 1883 } ], "openvpn": [ { "proto": "udp", "port": 1194 }, { "proto": "tcp", "port": 1194 } ] } }
注意:虽然您可以随意命名您的策略文件,但您不能将此文件命名为 services.json
,因为此策略名称已被 awall 包含的 services.json 使用。
使用我们的策略
您现在应该在 awall 配置目录中拥有两个目录,分别名为 optional 和 private,其中包含多个 json 文件。这两个目录之间最大的区别是启用和禁用 optional 目录中策略的能力。当您使用 awall enable policy-name
启用策略时,awall 将在您的 awall 配置目录中生成一个符号链接,并在您激活防火墙时自动加载它们。为了也能够使用 private 目录中的文件,我们需要将它们包含在我们的可选策略之一中。您可以随意命名该文件,只要它不与现有策略名称冲突(包括 private 目录和 awall 的系统策略中的名称)。示例名称可以是 hostname.json main.json firewall.json。对于此示例,我们将使用 main.json。
创建文件:/etc/awall/optional/main.json
{ "description": "Main firewall", "import": [ "base", "aliases", "custom-services" ] }
您的 awall 目录的内容
awall │ ├── optional │ ├── main.json │ ├── openvpn.json │ ├── ssh-to-hostname.json │ └── ssh.json └── private ├── aliases.json ├── base.json └── custom-services.json
启用可选策略
让我们启用我们创建的策略。首先,我们通过运行 awall list
列出它们,这将显示如下内容
openvpn disabled Allow local OpenVPN main disabled Main firewall ping disabled Allow rate-limited ping on WAN ssh disabled Allow rate-limited SSH on WAN ssh-to-hostname disabled Forward SSH to hostname
每个都需要启用
awall enable openvpn awall enable main awall enable ping awall enable ssh awall enable ssh-to-hostname
您的 awall 目录的内容现在应如下所示
awall/ ├── main.json -> ./optional/main.json ├── openvpn.json -> ./optional/openvpn.json ├── optional │ ├── main.json │ ├── openvpn.json │ ├── ping.json │ ├── ssh-to-hostname.json │ └── ssh.json ├── ping.json -> ./optional/ping.json ├── private │ ├── aliases.json │ ├── base.json │ └── custom-services.json ├── ssh-to-hostname.json -> ./optional/ssh-to-hostname.json └── ssh.json -> ./optional/ssh.json 2 directories, 13 files
测试策略
awall translate --verify
如果一切顺利,输出应为 null。
激活防火墙
现在我们已经验证了所有策略的 JSON 格式正确,我们可以激活它。
awall activate
这将加载防火墙规则并向您显示一条消息以确认。如果意外地犯了错误并把自己锁在外面,您只需等待 awall 再次禁用自身即可。
完成
在启动时激活防火墙规则
当 awall 已正确激活时,它将生成一个包含所有 iptables 规则的文件,当 iptables 通过 openrc 启动时,它将读取该文件。确保您已将 iptables 添加到 openrc 运行级别。如果使用 snat,还要为 masquerade 集启用 ipset。
rc-update add iptables
rc-update add ipset
允许 IPv4 转发
要允许 iptables 将数据包从一个区域转发到另一个区域,我们需要在 iptables 级别启用此功能。
即时生效
要即时启用它:sysctl -w net.ipv4.ip_forward=1
在 iptables 工具中启用 (启动时)
将以下内容添加到:/etc/conf.d/iptables
# Enable/disable IPv4 forwarding with the rules IPFORWARD="yes"