Alpine Linuxにfirewall(awall)を入れる

May 17, 2023

linuxAlpineLinuxawall

目次

はじめに

自宅LANに設置する自宅サーバー(AlpineLinuxで稼働)にファイアーウォールを設定します。

通常は自宅LANとWANと繋ぐルータにファイアーウォールが入っているので、自宅サーバーは無防備でもいいという考えもあります。しかし、筆者が愛用しているCentOS7は、デフォルトでファイアーウォールやSELinuxでガチガチにセキュリティを固めていて、なんとなく安心感があるので、裸のAlpineLinuxは漠然と不安に思います。 そこで、AlpineLinuxの標準ファイアーウォールであるawallをインストールし、ファイアーウォールを構築します。

ファイアーウォールに適用するポリシーは、ざっくりと以下の通りです。

  • サーバーの内側から外側(LAN)への通信は自由
  • サーバーの外側(LAN)から内側への通信はサービスを公開しているポートのみに制限
  • それ以外は全て拒絶

要するに、中から外は丸見えだけど、外から中は全然見えない。マジックミラー号のようなものですね。全く見えないと意味が無いので、必要なところにのぞき穴がある、というかんじでしょうか。

awallのインストール

以下の通りip6tablesとawallパッケージをインストールします。このほかに、iptablesも必要なのですが、これはdockerをインストールした際にいっしょに入れたはずなので、dockerがインストール済みの場合は不要。

# apk add ip6tables
# apk add awall

インストール後1回だけ実行

# modprobe ip_tables

ポリシーの定義

ポリシーを定義するファイルを/etc/awall/optional/my-policy.jsonに作成します。

まずはゾーンを定義します。

  • 内側ゾーン: “_fw”
  • 外側ゾーン: “wlan0”

内側ゾーンを規定する”_fw”は固定値で定義不要です。 外側ゾーンはWifiしかないPCだと”wlan0”ですが、有線LANの場合は”eth0”です。

/etc/awall/optional/my-policy.json
  "zone": {
    "LAN": { "iface": "wlan0" }
  },

マジックミラー号ポリシーをコード化すると、次のようになります。

/etc/awall/optional/my-policy.json
  "policy": [
    { "in": "LAN", "action": "drop" },
    { "out": "LAN", "action": "accept" },
    { "in": "_fw", "action": "accept" },
    { "out": "_fw", "action": "accept" },
    { "action": "reject" }
  ]

サービスは/usr/share/awall/mandatory/services.jsonに定義されていますが、独自のWebアプリで使用するなどサイト独自のサービスを制御する場合は、ここに定義します。“webapps”で”http”以外に多数のポートを開けていますが、これは、Webアプリをdocker composeでポートを変えて多数立ち上げているためです。

/etc/awall/optional/my-policy.json
  "service":{
    "avahi-daemon": [
      {"proto": "tcp", "port": 5353}
    ],
    "samba": [
      {"proto": "udp", "port": 137},
      {"proto": "udp", "port": 138},
      {"proto": "tcp", "port": 139},
      {"proto": "tcp", "port": 445}
    ],
    "webapps": [
      {"proto": "tcp", "port": 3000},
      {"proto": "tcp", "port": 3100},
      {"proto": "tcp", "port": 3200},
      {"proto": "tcp", "port": 3300},
      {"proto": "tcp", "port": 5000},
      {"proto": "tcp", "port": 5601},
      {"proto": "tcp", "port": 4040},
      {"proto": "tcp", "port": 8000},
      {"proto": "tcp", "port": 8010},
      {"proto": "tcp", "port": 8020},
      {"proto": "tcp", "port": 8030},
      {"proto": "tcp", "port": 8080},
      {"proto": "tcp", "port": 8888},
      {"proto": "tcp", "port": 9000},
      {"proto": "tcp", "port": 10000}
    ],
    "minidlna": [
      {"proto": "tcp", "port": 8200}
    ],
    "vpn": [
      {"proto": "udp", "port": 500},
      {"proto": "udp", "port": 4500}
    ],
    "elasticsearch": [
      {"proto": "tcp", "port": 9200},
      {"proto": "tcp", "port": 9201},
      {"proto": "tcp", "port": 9300}
    ],
    "openvpn": [
      {"proto": "udp", "port": 55505}
    ]
  },

