firewalld のリスナールールと転送ポリシー:それぞれが担う役割
firewalld で外側の通信を許可することと、プライベートなリソースへの到達を認可することは別々のポリシーです。リスナーを開き、そのうえで経路を認可します。
接続はするが何にも届かない VPN は、たいていファイアウォールの問題として説明され、人が手を伸ばす解決策はトンネルのインターフェースを信頼済みゾーンに入れることです。これはトラフィックが流れ始めるという意味では機能しますが、意図したサービスよりはるかに多くを通してしまいます。関わる二つのポリシーは別物で、一方は外側の通信を待ち受けソケットへ通し、もう一方は復号されたトラフィックが特定のリソースに届くことを認可します。両者を一つの設定として扱うことが、狭い許可を広い許可に変えてしまいます。二つは別の場所で決まるので、この間違いはとても起こしやすいのです。
二つのポリシー、一つのトンネル
外側のポリシーは単純な問いに答えます。この送信元からのパケットは、このホストの UDP 1194 に届いてよいか。内側のポリシーは別の問いに答えます。そのトンネルの背後の認証済みクライアントは、このプロトコルで、このポートで、この宛先に届いてよいか。前者はソケットの話であり、後者は経路の話であり、firewalld はそれらを別のオブジェクトで表現します。決まる地点が違うからです。一方はこのホストのソケットの性質であり、もう一方はそこを通る経路の性質です。
実務上の帰結として、動いているトンネルは二つ目のポリシーについて何も語らず、正しい二つ目のポリシーがあっても一つ目が不要になるわけではありません。
実際の外側リスナーを通す
推測するのではなく、すでに割り当てられているものを調べることから始めます。有効なゾーンを読み、実際に受信を運んでいるゾーンを一覧し、インストール済みのサービス定義を確認します。サービス名はポートの集合を表すだけで、このサーバーのリスナーがそれと一致するかどうかは何も語らないからです。
firewall-cmd --get-active-zones
firewall-cmd --zone=public --list-all
firewall-cmd --info-service=openvpnリスナーが本当にそのゾーンの UDP 1194 であるなら、そのポートと通信を具体的に開き、試験したうえで同じ具体的なルールを永続化します。送信元ベースの割り当ても確認します。送信元範囲に結び付いたゾーンは、インターフェースのゾーンが見る前にトラフィックを捕まえることがあるからです。
復号後の宛先を別に認可する
VPN サーバー自身で動くサービスへの接続はローカル入力のポリシーです。LAN 上の別のホストへ転送する接続には転送ポリシーが必要で、カーネルでの転送有効化と戻り経路の三つが別々の要件ですが、人はこれを一つにまとめてしまいがちです。近年の firewalld のポリシーオブジェクトは、入力ゾーンと出力ゾーンの間の方向付きトラフィックを表現するので、どの VPN 送信元がどのプライベートサービスに届いてよいかを書くのに適した場所です。
許可する送信元を明示し、それ以外はすべて拒否に落とします。外側のサービスへの許可はそのポリシーではなく、ゾーンの配置がどう見えても同じです。
インターフェースを信頼することが間違った近道である理由
目標がすべてを受け入れるゾーンにトンネルのインターフェースを入れると、ホストが公開するすべてのサービスへ復号済みトラフィックを通してしまい、確認していないサービスも含まれます。稼働中のマシンで信頼済みゾーンを制限的に作り替えるのはさらに悪い方法です。他のインターフェースや送信元範囲がすでにその意味に依存している可能性があり、編集すると挙動が変わります。狭いポリシーが必要なら新しく作り、共有ゾーンを転用しないでください。
トンネルのゾーン割り当ても、その設定を所有するコンポーネントを通じて安定させてください。再起動で割り当てを失うと、ファイアウォールのルール問題に見えて実際は永続化の問題である障害が生じます。
三つのことを検証する。そのうち一つは拒否
外側の接続を外部から試し、接続済みクライアントから認可済みの内側サービスを一つ試し、到達できないままであるべきサービスを一つ試します。三つ目の試験こそがポリシーと副作用を区別するものであり、すべてが動いているように見えるために人が飛ばしてしまう試験です。拒否されたサービスが応答するなら、あなたはサービスではなくゾーンを通してしまっています。
ゾーン、ポート、通信、ポリシーオブジェクトをサーバーの記録に残します。そうしなければ、このホストへの次の変更も同じ推測から始まります。