公開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/443 | Web(HTTP/HTTPS) | 公開サイトなら許可 |
| 5432/3306 | PostgreSQL/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/24ufw 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/SG | VPSに到達する前に遮断 |
| OS側 | ufw/nftables | OS内で受信を制御 |
両方で同じ最小ポリシー(必要ポートのみ許可)を組むのが基本だ.管理画面側で大枠を絞り,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 verboseとss -tlnpで「自分のサーバーで何が開いているか」を確認すること.不要な穴があれば閉じる.それだけで攻撃面は劇的に縮む.
費用ゼロ・数コマンドで効く,最もコスパの高いセキュリティだ.コンソールから復旧できるVPSがあれば,今夜から恐れずに設計できる.