新しく入れた Linux VPS は、OS を入れた瞬間から公網 IP がスキャナの射程に入ります。私たちが監視した Ubuntu 22.04 の一台では、起動から 4 時間も経たないうちに /var/log/auth.log に世界中からの SSH ブルートフォースが千件以上記録されていました。クラウドのセキュリティグループで一部は防げますが、OS 内のファイアウォールこそ、自分でコントロールできる第二の防壁です。
Ubuntu / Debian 系サーバーなら、UFW(Uncomplicated Firewall) がほぼ定番の答えです。構文がシンプルで iptables とシームレスに連携し、ドキュメントも充実しています。本記事では iptables の数十本のチェインを並べるのではなく、本番で何度も検証してきた UFW 設定フローをチェックリストにまとめます——インストールと SSH 開放から、Web ポート、Docker との共存、クラウドセキュリティグループとの連携、そして最重要の「自分を外に閉め出さずにファイアウォールを設定する方法」まで。
前提として、SSH またはクラウドコンソールの VNC でサーバーにログイン済みで、sudo 権限があること。すでに SSH が繋がらない場合は、先に Linux サーバー SSH 接続拒否のトラブルシューティング でネットワーク問題かファイアウォール問題かを切り分けてから、本記事に戻ってください。
なぜクラウドサーバーにファイアウォールが必要か
「クラウドを買えばセキュリティグループがあるから、OS 側は不要」と考える人は少なくありません。実際には二層の役割が異なります。クラウドセキュリティグループは仮想 NIC の外側でトラフィックをフィルタし、コンソールから管理します。UFWは OS カーネルの netfilter 層でフィルタし、コマンドラインから管理します。片方だけだと、玄関の鍵だけかけて寝室のドアは開けっぱなし——内網横移動、誤って露出したサービス、侵入後のリバースシェルなど、システムレベルのルールでカバーする場面が残ります。
UFW の下層は Ubuntu 公式 UFW ドキュメント が説明する iptables フロントエンドです。ufw allow 22 と書けば対応する ACCEPT ルールに変換されます。自然言語に近い構文で、ufw status numbered ですべてのポリシーが一覧でき、ルール変更でも迷いにくいのが利点です。
| レイヤー | ツール | 管理入口 | 典型的な用途 |
|---|---|---|---|
| クラウド(外側) | セキュリティグループ / Network ACL | Web コンソール | 粗い粒度のインバウンド:22/80/443 のみ |
| OS(内側) | UFW / firewalld | SSH コマンドライン | 細かい粒度:IP・ポート・レート制限 |
| アプリケーション層 | fail2ban / CrowdSec | 設定ファイル | ブルートフォース元 IP の動的ブロック |
ステップ 1:UFW のインストールと確認
Ubuntu デスクトップ版や多くの Server イメージには UFW がプリインストールされていますが、最小構成イメージには入っていないこともあります。まず確認しましょう。
sudo apt update
sudo apt install ufw -y
# 現在の状態を確認(inactive はまだ未有効)
sudo ufw status verbose
# 起動時自動起動(enable の前にルールを整えるのが推奨)
sudo systemctl enable ufw
Status: inactive と出れば、ルールを一つずつ追加してもまだ反映されません——これがいちばん安全な設定ウィンドウです。SSH を開放する前に ufw enable してはいけません。即座にリモート接続を失います。
ステップ 2:SSH を開放(最重要の 1 ルール)
SSH は管理経路なので、最初に開放します。sshd を非標準ポート(例:2222)に変更している場合、ルールのポートはsshd_config と一致させ、セキュリティグループも同じにしてください。
# デフォルト 22 番ポート sudo ufw allow 22/tcp comment 'SSH' # カスタムポート sudo ufw allow 2222/tcp comment 'SSH custom' # オフィス出口 IP のみ許可(本番環境で推奨) sudo ufw allow from 203.0.113.50 to any port 22 proto tcp # サービス名で指定(/etc/services に定義がある場合) sudo ufw allow OpenSSH
sshd が実際にリッスンしているか確認:sudo ss -tlnp | grep ssh。0.0.0.0:22 または [::]:22 が見えれば正常です。ListenAddress が 127.0.0.1 になっている場合、UFW で開放しても意味がありません——sshd の設定問題であり、ファイアウォールの問題ではありません。
SSH ポートとセキュリティグループの組み合わせについては、Linux クラウドホスト最小露出面ファイアウォール決定 FAQ の SSH/HTTPS トレードオフマトリクスが、長期ポリシーの設計に役立ちます。
ステップ 3:デフォルトポリシーの設定
UFW の推奨ベースラインは、インバウンドはすべて拒否、アウトバウンドはすべて許可です。アウトバウンドを開けておけば apt パッケージの取得、API アクセス、DNS クエリが可能になります。インバウンドを絞り、必要なサービスポートだけ開きます。
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 現在のルールを確認(番号付き、削除に便利)
sudo ufw status numbered
コンプライアンス要件でアウトバウンドも絞りたい場合は、ufw default deny outgoing のあと DNS(53)、HTTPS(443)などを allow out で個別に追加できます。ただし多くの Web / API サーバーでは、インバウンドだけ絞りアウトバウンドは全開放がコストパフォーマンス最高です。
ステップ 4:業務ポートの開放
実際に動かしているサービスに合わせてルールを追加します。よくある組み合わせは次のとおりです。
# HTTP / HTTPS(Nginx、Caddy、Apache) sudo ufw allow 80/tcp sudo ufw allow 443/tcp # サービス名のショートカット sudo ufw allow 'Nginx Full' # 開発環境で一時的に Node などを開放 sudo ufw allow 3000/tcp comment 'dev API' # 特定ソース IP から管理パネルへ sudo ufw allow from 198.51.100.0/24 to any port 8080 proto tcp
本番環境では、443 のリバースプロキシで済むなら 3000/8080 を直接露出しないのが鉄則です。UFW では 22 + 80 + 443 の 3 ポートだけ開き、アプリは 127.0.0.1 でリッスンし、Nginx や Caddy で TLS 終端——攻撃面が一気に小さくなります。
ステップ 5:有効化と検証
ルールを追加し終えたら、正式に有効化します。
sudo ufw enable
# 既存 SSH が中断される可能性がある旨の確認で y を入力
sudo ufw status verbose
sudo ufw status numbered
別のマシンからテストします:nc -zv your.server.ip 22 は open を返すべきです。未開放のポート(例:3306)はタイムアウトまたは拒否されます。SSH が切れたら、すぐにクラウドコンソール VNC から sudo ufw disable でロールバックし、不足ルールを特定してからやり直してください。
応用:レート制限、削除、ルール順序
UFW は allow より細かい操作にも対応しています。よく使うシーンをいくつか。
# レート制限:SSH ブルートフォース対策(30 秒あたり 6 回) sudo ufw limit 22/tcp # 番号でルールを削除(先に status numbered で番号確認) sudo ufw delete 3 # 特定 IP を拒否 sudo ufw deny from 192.0.2.100 # 全ルールをリセット(注意して使用) sudo ufw reset
ufw limit は下層で iptables の recent モジュールを使った接続頻度制限で、SSH に効果的です。ただし鍵認証の導入やパスワード認証の無効化の代替にはなりません。ルールは追加順にマッチするため、より具体的なルールは前に置くべきです——allow が効かないときは、後ろの deny に上書きされていないか確認してください。
Docker / Kubernetes との共存で注意すること
UFW が「設定したのに効いていない」ように見える典型シーンです。Docker はデフォルトで iptables に独自のチェインを挿入し、UFW のルールをバイパスすることがあります。3306 を開いていないつもりでも、コンテナポートが公網に見えている——そういう状態になります。
対処法(推奨度順):
- コンテナは 127.0.0.1 にバインド——
-p 127.0.0.1:3000:3000、ホストのリバースプロキシで外部公開 - docker-compose で ports を書かない、内部ネットワーク + リバースプロキシで接続
- Docker 設定で
"iptables": false(転送ルールは自分で管理、上級者向け) - クラウドセキュリティグループで最終防衛——Docker が UFW をバイパスしても外側でフィルタ
K8s ノードはさらに複雑で、通常は Calico/Cilium の NetworkPolicy を使い、UFW はノードレベルの補助にとどめます。単一 VPS で Docker Compose を動かすなら、最初の方法(loopback バインド)で十分なことが多いです。
クラウドセキュリティグループと UFW の連携
二層とも設定し、ポリシーは一致させる必要があります。セキュリティグループで 22 を開けたら UFW でも allow 22。セキュリティグループで 3306 を開いていなければ、UFW で allow しても外網からは入れません——ただし内網の侵害済みマシンからはスキャンされる可能性があるため、UFW 側でも deny しておくべきです。
推奨する役割分担:
- セキュリティグループ:粗い粒度、22/80/443 のみ、ソース IP はオフィスや CDN に絞れる
- UFW:細かい粒度、サービスコメント、SSH limit、悪意ある IP のブロック
- fail2ban:動的層、ログを読んで自動ブロック
どちらかを変更したら、外部からのプローブで検証します:nmap -p 22,80,443,3306 your.server.ip(自分のサーバーだけをスキャンしてください)。3306 が open なのに DB を意図的に露出していないなら、Docker のバインドやアプリのリッスンアドレスをすぐ調査してください。
トラブルシュート:UFW 有効化後にサービスにアクセスできない
次の順で確認すれば、10 分以内に大半の問題を特定できます。
sudo ufw status verbose——ルールは本当に有効か?ポートとプロトコル(tcp/udp)は正しいか?sudo ss -tlnp——アプリは0.0.0.0でリッスンしているか、127.0.0.1だけではないか?- クラウドセキュリティグループのインバウンドルールは同期しているか?
- Docker が UFW をバイパスしていないか?
- 一時的に
sudo ufw disableで比較テスト(終わったら enable に戻す)
特定の送信元 IP だけ繋がらない場合は、deny from や fail2ban のブロックを確認してください。UFW のログはデフォルトでは詳細ではありません。必要なら /etc/ufw/ufw.conf で LOGLEVEL=medium に設定し sudo ufw reload のあと /var/log/ufw.log で拒否パケットを確認できます。
本番投入チェックリスト(そのまま実行可)
新規サーバーや OS 再インストール後は、次の順で一通り実行してください。
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH' # またはカスタムポート
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw limit 22/tcp # 任意:SSH レート制限
sudo ufw enable
sudo ufw status verbose
最後に OS 側のハードニングも忘れずに:SSH 鍵認証、root のパスワードログイン無効化、unattended-upgrades の定期更新。ファイアウォールは境界防御であり万能薬ではありません——それでも自動スキャンの 90% は門前で止められ、より深いセキュリティ設定に時間を確保できます。
安定運用ノード:ファイアウォール設定の不安を減らす
複数の Linux VPS を管理するとき、固定出口 IP の踏み台を SSH 中継に使う人は多いです。セキュリティグループと UFW は踏み台 IP だけ許可し、手元では鍵でチェーン接続。Mac mini はこの用途に向いています:macOS はネイティブ Unix 環境で、Terminal と OpenSSH がそのまま使えます。M4 チップの待機時消費電力は約 4W で、7×24 デスク上の中継ノードに適し、x86 小型ホストより省電力で静かです。
同価格帯の Windows マシンを常時稼働の踏み台にすると、消費電力とファンノイズが目立ちます。macOS はクラッシュ率が低く、FileVault と Gatekeeper と組み合わせれば秘密鍵の保管も安心です。Mac 上で Xcode や Docker でリリースビルドも回すなら、クラウド Mac mini で「踏み台 + ビルド」を 1 ノードにまとめ、切り替えを減らせます。
安定したリモート運用環境を組み立てるなら、 VPSSPark クラウド Mac mini M4 は低消費電力の踏み台兼開発ノードとして現実的な選択です—— プランを今すぐ確認 、サーバーセキュリティ強化を深夜の一人作業にしないために。