Alpine Linuxのiptablesは他のディストリビューションと同じくiptablesコマンドを何行も書いたり/etc/sysconfig/iptablesファイルを編集して設定する方法だけでなく、Awallという設定ツールを使用して設定する方法も有る。
今回は、Androidスマホ内で動作するAlpine LinuxにてAwallを使ってiptablesの設定した。
当方の環境
・スマホ(ホスト機):SONY Xperia XZ2 / Android OS 9
・ホスト機の通信環境:WLANと4G回線
・エミュレータ:Limbo PC Emulator 2.10.0
・ゲストOS:alpine-virt-3.14.3-x86.iso
・ソフトウェアキーボード:Androidアプリの「Hacker's Keyboard」
※スマホ内で動作するAlpine LinuxにMacBook Airからsshでログインし設定投入した。
※勿論、VirtualBoxやVMware WorkstationにデプロイしたAlpine Linuxでも当記事の内容で設定可能。
Awallとは?
iptablesの軽量な管理フレームワークであるAlpine Wall(Awall)の事。Red HatやCentOSで言うFirewalldのようなツール。
Awallはデータモデル、バックエンド、フロントエンドの3つの主要なコンポーネントで構成されている。
データモデルは、設定ファイルを読み込みiptablesのユーティリティを利用し要件に沿うようにFirewallを構成する。
バックエンドは、jsonやYAMLで書かれた設定をiptablesのルールに変換する。フレームワークには、基本モデルを解釈するためのモジュールが含まれている。
フロントエンドは、バックエンドを使用してデータモデルを編集し変更を有効化する。また、変更した後に構成を検証および有効化するためのコマンドラインツールを提供する。
Awallの設定ファイルの構成
awallの設定ファイルはjsonで書かれている。設定ファイルは/etc/awall/private/ディレクトリ内と/etc/awall/optional/ディレクトリ内に置く。
/etc/awall/private/base.json
/etc/awall/optional/hogehoge.json
base.jsonでインターフェース毎にゾーン設定、ゾーンに対し基本的なポリシー(AcceptやDropやRejectなど)を設定する。
hogehoge.jsonでFTPやSSH等サービス毎に詳細なポリシーを設定する。※ここではhogehoge.jsonと書いているが、ssh.jsonやftp.json等何のポリシーを書いているか分かりやすいようなファイル名にする。
自分の場合、以下のファイル構成となった。base.json以外は任意でファイル名を決める事が出来るようだ。
/etc/awall/private/base.json:ゾーンや基本的なポリシーの設定
/etc/awall/optional/ssh.json:ssh接続のポリシー設定
/etc/awall/optional/ftp.json:ftp接続のポリシー設定
/etc/awall/optional/ping.json:pingの応答に対するポリシー設定
/etc/awall/optional/main.json:optionalディレクトリ配下のポリシー設定を有効にする
/etc/awall/optional/drop.json:dropする対象を明示的に定義するポリシー設定
当作業の流れ
大まかに分けて、以下の5つの手順を上から順に進めていく事になる。
・iptablesとAwallのインストール
・iptablesの有効化
・ポリシーファイルの作成
・ポリシーの有効化
・設定したポリシーをiptablesに反映
iptablesとAwallのインストール
では早速、Awallを使ったiptablesの設定の手順に進む。
Alpine Linuxのデプロイ直後はAwallやiptablesだけでなくSELinux等のツールもインストールされていない。
以下のコマンドを打ち、iptablesとAwallをインストールする。
# apk add iptables awall
iptablesの有効化
iptablesとAwallのインストール後、modprobeコマンドとrc-updateコマンド(他のディストリビューションで言うとsystemctl)を打ち、iptablesを有効にする。
# modprobe ip_tables # rc-update add iptables
各ポリシー設定ファイルの内容
/etc/awall/private/base.json
Awallとiptablesの準備が出来たところで、jsonでポリシーを書く。
まずは最初に、Zoneとデフォルトのポリシーを定義する。
自分の環境では外部との接続はNATでIPアドレスが変換される為、外部から見ての変換後のIPアドレス10.0.2.0/24だけで良いかも知れない。
外部から流れてくるパケットはデフォルトで破棄(drop)し、それ以外のパケットは許可(accept)する内容となっている。
LANは外部と接続するインタフェースeth0を示し、_fwはsshやftp等Alpine Linux内部で動作するサービスと接続するインタフェースを示す。
{ "description": "Base zones and policies", "zone": { "LAN": { "iface": "eth0", "addr": ["10.0.2.0/24","192.168.3.0/24"] } }, "policy": [ { "in": "LAN", "action": "drop" }, { "out": "LAN", "action": "accept" }, { "in": "_fw", "action": "accept" }, { "out": "_fw", "action": "accept"} ] }
Alpine LinuxがNICを複数持っていて、NIC1からNIC2にパケットを転送させるようなポリシーを作成する必要が有る場合、"zone": 内の定義を複数行書く。
勿論、"policy":内も行を追加する。
/etc/awall/optional/ssh.json
ここからは各サービス毎にポリシーを書く。
当ファイルにてsshのポリシーを定義。外部接続のインタフェースeth0から受信したパケットがsshサービスに流れる事を許可する内容になっている。
conn-limitの行は、60秒間に10回までしかパケットを許可しない事を示す。
{ "description": "Allow rate-limited SSH on eth0", "filter": [ { "in": "LAN", "out": "_fw", "service": "ssh", "action": "accept", "conn-limit": { "count": 10, "interval": 60 } } ] }
/etc/awall/optional/ftp.json
当ファイルにてftpのポリシーを定義。
外部接続のインタフェースeth0から受信したパケットがFTPサービスに流れる事を許可する内容になっている。
{ "description": "Allow FTP on eth0", "filter": [ { "in": "LAN", "out": "_fw", "service": "ftp", "action": "accept" } ] }
/etc/awall/optional/ping.json
当ファイルにてpingのポリシーを定義。
外部接続のインタフェースeth0から受信したパケットがpingサービスに流れる事を許可する内容になっている。
(pingサービスという表現に違和感を覚えるが...)
conn-limitの行は、1秒間に10回までしかパケットを許可しない事を示す。
{ "description": "Allow rate-limited ping on eth0", "filter": [ { "in": "LAN", "out": "_fw", "service": "ping", "action": "accept", "flow-limit": { "count": 10, "interval": 1 } } ] }
/etc/awall/optional/drop.json
当ファイルにて、破棄したい送信元IPアドレスを明示的に指定。
当環境では不要な気がするが、/etc/awall/private/base.jsonにて定義したネットワークアドレスの中から通信を破棄したいIPアドレスをここで指定する...という事が出来る。
{ "description": "Sample awall policy; copy to /etc/awall to use", "filter": [ { "src": [ "192.168.1.0"/24,"192.168.2.0/24","192.168.3.5,"192.168.3.6", "192.168.3.7","192.168.3.8","192.168.3.9" ], "action": "drop" } ] }
/etc/awall/optional/main.json
当ファイルにて、optionalディレクトリ配下のポリシー設定を有効にする。
サービス毎にファイルを分ける事は必須ではないようで、下記リンク先では1つのファイルにまとめて記載している例も有るが、自分の場合はAlpine Linuxの公式サイトの記載内容に従って作成した。
{ "description": "Main firewall", "import": [ "base", "ftp", "ssh", "drop" ] }
設定したポリシーの有効化
以下のコマンドを打ち、上記にて作成した各ポリシーを有効にする。
awall listコマンドで有効になっているか確認する事が出来る。
ssh.jsonやftp.json等の設定ファイルにてdescriptionを記載すると、awall listコマンドの出力内容の右側に表示させる事が出来る。
# awall enable main # awall enable ftp # awall enable ssh # awall enable ping # awall enable drop # awall list drop enabled Sample awall policy; copy to /etc/awall to use ftp enabled Allow FTP on eth0 main enabled Main firewall ping enabled Allow rate-limited ping on eth0 ssh enabled Allow rate-limited SSH on eth0
設定したポリシーをiptablesに反映
以下のコマンドを打ち、上記で設定した各ポリシーをiptablesに反映させる。
Press RETURN to commit changes permanently:が出力されたらEnterキーを叩き、設定内容を反映させる。
# awall translate -V # awall activate Warning: firewall not enabled for inet6 New firewall configuration activated Press RETURN to commit changes permanently:
iptablesの再起動
awall translate -Vコマンドとawall activateコマンドで設定内容をiptablesに反映させた後は、rc-service iptables restartコマンドでiptablesを一旦再起動させる。
ここまで来ると、Awallで設定した内容が反映されたかたちでiptablesはパケットフィルタリングを実行する。
# rc-service iptables restart * Disabling forwarding ... [ ok ] * Saving iptables state ... [ ok ] * Stopping firewall ... [ ok ] * Loading iptables state and starting firewall ... [ ok ] * Enabling forwarding ... [ ok ] #
これで、awallを使ったiptablesの設定は完了。
awallで設定した内容は、iptables -Lコマンドを打つ事によりiptablesに反映されている事を確認出来る。
また、vオプションでパケットのカウンタ、nオプションでサービス名を数値(ポート番号)で出力する。
# iptables -L -v -n Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 limit-ping-0 icmp -- eth0 * 192.168.3.0/24 0.0.0.0/0 icmptype 8 0 0 limit-ping-0 icmp -- eth0 * 10.0.2.0/24 0.0.0.0/0 icmptype 8 3577 1143K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate ESTABLISHED 0 0 icmp-routing icmp -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.3 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.38 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.39 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.40 0.0.0.0/0 0 0 logdrop-0 all -- * * 198.51.100.0/24 0.0.0.0/0 0 0 logdrop-0 all -- * * 203.0.113.0/30 0.0.0.0/0 0 0 logdrop-0 all -- * * 203.0.113.6/31 0.0.0.0/0 0 0 ACCEPT tcp -- eth0 * 10.0.2.0/24 0.0.0.0/0 tcp dpt:21 10 440 ACCEPT tcp -- eth0 * 192.168.3.0/24 0.0.0.0/0 tcp dpt:21 0 0 ACCEPT all -- eth0 * 10.0.2.0/24 0.0.0.0/0 ctstate RELATED helper match "ftp" 0 0 ACCEPT all -- eth0 * 192.168.3.0/24 0.0.0.0/0 ctstate RELATED helper match "ftp" 0 0 ACCEPT icmp -- eth0 * 10.0.2.0/24 0.0.0.0/0 icmptype 8 0 0 ACCEPT icmp -- eth0 * 192.168.3.0/24 0.0.0.0/0 icmptype 8 0 0 ACCEPT tcp -- eth0 * 10.0.2.0/24 0.0.0.0/0 tcp dpt:22 9 392 ACCEPT tcp -- eth0 * 192.168.3.0/24 0.0.0.0/0 tcp dpt:22 0 0 icmp-routing icmp -- * * 0.0.0.0/0 0.0.0.0/0 0 0 logdrop-1 all -- eth0 * 10.0.2.0/24 0.0.0.0/0 0 0 logdrop-1 all -- eth0 * 192.168.3.0/24 0.0.0.0/0 0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate ESTABLISHED 0 0 icmp-routing icmp -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED 0 0 logdrop-0 all -- * * 192.0.2.3 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.38 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.39 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.40 0.0.0.0/0 0 0 logdrop-0 all -- * * 198.51.100.0/24 0.0.0.0/0 0 0 logdrop-0 all -- * * 203.0.113.0/30 0.0.0.0/0 0 0 logdrop-0 all -- * * 203.0.113.6/31 0.0.0.0/0 0 0 icmp-routing icmp -- * * 0.0.0.0/0 0.0.0.0/0 0 0 logdrop-1 all -- eth0 * 10.0.2.0/24 0.0.0.0/0 0 0 logdrop-1 all -- eth0 * 192.168.3.0/24 0.0.0.0/0 0 0 ACCEPT all -- * eth0 0.0.0.0/0 10.0.2.0/24 0 0 ACCEPT all -- * eth0 0.0.0.0/0 192.168.3.0/24 Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 2725 514K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate ESTABLISHED 0 0 icmp-routing icmp -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.3 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.38 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.39 0.0.0.0/0 0 0 logdrop-0 all -- * * 192.0.2.40 0.0.0.0/0 0 0 logdrop-0 all -- * * 198.51.100.0/24 0.0.0.0/0 0 0 logdrop-0 all -- * * 203.0.113.0/30 0.0.0.0/0 0 0 logdrop-0 all -- * * 203.0.113.6/31 0.0.0.0/0 0 0 ACCEPT all -- * eth0 0.0.0.0/0 10.0.2.0/24 ctstate RELATED helper match "ftp" 0 0 ACCEPT all -- * eth0 0.0.0.0/0 192.168.3.0/24 ctstate RELATED helper match "ftp" 0 0 icmp-routing icmp -- * * 0.0.0.0/0 0.0.0.0/0 8 546 ACCEPT all -- * eth0 0.0.0.0/0 10.0.2.0/24 0 0 ACCEPT all -- * eth0 0.0.0.0/0 192.168.3.0/24 1 60 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 Chain icmp-routing (6 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 3 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 11 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 12 Chain limit-ping-0 (2 references) pkts bytes target prot opt in out source destination 0 0 logdrop-ping-0 all -- * * 0.0.0.0/0 0.0.0.0/0 recent: UPDATE seconds: 6 hit_count: 10 name: limit-ping-0 side: source mask: 255.255.255.255 0 0 all -- * * 0.0.0.0/0 0.0.0.0/0 recent: SET name: limit-ping-0 side: source mask: 255.255.255.255 Chain logdrop-0 (21 references) pkts bytes target prot opt in out source destination 0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 1/sec burst 5 LOG flags 0 level 4 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 Chain logdrop-1 (4 references) pkts bytes target prot opt in out source destination 0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 1/sec burst 5 LOG flags 0 level 4 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 Chain logdrop-ping-0 (1 references) pkts bytes target prot opt in out source destination 0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 1/sec burst 5 LOG flags 0 level 4 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 #
Alpine Linuxの情報源等
https://alpinelinux.org/ Alpine Linux
https://wiki.alpinelinux.org/wiki/Main_Page Alpine Linux Wiki
Awallの情報源
https://wiki.alpinelinux.org/wiki/Alpine_Wall Alpine Wall
https://wiki.alpinelinux.org/wiki/How-To_Alpine_Wall How-To Alpine Wall
https://wiki.alpinelinux.org/wiki/Zero-To-Awall Zero-To-Awall
https://saturday-in-the-park.netlify.app/AlpineLinux/08_firewall/ Alpine Linuxにfirewall(awall)を入れる
https://ma-tech.centurysys.jp/doku.php?id=mae3xx_tips:use_awall_instead_of_firewalld:start awall (Alpine Wall) を使う
https://www.hiroom2.com/2017/08/20/alpinelinux-3-6-awall-ja/ AlpineLinux 3.6: awallでファイアウォール制御
http://miimou.mydns.jp/post/2018/10/06t12-54/ awallによるファイアウォール
Alpine Linuxに関する記事
https://debslink.hatenadiary.jp/entry/20200418/1587204948 AndroidスマホでAlpine Linuxを動かす
https://debslink.hatenadiary.jp/entry/20200506/1588733149 Androidスマホで動作するAlpine LinuxにてFTPサーバを構築
https://debslink.hatenadiary.jp/entry/20211024/1635075047 Alpine Linuxの保守用コマンド
https://debslink.hatenadiary.jp/entry/20220101/1640973274 Alpine LinuxのFTPで暗号化通信 FTPS編
https://debslink.hatenadiary.jp/entry/20220111/1641903376 Alpine LinuxのFTPで暗号化通信 SFTP編