UFW はファイアウォールを三つのコマンドで設定できるように考え出されたもので、その点では成功しています。問題は別のところにあります。ufw status が示すのは結果ではなく意図だということです。ルールは一覧にありながら何一つ閉じていないことがあり得ます——それも三つの異なる理由で、しかもその三つはどれも実際のサーバーで定期的に見つかります。
自分を締め出さない始め方
コマンドの順序が大事です。先に SSH を許可し、それから有効化します。
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable
SSH を許可する前の ufw enable は自分のセッションを切り、その後はプロバイダーのコンソールしか残りません。サーバーがすでに設定済みで自信がないなら、二つ目の接続を開けたままにしてください——それは失敗した編集を生き延びます。
詳細な状態を見てください。短いほうは既定ポリシーを隠します。
sudo ufw status verbose
一つ目の誤り:ルールはあるがポートは世界に開いている
他人の設定で最もよく見かける一行:
sudo ufw allow 3306
MySQL はこうやって「家から接続できるように」開けられ——そしてインターネット全体に開かれます。正しい書き方は二つあり、どちらもこれよりましです。
sudo ufw allow from 203.0.113.25 to any port 3306
あるいは、より確実には、そもそもサービスを外に出さないことです。MySQL の設定に bind-address = 127.0.0.1、外部からのアクセスは SSH トンネル経由。ファイアウォールは二線目であり、一線目はサービスが公開アドレスで待ち受けないことです。UFW のルールは誤って消され得ますが、bind-address はひとりでに変わりません。
二つ目の誤り:IPv6
ufw allow from 203.0.113.25 のようなルールは IPv4 にしか効きません。サーバーに IPv6 アドレスがあるなら——そして多くの VPS にはあり、有効になっています——サービスはそれ経由で届いたままです。プロバイダーがアドレスを配り、あなたはそれを覚えておらず、スキャナは覚えています。
v6 のフィルタリングがそもそも有効か(/etc/default/ufw の IPV6=yes)、そしてサービスが必要もなく :: で待ち受けていないかを確認してください。
ss -tulpn | grep ':::'
アドレスを明示するルールは、プロトコルのバージョンごとに別々に書く必要があります。
三つ目の誤り:Docker
最も腹立たしいものです。Docker はポートを公開する際、UFW が書くルールの前に自分のルールを iptables のチェーンへ加えます。その結果、-p 5432:5432 で起動したコンテナは、UFW が Status: active と deny incoming ポリシーを報告していてもインターネットから届きます。ファイアウォールが壊れているのではなく——単に順番が回ってこないのです。
治し方は UFW ではなく、ポートの公開のしかたにあります。
ports:
- "127.0.0.1:5432:5432"
ローカルアドレスへの束縛が最も単純で確実な解決です。外を向くべきなのは本当に訪問者に応対するものだけ——通常はリバースプロキシの 80 と 443 です。
ルールの順序
UFW は最初に一致したルールを適用してそこで止まります。ですから許可の後に足した拒否は効きません。順番が回ってこないのです。番号を見て、必要な位置に挿入してください。
sudo ufw status numbered
sudo ufw insert 1 deny from 198.51.100.0/24
sudo ufw delete 7
ルールは番号で削除しますが、削除のたびに番号はずれます——一つずつ消して、一覧を読み直してください。
外部からの確認
ローカルのコマンドが示すのは設定されたものです。実際どうなったかは別のマシンからしか見えません。
nmap -Pn -p- 203.0.113.25
nc -zv 203.0.113.25 3306
他のどのサーバーでも、自宅のパソコンでも構いません。これは嘘をつかない唯一の確認であり、目立った再設定のたびに走らせる価値があります——とくに「自分でネットワークを設定する」たぐいのものを入れた後は。Docker、コントロールパネル、VPN などです。
ログ
既定では UFW はほとんど何も書きません。これで有効にします。
sudo ufw logging low
記録は /var/log/ufw.log へ行きます——ただしシステムに rsyslog がある場合に限ります。Debian 12 と Ubuntu 24.04 では無いこともあり、そのときはすべて systemd のジャーナルへ入ります。
sudo journalctl -k | grep -i '\[UFW'
空の /var/log/ufw.log はそれ自体では何も意味しません——先にジャーナルを見てください。
ファイアウォールに何を期待すべきか
UFW は届くべきでないものを閉じます。開いているものへ来るリクエストの中身は見ません。443 は誰にでも開いており、サイトに来るものは何であれ妨げなく到達します。それは他のツールの仕事です——アプリケーション層の WAF、トラフィック層の IDS。ファイアウォールの務めはもっと地味で、もっと重要です。開いているポートの一覧が、あなたがそれについて信じている内容と一致していること。その一覧を有効なルールと並べて一つのページに置くとどう見えるかは、下のデモで。