ここまでの設定では、“LAN”からの”in”は全て”drop”されてしまうので、サービス毎にのぞき穴を開ける必要があります。

例えば、“LAN”からの”http”を通すには以下のような記述になります。

/etc/awall/optional/my-policy.json
  "filter": [
    {
      "in": "LAN",
      "out": "_fw",
      "service": [ "http" ],
      "action": "accept"
    }
  ]

Sambaによるファイル共有を通すには、Sambaで使用するポートをすべて開けて、以下のような記述になります。

/etc/awall/optional/my-policy.json
  "filter": [
    {
      "in": "LAN",
      "out": "_fw",
      "service": [ "avahi-daemon", "samba"],
      "action": "accept"
    }
  ]

サーバで提供するサービスで使用するポートをすべて開けて、ポリシーファイルの全貌は以下のようになりました。

/etc/awall/optional/my-policy.json
{
  "description": "My awall policy;",

  "zone": {
    "LAN": { "iface": "wlan0" }
  },

  "policy": [
    { "in": "LAN", "action": "accept" },
    { "out": "LAN", "action": "accept" },
    { "in": "_fw", "action": "accept" },
    { "out": "_fw", "action": "accept" },
    { "action": "reject" }
  ],

  "service":{
    "avahi-daemon": [
      {"proto": "tcp", "port": 5353}
    ],
    "samba": [
      {"proto": "udp", "port": 137},
      {"proto": "udp", "port": 138},
      {"proto": "tcp", "port": 139},
      {"proto": "tcp", "port": 445}
    ],
    "webapps": [
      {"proto": "tcp", "port": 3000},
      {"proto": "tcp", "port": 3100},
      {"proto": "tcp", "port": 3200},
      {"proto": "tcp", "port": 3300},
      {"proto": "tcp", "port": 3400},
      {"proto": "tcp", "port": 3500},
      {"proto": "tcp", "port": 3600},
      {"proto": "tcp", "port": 5000},
      {"proto": "tcp", "port": 5601},
      {"proto": "tcp", "port": 4040},
      {"proto": "tcp", "port": 8000},
      {"proto": "tcp", "port": 8010},
      {"proto": "tcp", "port": 8020},
      {"proto": "tcp", "port": 8030},
      {"proto": "tcp", "port": 8080},
      {"proto": "tcp", "port": 8888},
      {"proto": "tcp", "port": 9000},
      {"proto": "tcp", "port": 10000}
    ],
    "minidlna": [
      {"proto": "tcp", "port": 8200}
    ],
    "vpn": [
      {"proto": "udp", "port": 500},
      {"proto": "udp", "port": 4500}
    ],
    "elasticsearch": [
      {"proto": "tcp", "port": 9200},
      {"proto": "tcp", "port": 9201},
      {"proto": "tcp", "port": 9300}
    ],
    "openvpn": [
      {"proto": "udp", "port": 55505}
    ]
  },

  "filter": [
    {
      "in": "LAN",
      "service": "ping",
      "action": "accept",
      "flow-limit": { "count": 10, "interval": 6 }
    },
    {
      "in": "LAN",
      "service": "dns",
      "action": "accept"
    },
    {
      "in": "LAN",
      "service": [ "vpn", "openvpn"],
      "action": "accept"
    },
    {
      "in": "LAN",
      "out": "_fw",
      "service": [ "ssh", "avahi-daemon", "samba", "minidlna", "sip"],
      "action": "accept"
    },
    {
      "in": "LAN",
      "out": "_fw",
      "service": [ "http", "webapps", "elasticsearch"],
      "action": "accept"
    }
  ]
}

awall導入前

awallを起動する前に、ALpine Linuxをインストールしただけのときのファイアーウォールがどうなっているのかを見ておきます。

# iptables -n -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DOCKER-USER  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

# ip6tables -n -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

IPv4, IPv6ともinもoutもポリシーがACCEPT。すなわちファイアーウォールが全くない状態であることがわかります。

awallの起動

ポリシーの有効化

# awall enable my-policy
# awall activate -f

ポリシーの無効化

# awall disable my-policy
# awall activate -f

