Alpine Linuxにfirewall(awall)を入れる
May 17, 2023
linux AlpineLinux awall目次
はじめに
自宅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”です。
"zone": {
"LAN": { "iface": "wlan0" }
},
マジックミラー号ポリシーをコード化すると、次のようになります。
"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でポートを変えて多数立ち上げているためです。
"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”を通すには以下のような記述になります。
"filter": [
{
"in": "LAN",
"out": "_fw",
"service": [ "http" ],
"action": "accept"
}
]
Sambaによるファイル共有を通すには、Sambaで使用するポートをすべて開けて、以下のような記述になります。
"filter": [
{
"in": "LAN",
"out": "_fw",
"service": [ "avahi-daemon", "samba"],
"action": "accept"
}
]
サーバで提供するサービスで使用するポートをすべて開けて、ポリシーファイルの全貌は以下のようになりました。
{
"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のファイアーウォールを設定する方法を紹介しました。