公開VPSは,立ち上げた瞬間から世界中の自動攻撃に晒される.その最前線で「開いている穴の数」を制御するのがファイアウォールだ.攻撃面はそのまま,開いているポートの数に比例する.

ところが多くの個人開発者は,ファイアウォールを「なんとなく有効化しただけ」で済ませている.何が開いていて,何が閉じているのかを把握できていないサーバーは,自分でも気づかぬ穴を抱えていることが多い.

この記事は,公開VPSを運用する個人開発者,ファイアウォールを雰囲気で設定しているエンジニアに向けている.デフォルト拒否の原則から,ufwの実践,nftablesの理解,クラウド側との二層防御までを一気に解説する.

読み終えたとき,あなたは「自分のサーバーで何が開いているか」を即答でき,必要なポートだけを意図して開けるようになっている.これはセキュリティの最も基本的で,最も効果の大きい一手だ.

なぜファイアウォールが第一防衛線なのか

侵入の多くは,意図せず開いていたポートを突いて起きる.デバッグ用に開けたまま忘れたポート,デフォルトで外部公開されてしまったサービス── これらが攻撃者の入り口になる.

ファイアウォールの役割は,「許可したもの以外,すべて遮断する」ことだ.アプリ側でいくら認証を固めても,そもそも到達できなければ攻撃は成立しない.通信経路の段階で断つのが最も強い.

そして攻撃面の縮小は,費用ゼロで即効性がある.数コマンドで「必要な3〜4ポート以外すべて閉じる」状態を作れる.これだけで無差別攻撃の大半が無効化される.

重要なのは,「閉じる」だけでなく「今何が開いているかを常に把握する」姿勢だ.本記事ではその両方を身につける.

大原則 ― デフォルト拒否(ホワイトリスト方式)

ファイアウォール設計の鉄則はただ一つ,「デフォルトはすべて拒否し,必要なものだけ明示的に許可する」ことだ.これをホワイトリスト方式と呼ぶ.

逆の「基本許可で危険なものだけ塞ぐ」(ブラックリスト方式)は,「塞ぎ忘れ」が必ず穴になるため公開サーバーには向かない.許可リストを最小限に保つことが,攻撃面を最小化する唯一の確実な方法だ.

方針考え方公開サーバー向きか
デフォルト拒否全部閉じ,必要な分だけ開ける◎ 推奨
デフォルト許可全部開け,危険な分だけ塞ぐ× 塞ぎ忘れが穴になる

通信方向も意識する.外から入ってくる通信(incoming)は厳しく拒否ベース,サーバーから出る通信(outgoing)は基本許可,が一般的な出発点だ.まずincomingを最小化することに集中しよう.

ufw実践 ― 最短で安全な状態を作る

Ubuntu/Debian系で最も手軽なのがufw(Uncomplicated Firewall)だ.背後のnftables/iptablesを,分かりやすいコマンドで操作できる.まずはデフォルト拒否+必要ポートだけ許可の基本形を作る.

ufwの基本セットアップ

sudo ufw default deny incoming    # 受信は全部拒否
sudo ufw default allow outgoing   # 送信は許可
sudo ufw allow OpenSSH            # SSH(自分が締め出されないよう最初に)
sudo ufw allow 80,443/tcp         # Web
sudo ufw enable                   # 有効化
sudo ufw status verbose           # 現在のルールを確認

最重要の注意点は,enableの前に必ずSSHを許可することだ.これを忘れて有効化すると,自分がSSHで締め出される(コンソールから復旧は可能だが避けたい).ufw status verboseで「今何が開いているか」を常に確認する習慣をつけよう.

ルールの削除と番号指定

不要になったルールはufw status numberedで番号を確認し,番号で削除する.「昔開けたが今は使っていない」ポートを定期的に棚卸しすることが,穴を残さないコツだ.

ルールの確認と削除

sudo ufw status numbered
sudo ufw delete 3        # 番号3のルールを削除
sudo ufw delete allow 8080/tcp  # 内容指定でも削除可