ファイアウォールを起動する

# rc-service iptables start

ポリシーを書き換えたら

# awall activate -f
# rc-service iptables restart

起動時にファイアウォールを自動起動(runlevel=boot)

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

起動時にファイアウォールを自動起動を解除するには

# rc-update delete iptables
# rc-update delete ip6tables

awallの導入後

# iptables -n -L
Chain INPUT (policy DROP)
target     prot opt source               destination
limit-ping-0  icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 8
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate ESTABLISHED
icmp-routing  icmp --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 8
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:53
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 500,4500,55505
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22,5353,139,445,8200,5060
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 137,138,5060
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED helper match "sip"
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 80,3000,3100,3200,3300,5000,5601,4040,8000,8010,8020,8030,8080,8888,9000
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 10000,9200,9201,9300
icmp-routing  icmp --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
logreject-0  all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy DROP)
target     prot opt source               destination
limit-ping-0  icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 8
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate ESTABLISHED
icmp-routing  icmp --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0            icmptype 8
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:53
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 500,4500,55505
icmp-routing  icmp --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
logreject-0  all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate ESTABLISHED
icmp-routing  icmp --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED helper match "sip"
icmp-routing  icmp --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
logreject-0  all  --  0.0.0.0/0            0.0.0.0/0


# apk add ip6tables
# ip6tables -n -L
Chain INPUT (policy DROP)
target     prot opt source               destination
limit-ping-0  ipv6-icmp    ::/0                 ::/0                 ipv6-icmptype 128
ACCEPT     all      ::/0                 ::/0                 ctstate ESTABLISHED
icmp-routing  ipv6-icmp    ::/0                 ::/0                 ctstate RELATED
ACCEPT     all      ::/0                 ::/0
ACCEPT     ipv6-icmp    ::/0                 ::/0                 ipv6-icmptype 128
ACCEPT     tcp      ::/0                 ::/0                 tcp dpt:53
ACCEPT     udp      ::/0                 ::/0                 udp dpt:53
ACCEPT     udp      ::/0                 ::/0                 multiport dports 500,4500,55505
ACCEPT     tcp      ::/0                 ::/0                 multiport dports 22,5353,139,445,8200,5060
ACCEPT     udp      ::/0                 ::/0                 multiport dports 137,138,5060
ACCEPT     all      ::/0                 ::/0                 ctstate RELATED helper match "sip"
ACCEPT     tcp      ::/0                 ::/0                 multiport dports 80,3000,3100,3200,3300,5000,5601,4040,8000,8010,8020,8030,8080,8888,9000
ACCEPT     tcp      ::/0                 ::/0                 multiport dports 10000,9200,9201,9300
ACCEPT     ipv6-icmp    ::/0                 ::/0
ACCEPT     all      ::/0                 ::/0
ACCEPT     all      ::/0                 ::/0
logreject-0  all      ::/0                 ::/0

Chain FORWARD (policy DROP)
target     prot opt source               destination
limit-ping-0  ipv6-icmp    ::/0                 ::/0                 ipv6-icmptype 128
ACCEPT     all      ::/0                 ::/0                 ctstate ESTABLISHED
icmp-routing  ipv6-icmp    ::/0                 ::/0                 ctstate RELATED
ACCEPT     ipv6-icmp    ::/0                 ::/0                 ipv6-icmptype 128
ACCEPT     tcp      ::/0                 ::/0                 tcp dpt:53
ACCEPT     udp      ::/0                 ::/0                 udp dpt:53
ACCEPT     udp      ::/0                 ::/0                 multiport dports 500,4500,55505
icmp-routing  ipv6-icmp    ::/0                 ::/0
ACCEPT     all      ::/0                 ::/0
ACCEPT     all      ::/0                 ::/0
logreject-0  all      ::/0                 ::/0

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all      ::/0                 ::/0                 ctstate ESTABLISHED

IPv4, IPv6ともinもoutもポリシーがDROP、すなわちファイアーウォールですべて遮断に変わり、必要なポートだけが別途ACCEPTとして追加されています。

まとめ

AlpineLinuxのファイアーウォールを設定する方法を紹介しました。


Written by questions6768 who lives in Uji, Kyoto.