「ufw enableしたから安全」と思い込んで、実は穴が空いたままのUbuntuサーバーは珍しくありません。UFW(Uncomplicated Firewall)は設定を簡単にする代わりに、内部で実際に通信を制御しているiptables(またはnftables)との間にズレが生まれやすい構造になっています。この記事では、Ubuntu 24.04を基準に ufw status verbose と iptables -L -n の出力を実際に突き合わせて、「有効にしたつもり」の設定漏れを自分で見分ける手順をまとめます。
UFWは「有効」でも穴が空くことがある理由
UFWは自分でパケットを処理しているわけではなく、Linuxカーネルのパケットフィルタ(iptables/nftables)にルールを書き込むための操作しやすい窓口(フロントエンド)です。つまり「UFWの設定」と「実際にカーネルが使っているルール」は別物で、両者がズレていてもufw statusは平気で「active」と表示し続けます。
穴が空く典型パターン
パターン | 何が起きるか |
|---|---|
Dockerが動いている | Dockerは自分でiptablesに |
IPv6を見落とす |
|
他のツールが直接iptablesを書き換える | 導入したミドルウェアやインストールスクリプトがUFWを経由せず直接ルールを追加し、UFW側の一覧には出てこない |
UFWの再起動漏れ | ルール変更後にリロードし忘れ、古いルールが残ったまま新ルールと混在する |
sudo ufw status verboseで自分が設定したルールを確認する
まず「自分がUFWにどう指示したか」を確認します。
sudo ufw status verboseこのコマンドは、UFWが記憶している許可・拒否ルールと、デフォルトポリシー(何も一致しなかった通信をどう扱うか)を表示します。sudoが必要ですが、設定を変更するコマンドではないため何度実行しても安全です。
出力例:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80,443/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80,443/tcp (v6) ALLOW IN Anywhere (v6)判断基準は次の2点です。
Status: activeになっているか(inactiveならUFW自体が動いていないので、下の突き合わせ以前の問題)Default: deny (incoming)になっているか。ここがallow (incoming)だと、許可ルールに書いていないポートまで全部開いている状態
この一覧に見覚えのないポートが並んでいたら、それは「UFW側で誰かが許可した」記録です。まずsudo ufw status numberedで番号を確認し、心当たりがなければsudo ufw delete [番号]で削除します(削除もUFW経由の操作なので取り消しやすく、後から同じルールをufw allowで入れ直せば元に戻せます)。
sudo iptables -L -nで実際に効いているルールを確認する
次に「カーネルが実際に何を通しているか」を確認します。
sudo iptables -L -n-Lは現在のルール一覧表示、-nはホスト名やサービス名を名前解決せず数値のまま表示するオプションです(名前解決を待つと表示が遅くなるため、点検用途では-nを付けるのが基本)。
出力例(UFW管理下の場合、INPUTチェーンからufw独自のチェーンに処理が渡る形になります):
Chain INPUT (policy DROP)
target prot opt source destination
ufw-before-input all -- 0.0.0.0/0 0.0.0.0/0
ufw-after-input all -- 0.0.0.0/0 0.0.0.0/0
Chain ufw-user-input (1 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443判断基準は次の2点です。
- 1行目
Chain INPUT (policy DROP)のpolicyがDROPかREJECTになっているか(ACCEPTになっていたら、UFWが「deny」と言っていてもカーネルレベルでは全通しの状態) ufw-user-inputチェーン以外の場所(DOCKERや独自チェーン名)に、見覚えのないACCEPTルールが挟まっていないか
iptables -Lはnftables経由の表示になっている点に注意
Ubuntu 24.04以降、iptablesコマンドはデフォルトでnftablesバックエンド(iptables-nft)を使う互換シムになっています。sudo iptables -Vを実行して
iptables v1.8.10 (nf_tables)のように末尾が(nf_tables)となっていれば、実体はnftablesのルールセットです。より正確に見たい場合はsudo nft list rulesetで直接nftables側の全ルールを確認できます。Canonicalが2026年4月にリリースしたUbuntu 26.04 LTSはセキュリティ強化を掲げる中でnftables系ツールへの依存をさらに強める方向にあり、24.04環境でも「iptablesコマンドの裏側はnftables」という前提で見ておくと今後の移行でも読み方に迷いません。
2つを突き合わせて「穴」を見分ける
ufw status verboseとiptables -L -nを並べて、次の対応関係が崩れていないかを確認します。
確認項目 | ufw status verboseでの表示 | iptables -L -nでの対応 | ズレていたら |
|---|---|---|---|
デフォルトポリシー | Default: deny (incoming) | Chain INPUT (policy DROP) | iptables側がACCEPTなら、他のツールがポリシーを書き換えている |
個別ポートの許可 | To の一覧に載っているポート | ufw-user-inputチェーン内のACCEPT行 | ufw側に無いのにiptables側にACCEPTがあれば、UFWを経由しない野良ルール |
IPv4/IPv6 | 末尾に(v6)と付く行の有無 | ip6tables -L -nの出力 | ufwでv6の許可を出していないのにip6tables側で開いていれば要調査 |
Docker公開ポート | UFWのルールに記載なし | DOCKER-USER・DOCKERチェーンにACCEPT | UFWで塞いだつもりのポートがコンテナ経由で外部に開いている典型例 |
ズレを見つけたときの次の一手は次の通りです。
- そのポートやIPで待ち受けているプロセスを
sudo ss -tulpnで特定し、心当たりのあるサービスかを確認する - 身に覚えのない許可ルールであれば、追加した記憶のあるツール(Docker・Snap・VPNソフトなど)の設定変更履歴を洗う
- Dockerが原因の場合は、UFWとDockerの競合は既知の問題として広く報告されているため、対応方法(DOCKER-USERチェーンでの制御やdaemon.jsonでのiptables管理設定変更など)を調べてから対処する。勢いで削除するとコンテナの外部公開自体が止まる場合がある
ログイン試行の点検も合わせて行いたい場合は、journalctlでSSH侵入後のauthorized_keys改ざん確認2026/8の手順で認証ログ側の異常有無も確認しておくと、ファイアウォールの穴が実際に悪用された形跡がないかまで一通り点検できます。
確認だけなら安全。設定変更するときの注意
ufw status verboseとiptables -L -nはどちらも表示コマンドで、システムの設定を一切変更しません。sudoは必要ですが、何度実行しても安全です- ルールを削除・変更する場合は、必ず今の状態を保存してから行います:
sudo iptables-save > ~/iptables_backup_$(date +%Y%m%d).rulesで保存し、戻したいときはsudo iptables-restore < ~/iptables_backup_日付.rulesで復元できます - UFW側の変更で不安な場合は
sudo ufw disableでいったん無効化してから作業し、sudo ufw enableで戻す、という切り戻し手順を用意しておくと安心です。ただし無効化中は無防備な状態になるため、作業は手短に済ませます - SSH接続で作業している場合、ルール変更でSSHポート自体を塞いでしまうと接続が切れて元に戻せなくなります。変更前に別ウィンドウでもう1つSSHセッションを開いておくか、コンソール(VNC等)からアクセスできる状態を確保してから作業してください
Debianや他ディストリでの違い
- Debianには標準でUFWが入っていないため、
sudo apt install ufwでインストールする必要があります(Ubuntuはデフォルトで導入済み) - iptablesがiptables-legacyとiptables-nftのどちらで動いているかは環境によって異なるため、
sudo update-alternatives --list iptablesで確認できます。legacy側で動いている環境ではnft list rulesetには何も表示されない点に注意してください - firewalldを使っている場合(RHEL系に多い)は、UFWではなく
sudo firewall-cmd --list-allとiptables -L -n(またはnft list ruleset)の突き合わせに読み替えます
他の設定漏れが心配な場合は、sudo -lとNOPASSWDを点検2026年8月版もあわせて確認しておくと、権限まわりの見落としも一通りカバーできます。
まとめ
UFWの「active」表示は、あくまでUFW自身が把握しているルールが有効という意味であり、カーネルが実際に処理しているルールと一致している保証ではありません。sudo ufw status verboseで自分の設定意図を確認し、sudo iptables -L -n(Ubuntu 24.04以降は実体がnftablesの互換表示である点に注意)で実際の適用状況を確認して、両者のポリシーとポート一覧を突き合わせる習慣をつけることで、Docker連携や野良ルールによる「開けたつもりが開いていない/塞いだつもりが塞がっていない」を自分で発見できます。確認作業自体はシステムを変更しないため、まずは今の環境で両方のコマンドを実行し、表の対応関係を照らし合わせるところから始めてみてください。