メモのページ - チラシの裏メモ 3枚目

通信技術や気になった事を黙々とメモし続ける

Alpine LinuxでAwallを使ってiptables設定

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編