Zero-To-Awall

来自 Alpine Linux

Awall 傻瓜教程

本指南旨在帮助那些对 iptables 和其他防火墙框架(如 Shorewall)没有(或只有少量)经验的用户。

本指南将分为 5 个部分。

  1. 定义我们的基本 json 文件,其中包含我们的区域和基本策略。
  2. 创建服务策略。
  3. 使用别名和自定义服务。
  4. 启用和测试策略。
  5. 完成并使其启动(在启动时)

注意:请注意,所有配置文件都存储为 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"


参见