ポート設計 ― 開けてよいもの・絶対に閉じるもの

「何を開けるか」は用途で決まる.基本はSSH・HTTP・HTTPSの3〜4個だけで多くのケースは足りる.データベースや管理用ポートは外部に開けないのが原則だ.

ポート用途外部公開
22 (SSH)リモート操作許可(できれば鍵認証+IP制限)
80/443Web(HTTP/HTTPS)公開サイトなら許可
5432/3306PostgreSQL/MySQL× 原則閉じる(localhost接続)
6379 (Redis)Redis× 絶対に外部公開しない
各種admin管理画面・監視× IP制限 or トンネル経由

とくにDBやRedisの外部公開は重大事故に直結する.これらはlocalhostにバインドし,外部から触りたいときはSSHポートフォワード経由にする(SSH記事参照).「開けない」ことが最大の防御だ.

特定IPのみ許可とレート制限 ― 開けつつ絞る

SSHや管理画面は,「開けるが,特定IPからのみ」に絞ると安全性が大きく上がる.固定IPの環境(自宅・オフィス・踏み台)からのみ許可する設計だ.

IP限定とレート制限

# SSHを特定IPからのみ許可
sudo ufw allow from 203.0.113.10 to any port 22
# ufwの簡易レート制限(短時間の多数接続をブロック)
sudo ufw limit OpenSSH
# 特定IPを全面拒否
sudo ufw deny from 198.51.100.0/24

ufw limitは,短時間に多数の接続を試みるIPを自動でブロックする簡易的な総当たり対策だ.より高度な検知・ban は次回のfail2ban記事で扱う.固定IPが使えるならallow fromでのIP限定が最も強力だ.

nftables ― ufwの「下」で動く本体を理解する

ufwは便利なラッパーだが,その下ではnftables(かつてのiptablesの後継)が実際の制御を担っている.普段はufwで足りるが,本体を理解しておくとトラブル時に強い.

nftablesはテーブル→チェーン→ルールという階層で動く.ufwで表現しきれない細かい制御や,ufwを使わずnftables直書きで管理したい場合に必要になる.

nftablesの状態確認

# 現在のルールセットを表示
sudo nft list ruleset
# ufw使用時も,実体はnftablesで確認できる
sudo nft list tables

個人開発では基本ufwで十分だ.ただし「ufwで許可したのに通らない」といった謎が起きたとき,nft list rulesetで実際のルールを見ると原因が分かることがある.Dockerがiptables/nftablesを操作してufwと競合する,という事故もあるため,両者の関係は頭に入れておきたい.

Dockerとファイアウォールの競合に注意

Dockerはポート公開時に自前でnftables/iptablesルールを挿入し,ufwのルールを迂回することがある.「ufwで閉じたはずのポートが,Dockerコンテナでは外部公開されていた」という事故は定番だ.コンテナのポート公開は127.0.0.1:3000:3000のようにlocalhostバインドで行い,外部公開はリバースプロキシ経由にするのが安全だ.

二層防御 ― クラウド側ファイアウォールとの併用

多くのVPSは,OS内のufwとは別にクラウド/管理画面側のファイアウォール(セキュリティグループ)を提供している.この二層で守るのが理想だ.

OS側の設定ミスやマルウェアによる改変があっても,ネットワーク側でブロックされていれば被害を防げる.逆も然りで,多層防御は片方の穴をもう片方が塞ぐ.

場所役割
ネットワーク側VPS管理画面のFW/SGVPSに到達する前に遮断
OS側ufw/nftablesOS内で受信を制御

両方で同じ最小ポリシー(必要ポートのみ許可)を組むのが基本だ.管理画面側で大枠を絞り,OS側で細かく制御する.二重管理の手間はあるが,どちらか一方が破られても守りが残る安心感は大きい.

よくある事故と確認の習慣

ファイアウォール関連の事故は,たいてい「把握していなかった」ことから起きる.確認の習慣で防げる.

「開けたはずなのに繋がらない/閉じたはずが開いている」

