
QubesOS向けの最小限のユニカーネルファイアウォールで、ネットワークトラフィックをフィルタリングし、NATを実装し、Qubes DBとqrexecを介して通信します。
QubesOS の ProxyVM として実行でき、sys-firewall を置き換えるユニカーネルです。mirage-qubes ライブラリを使用して Qubes プロトコルを実装しています。
詳細は A Unikernel Firewall for QubesOS を参照してください。
ビルド済みバイナリは リリースページ から入手できます。インストール手順については、以下の デプロイ セクションを参照してください。
注: 最も確実なビルド方法は Docker または Podman を使うことです。Fedora 42 はこれに適しています。Debian 12 でも動作しますが、Docker を入手するには docker.com の指示に従う必要があります(Debian 版の Docker は使わないでください)。
新しい Fedora-42 AppVM を作成するか(既存のものを再利用しても構いません)、Qube の設定(基本 / ディスクストレージ)でプライベートストレージの最大サイズをデフォルトの 2048 MiB から 8192 MiB に増やしてください。ターミナルを開きます。
この Git リポジトリをクローンし、引数に docker または podman を指定して build-with.sh スクリプトを実行します(注: 新しい SELinux ポリシーを備えた Fedora では、docker イメージをホームディレクトリに通常どおり保持できないため、chcon の呼び出しが必須です):
mkdir /home/user/docker
sudo ln -s /home/user/docker /var/lib/docker
sudo chcon -Rt container_file_t /home/user/docker
sudo dnf install docker
sudo systemctl start docker
git clone https://github.com/mirage/qubes-mirage-firewall.git
cd qubes-mirage-firewall
sudo ./build-with.sh docker
または
sudo systemctl start podman
git clone https://github.com/mirage/qubes-mirage-firewall.git
cd qubes-mirage-firewall
./build-with.sh podman
私のラップトップではこれに約 15 分かかりました(再度実行するとはるかに速くなります)。先頭のシンボリックリンクの手順は、ビルド VM がスタンドアロンの場合は不要です。Docker により多くのディスク容量を与え、Qube を再起動しても Docker イメージキャッシュが失われないようにします。Podman ではコンテナがデフォルトでホームディレクトリ内に置かれるため、この手順は不要です。
注: オブジェクトファイルは _build ディレクトリに保存され、インクリメンタルビルドを高速化します。依存関係を変更した場合は、再ビルドする前にこのディレクトリを削除する必要があります。
再起動後も残したい場合は、テンプレート VM に Docker または Podman パッケージをインストールしても問題ありません。ただし、ファイアウォール自体のビルドは通常の AppVM で行う必要があります。
通常の Mirage ユニカーネルと同様に、このスクリプトを使わずにビルドすることもできます。詳細は Mirage のインストール手順 を参照してください。
ビルドスクリプトは使用するライブラリのバージョンを固定するため、リリースに含まれるものとまったく同じバイナリが得られます。これを使わずにビルドすると、代わりに最新バージョンに対してビルドされるため(ハッシュはおそらく一致しません)、それでも問題なく動作するはずです。
手動でデプロイする場合は、domU で qubes-firewall.xen と qubes-firewall.sha256 をダウンロードし、.xen ファイルに対応するハッシュサムがあることを確認するだけです。qubes-firewall.xen がユニカーネル本体であり、dom0 の /var/lib/qubes/vm-kernels/mirage-firewall ディレクトリ内の vmlinuz にコピーする必要があります。例(dev がビルドした AppVM の場合):
[tal@dom0 ~]$ mkdir -p /var/lib/qubes/vm-kernels/mirage-firewall/
[tal@dom0 ~]$ cd /var/lib/qubes/vm-kernels/mirage-firewall/
[tal@dom0 mirage-firewall]$ qvm-run -p dev 'cat mirage-firewall/qubes-firewall.xen' > vmlinuz
上記で追加した mirage-firewall カーネルを使用して mirage-firewall VM を作成するには、dom0 で次のコマンドを実行します。
qvm-create \
--property kernel=mirage-firewall \
--property kernelopts='' \
--property memory=32 \
--property maxmem=32 \
--property netvm=sys-net \
--property provides_network=True \
--property vcpus=1 \
--property virt_mode=pvh \
--property audiovm='' \
--label=green \
--class StandaloneVM \
mirage-firewall
qvm-features mirage-firewall qubes-firewall 1
qvm-features mirage-firewall no-default-kernelopts 1
qvm-features mirage-firewall skip-update 1
Qubes での salt ステートの実行方法に精通しているなら、スクリプト SaltScriptToDownloadAndInstallMirageFirewallInQubes.sls を使って、Qubes OS に最新版の mirage firewall を自動デプロイすることもできます。入門編は こちら と こちら にあります。前者のリンクの指示に従うと、dom0 で sudo qubesctl --show-output state.apply SaltScriptToDownloadAndInstallMirageFirewallInQubes saltenv=user コマンドを実行できます。このスクリプトは、統合サーバーからチェックサムを取得し、GitHub リリースで提供されている最新バージョンと比較します。デフォルトのテンプレートに curl と tar ツールがデフォルトでインストールされていない場合、mirage ユニカーネルのダウンロードに使用するスクリプト内の VM テンプレートを調整する必要があるかもしれません。また、ユニカーネルを使用する VM を変更するか、"Qubes Global Settings" を調整することを忘れないでください。
以前のリリースからアップグレードするには、/var/lib/qubes/vm-kernels/mirage-firewall/vmlinuz を新しいバージョンで上書きし、ファイアウォール VM を再起動するだけです。
mirage-firewall は既存の sys-firewall と並行して実行でき、GUI を使ってどの AppVM がどのファイアウォールを使用するかを選択できます。AppVM がこれを使用するように設定するには、GUI でアプリ VM の設定に移動し、NetVM を default (sys-firewall) から mirage-firewall に変更します。
dom0 で次のコマンドを実行して設定することもできます(my-app-vm は AppVM の名前に置き換えてください):
qvm-prefs --set my-app-vm netvm mirage-firewall
あるいは、mirage-firewall をデフォルトのファイアウォール VM として設定することもできます。
デフォルトでは、dom0 は「UpdateVM」(アップデートをダウンロードするためのプロキシ)として sys-firewall を使用していることに注意してください。mirage-firewall はこの用途には使用できませんが、Linux VM であればどれでも問題ありません。https://www.qubes-os.org/doc/software-update-dom0/ には次のようにあります:
UpdateVM の役割は、Qubes VM Manager の任意の VM に割り当てることができ、 この選択に重大なセキュリティへの影響はありません。デフォルトでは、 この役割は firewallvm に割り当てられています。
OpenBSD は現在 netvm として使用できないため、BSD を sys-net VM として使用したい場合は、その netvm を qubes-mirage-firewall に設定する必要があります(詳細は https://github.com/mirage/qubes-mirage-firewall/issues/146 を参照)。つまり、AppVMs -> qubes-mirage-firewall <- OpenBSD という構成になり、矢印は netvm プロパティの設定を表します。
その場合、どの AppVM クライアントをアップリンクとして使用するかを qubes-mirage-firewall に指定する必要があります:
qvm-prefs --set mirage-firewall -- kernelopts '--ipv4=X.X.X.X --ipv4-gw=Y.Y.Y.Y'
ここで X.X.X.X は mirage-firewall の IP アドレス、Y.Y.Y.Y は OpenBSD HVM の IP アドレスです。
この図は主要コンポーネントを示しています(各ボックスは同じ名前のソース .ml ファイルに対応します):
イーサネットフレームは、クライアントキューブ(work や personal など)または sys-net から到着します。インターネット(IP)パケットは firewall に送られ、NAT テーブルと QubesDB のルールを参照してパケットをどう処理するかを決定します。転送すべき場合は、router を使用して選択した宛先に送信します。client_net は dom0 が提供する XenStore データベースを監視し、クライアントを追加または削除する必要があるタイミングを検出します。
起動プロセス:
config.ml は、使用するライブラリと静的設定(NAT テーブルサイズ)を記述します。mirage ツールはこれを使って main.ml を生成します。main.ml は config.ml で選択されたドライバを初期化し、unikernel.ml の start 関数を呼び出します。unikernel.ml は Qubes エージェントに接続し、ネットワーキングコンポーネントをセットアップして、シャットダウン要求を待ちます。開発には、test-mirage スクリプトを使用して、開発 AppVM からユニカーネル(qubes-firewall.xen)をデプロイします。初回はセットアップに少し時間がかかりますが、その後ははるかに速くなります。例:
[user@dev ~]$ test-mirage dist/qubes-firewall.xen mirage-firewall
Waiting for 'Ready'... OK
Uploading 'dist/qubes-firewall.xen' (7454880 bytes) to "mirage-test"
Waiting for 'Booting'... OK
Connecting to mirage-test console...
Solo5: Xen console: port 0x2, ring @0x00000000FEFFF000
| ___|
__| _ \ | _ \ __ \
\__ \ ( | | ( | ) |
____/\___/ _|\___/____/
Solo5: Bindings version v0.7.3
Solo5: Memory map: 32 MB addressable:
Solo5: reserved @ (0x0 - 0xfffff)
Solo5: text @ (0x100000 - 0x319fff)
Solo5: rodata @ (0x31a000 - 0x384fff)
Solo5: data @ (0x385000 - 0x53ffff)
Solo5: heap >= 0x540000 < stack < 0x2000000
2022-08-13 14:55:38 -00:00: INF [qubes.rexec] waiting for client...
2022-08-13 14:55:38 -00:00: INF [qubes.db] connecting to server...
2022-08-13 14:55:38 -00:00: INF [qubes.db] connected
2022-08-13 14:55:38 -00:00: INF [qubes.db] got update: "/mapped-ip/10.137.0.20/visible-ip" = "10.137.0.20"
2022-08-13 14:55:38 -00:00: INF [qubes.db] got update: "/mapped-ip/10.137.0.20/visible-gateway" = "10.137.0.23"
2022-08-13 14:55:38 -00:00: INF [qubes.rexec] client connected, using protocol version 3
2022-08-13 14:55:38 -00:00: INF [unikernel] QubesDB and qrexec agents connected in 0.041 s
2022-08-13 14:55:38 -00:00: INF [dao] Got network configuration from QubesDB:
NetVM IP on uplink network: 10.137.0.4
Our IP on uplink network: 10.137.0.23
Our IP on client networks: 10.137.0.23
DNS resolver: 10.139.1.1
DNS secondary resolver: 10.139.1.2
2022-08-13 14:55:38 -00:00: INF [net-xen frontend] connect 0
2022-08-13 14:55:38 -00:00: INF [net-xen frontend] create: id=0 domid=1
2022-08-13 14:55:38 -00:00: INF [net-xen frontend] sg:true gso_tcpv4:true rx_copy:true rx_flip:false smart_poll:false
2022-08-13 14:55:38 -00:00: INF [net-xen frontend] MAC: 00:16:3e:5e:6c:00
2022-08-13 14:55:38 -00:00: INF [ethernet] Connected Ethernet interface 00:16:3e:5e:6c:00
2022-08-13 14:55:38 -00:00: INF [ARP] Sending gratuitous ARP for 10.137.0.23 (00:16:3e:5e:6c:00)
2022-08-13 14:55:38 -00:00: INF [ARP] Sending gratuitous ARP for 10.137.0.23 (00:16:3e:5e:6c:00)
2022-08-13 14:55:38 -00:00: INF [udp] UDP layer connected on 10.137.0.23
2022-08-13 14:55:38 -00:00: INF [dao] Watching backend/vif
2022-08-13 14:55:38 -00:00: INF [memory_pressure] Writing meminfo: free 20MiB / 27MiB (72.68 %)
ファイアウォールをテストするユニカーネルは test/ サブディレクトリにあります。これを使うには、test.sh を実行し、指示に従ってテスト環境をセットアップしてください。
ファイアウォールに影響するセキュリティアドバイザリについては、security タグが付いた issue を参照してください。
LICENSE.md を参照してください。