Tường lửa Awall trên Alpine Linux

Alpine linux không có sẵn tường lửa mặc định lúc cài đặt hệ điều hành. Do đó, để đảm bảo cho việc bảo mật thì việc lựa chọn tường lửa cho Alpine nên được thiết lập ngay sau khi cài đặt thành công hệ điều hành. Bài viết này hướng dẫn cách thiết lập tường lửa trên Alpine linux sử dụng Awall.

Cài đặt iptables và awall trên Alpine

Awall chỉ là một tiện ích cho iptables, làm cho nó dễ cấu hình và sử dụng hơn. Do đó bước đầu tiên là cài đặt và kích hoạt iptables.

# apk update && apk upgrade
# apk add iptables ip6tables
# modprobe ip_tables          ##### for IPv4
# modprobe ip6_tables         ##### for IPv6
# /etc/init.d/iptables save
# rc-service iptables start
# /etc/init.d/ip6tables save
# rc-service ip6tables start

Thêm iptables vào runlevel mặc định của OpenRC để chạy nó cùng lúc với khởi động hệ điều hành:

# rc-update add iptables
# rc-update add ip6tables

Sau khi đã có iptables thì việc cài đặt awall chỉ bằng một câu lệnh đơn giản:

# apk add awall

Bây giờ bạn đã có thể cấu hình những chính sách (policy) để gọi tường lửa awall thực thi.

Cấu hình tường lửa Awall

Cấu hình Awall bắt đầu với một hoặc nhiều tập tin định dạng JSON được gọi là tập tin policy (chính sách). Các tập tin cấu hình mặc định của Awall được lưu ở thu mục /usr/share/awall. Tuy nhiên, bạn cần thiết lập các policy tùy chỉnh ở thư mục “optional” và “private” trong /etc/awall. Thư mục “optional” sẽ lưu tất cả những policy thực, và thư mục “private” có thể lưu bất kì dịch vụ hoặc biến tùy chỉnh nào đó mà bạn muốn định nghĩa.

Chính sách đầu tiên

Cách tốt nhất để thiết lập tường lửa là bắt đầu khóa mọi thứ. Sau đó chúng ta thêm thiết lập để cho phép những dịch vụ cần sử dụng. Tương ứng, policy đầu tiên chúng ta thiết lập tường lửa là drop tất cả các gói tin kết nối đến từ bên ngoài và từ chối (reject) tất cả những thứ khác.

Bạn có thể tưởng tượng drop gói tin như là vứt nó vào sọt rác. Khi từ chối gói tin có nghĩa là không chỉ vứt nó vào sọt rác mà còn báo với người gửi rằng “Tôi từ chối nó”.

vi /etc/awall/optional/default.json
{
    "description": "Drop all incoming traffic from WAN, reject all other",
    "zone": {
        "WAN": { "iface": "eth0" }
    },
    "policy": [
        { "in": "WAN", "action": "drop" },
        { "action": "reject" }
    ]
}

File JSON như trên tuy không quá dễ đọc với người bình thường nhưng nhìn chung nó dễ dàng tùy chỉnh thậm chí bạn chưa bao giờ tiếp xúc với định dạng JSON.

Nếu bạn muốn chỉ định nhiều interface trong một zone, hoặc nhiều zone, bạn có thể thực hiện như sau:

    "zone": {
        "WAN": { "iface": [ "eth0", "wlan0"] },
        "VPN": { "iface": "wg0" }
    },

Cho phép kết nối SSH

vi /etc/awall/optional/ssh.json
{
    "description": "Allow incoming SSH on WAN (TCP/22)",
    "filter": [
        {
            "in": "WAN",
            "out": "_fw",
            "service": "ssh",
            "action": "accept",
            "conn-limit": { "count": 3, "interval": 30 }
        }
    ]
}

Đầu tiên, bạn mô tả những gói tin nào mà policy này được áp dụng. Những gói tin đến từ bên ngoài internet ("in": "WAN") và được đưa đến một dịch vụ bên trong là ("out": "_fw"). Trong đó, zone "_fw" cơ bản chỉ có nghĩa là “dịch vụ trên máy tính này”, nó là zone được tích hợp sẵn trong awall. Sau đó chúng ta chỉ ra giao thức (protocol) và cổng (port) được sử dụng (“service”: “ssh”). Đến đây bạn có thể thắc mắc rằng: làm sao điều đó chỉ ra giao thức và dịch vụ? Không phải nó chỉ bảo là “ssh”?

Để làm cho cuộc sống chúng ta dễ dàng hơn, có một danh sách mặc định cho những dịch vụ thường dùng được lưu ở /usr/share/awall/mandatory/services.json. Bạn có thể thấy rằng ở đó “ssh” có chỉ ra giao thức và cổng kết nối, trông giống như sau:

{ "proto": "tcp", "port": 22 }

Cho phép những dịch vụ cơ bản kết nối internet (DNS, HTTP, HTTPS, SSH, ping, ntp)

vi /etc/awall/optional/outgoing.json
{
    "description": "Allow basic outgoing traffic from local to WAN",

    "filter": [
        {
            "in": "_fw",
            "out": "WAN",
            "service": [ "dns", "http", "https", "ssh", "ping" , "ntp"],
            "action": "accept"
        }
    ]
}

Cho phép ping đến server

vi /etc/awall/optional/ping.json
{
    "description": "Allow incoming ping on WAN with flow-limit",

    "filter": [
        {
            "in": "WAN",
            "out": "_fw",
            "service": "ping",
            "action": "accept",
            "flow-limit": { "count": 10, "interval": 6 }
        }
    ]
}

Liệt kê, cho phép và kích hoạt các policy

# awall list
main        disabled    Drop incoming traffic from WAN, reject all other
outgoing    disabled    Allow outgoing traffic from local to WAN
ping        disabled    Allow incoming ping on WAN with flow-limit
ssh     disabled    Allow incoming SSH on WAN with conn-limit (TCP/22)
# awall enable main outgoing ping incoming-ssh
# awall disable ping
# awall enable ping
# awall activate
New firewall configuration activated
Press RETURN to commit changes permanently: 

Phím RETURN là phím ENTER trên bàn phím.

Định nghĩa những dịch vụ tùy chỉnh

# vi /etc/awall/private/custom-services.json

{
    "service": {
        "wireguard": [
            { "proto": "udp", "port": 17511 }
        ],
        "squid": [
            { "proto": "tcp", "port": 3128 }
        ]
    }
}

Bạn cần import custom-services.json vào file policy mặc định mà đã tạo lúc ban đầu:

{
    "description": "..."
    "import": [ "custom-services" ],
    "zone": {...},
    "policy": [...]
}

Dưới đây là cấu hình mặc định nên áp dụng cho VPS, trong đó có sử dụng VPN giao thức Wireguard:

{
  "description": "Default awall policy for VPS",
  "import": "custom-services",
  "zone": {
    "WAN": { "iface": "eth0" },
    "VPN": { "iface": "wg0" }
  },
  "policy": [
    { "in": "WAN", "action": "drop" },
    { "in": "VPN", "out": "WAN", "action": "accept" },
    { "in": "VPN", "out": "_fw", "action": "accept" },
    { "out": "VPN", "in": "WAN", "action": "accept" },
    { "action": "reject" }
  ],
  "snat": [ { "out": "WAN", "src": "172.16.4.1/24" } ]
}