sudo ss -tlnp実際に待ち受けているポートとプロセスを確認し,ufw status verboseと突き合わせる.「サービスがlocalhostのみ待ち受けているか,0.0.0.0(全公開)か」もここで分かる.Docker絡みならnft list rulesetも確認する.

開いているポートの実態確認

sudo ss -tlnp        # 待ち受け中のポートとプロセス
sudo ufw status verbose
# 外部から見たポート状態(別ホストから)
# nmap -Pn <VPSのIP>

自分を締め出してしまった

SSHを閉じてしまった場合は,VPSのコンソール(VNC)からログインしてufwルールを修正する.スナップショットがあれば設定前へ巻き戻すのが最速だ.設定変更時は別セッションを開いたままにする習慣で,この事故は防げる.

補論:ファイアウォールの実験は「コンソール復旧できるVPS」で安全に

ファイアウォールの設定は,一手間違えると自分が締め出される作業だ.だからこそ「SSHが切れてもコンソールから入れる」「失敗したらスナップショットで戻せる」環境が,安心して設計を攻めるための前提になる.

高速NVMe・50種類以上のOSテンプレートに対応した国内VPS─シン・VPS─ はブラウザコンソール(VNC)とスナップショットを備え,さらに管理画面側のファイアウォールも提供する.つまりOS側ufw+ネットワーク側の二層防御を1つのサービスで組め,万一締め出してもコンソールから復旧できる.ファイアウォールを学び・運用する基盤として理想的だ.

公開するWebサービスにはHTTPSと独自ドメインが要る.取り扱い400種類以上のドメイン取得サービス─ムームードメイン─ で取得したドメインをVPSに向け,80/443だけを開けた最小構成で公開すれば,攻撃面を絞った安全なサイトが月数百円〜で運用できる.

よくある質問(FAQ)

Q1.ufwとnftables/iptables、どれを使えばいい?

個人開発はufwで十分だ.背後のnftablesを分かりやすく操作できる.細かい制御が必要になったときにnftablesを直接学べばよい.まずはufwでデフォルト拒否+必要ポート許可を確実に組む.

Q2.最低限どのポートを開ければいい?

SSH(22)・HTTP(80)・HTTPS(443)の3つで多くのWebサービスは足りる.DBやRedis,管理用ポートは外部に開けず,localhost接続やSSHトンネル経由にする.

Q3.Dockerを使うとufwが効かないと聞いた

Dockerはポート公開時に独自のルールを挿入し,ufwを迂回することがある.対策はコンテナのポートをlocalhostにバインド(127.0.0.1:3000:3000)し,外部公開はリバースプロキシ経由にすること.これで意図しない公開を防げる.

Q4.ufw enableで締め出されないか不安

enableの前に必ずSSHを許可(ufw allow OpenSSH)する.加えて別セッションを開いたまま有効化し,接続を確認する.万一締め出してもコンソールやスナップショットで復旧できる.

Q5.クラウド側FWとufwは両方要る?

両方が理想だ.片方の設定ミスやマルウェアによる改変を,もう一方が防ぐ多層防御になる.両方で同じ最小ポリシーを組むのがおすすめ.

Q6.今何が開いているか確認するには?

sudo ufw status verbose(ルール)とsudo ss -tlnp(実際の待ち受け)を突き合わせる.外部視点では別ホストからのnmapも有効だ.定期的な棚卸しが穴を残さない秘訣だ.

まとめ ― 攻撃面は「開いている穴の数」で決まる

ファイアウォールの要諦は,デフォルト拒否で必要なポートだけ開け,今何が開いているかを常に把握することだ.DBやRedisを外部に晒さず,可能ならIP限定し,クラウド側と二層で守る.

今日やるべきことは,ufw status verbosess -tlnpで「自分のサーバーで何が開いているか」を確認すること.不要な穴があれば閉じる.それだけで攻撃面は劇的に縮む.

費用ゼロ・数コマンドで効く,最もコスパの高いセキュリティだ.コンソールから復旧できるVPSがあれば,今夜から恐れずに設計できる.