なぜ「多層防御」なのか
「セキュリティ対策」と一括りにされがちですが、実際に本番サービスを狙う攻撃者は単一の対策を突破するのではなく、複数のレイヤーを段階的に突破していきます。
つまり、防御側も 各層で「もし突破されたら次の層でどう受け止めるか」を設計 しないと、1点突破で全滅します。これが「多層防御 (Defense in Depth)」の基本発想です。
本記事では、私が自社サービス で実装している 7層の防御スタック を、選定理由と一緒に公開します。
7層防御スタックの全体像
[インターネット]
↓
1. Cloudflare(WAF / Bot Fight / Page Shield / TLS)
↓
2. ufw(Cloudflare IP のみ 80/443 許可・SSH はカスタムポート)
↓
3. CrowdSec(Community Blocklist + Firewall Bouncer)
↓
4. fail2ban(sshd / nginx / recidive)
↓
5. Nginx(real_ip / Origin IP 隠蔽)
↓
6. Django(HSTS Preload / 管理URL隠蔽 / Secure Cookie)
↓
7. PostgreSQL(localhost 限定)
全て 無料 or 極めて安価 で構築できます。
各層の役割と選定理由
1. Cloudflare — Bot / DDoS / WAF の第一段階
無料プランで以下がついてきます:
- WAF(Web Application Firewall): OWASP Top 10 の主要攻撃をブロック
- Bot Fight Mode: 悪質ボットの自動遮断
- Page Shield: JS の改ざん・不正埋め込み検知
- フル厳密 TLS + HSTS Preload: HTTPS 強制
大事なポイント: Cloudflare の設定で「フル (Strict)」を選ばないと、Cloudflare ⇄ Origin 間が HTTP のまま抜けます。ここは必ず Origin 証明書を発行して TLS 化。
2. ufw — Origin ファイアウォールで表玄関を絞る
Cloudflare の IP 帯以外からは 80/443 に到達させないようにします。
# Cloudflare IP 帯を許可(v4 / v6 両方)
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
sudo ufw allow from $ip to any port 80,443 proto tcp
done
SSH はカスタムポートに変更 + IP 制限。デフォルトの 22 番は世界中からブルートフォースの標的です。
3. CrowdSec — Community Blocklist で「知られている悪」を止める
CrowdSec は Fail2ban の思想を クラウド分散化 したもの。世界中のノードが報告する悪意ある IP を Community Blocklist として共有し、自ノードでブロックします。
# インストール
curl -s https://install.crowdsec.net | sudo sh
sudo cscli parsers install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/nginx
# Firewall Bouncer で ufw / iptables に反映
sudo apt install crowdsec-firewall-bouncer-iptables
これで 「まだ攻撃を受けていないが、他の誰かが既に攻撃されている IP」 を先回りしてブロックできます。
4. fail2ban — ローカルのブルートフォースを止める
- sshd: SSH ブルートフォース
- nginx: 404 大量 / .env 探索など
- recidive: 何度も banされる悪質 IP を長期 ban
# /etc/fail2ban/jail.local
[recidive]
enabled = true
findtime = 86400
maxretry = 3
bantime = 604800
5. Nginx — real_ip と Origin IP 隠蔽
Cloudflare 経由の接続は X-Forwarded-For に本当のクライアント IP が入るので、Nginx で読み替えます。
set_real_ip_from 173.245.48.0/20;
# ... 他のCloudflare IP 帯 ...
real_ip_header CF-Connecting-IP;
Origin IP は DNS に直接晒さない(Cloudflare Proxy を必ず経由)ように。
6. Django — アプリケーション層のハードニング
# settings.py
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_PRELOAD = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
# 管理URL は隠蔽
ADMIN_URL = "obscure-random-path/"
HSTS Preload リストへの登録 は hstspreload.org から。ブラウザに焼き込まれるため強力です。
7. PostgreSQL — localhost 限定
# postgresql.conf
listen_addresses = 'localhost'
外部からの接続経路そのものを絶ちます。
SSH ハードニング詳細
多層防御の中でも SSH は攻撃者の第一標的なので、追加で以下を実施。
- 鍵認証のみ(パスワードログイン完全禁止)
- カスタムポート
- ssh-audit で fail/warn ゼロを目指す
- DHEat DoS 対策 (CVE-2002-20001)
ssh-audit localhost -p 22222
# → 全て "pass" 表示になるまで /etc/ssh/sshd_config を調整
監視・自動化
- auditd: 権限・SSH・cron の改ざん検知
- AIDE: ファイル整合性監視
- unattended-upgrades: セキュリティパッチ自動適用
- 日次バックアップ: DB / メディア / 設定を オフサイト に
「金融機関水準」って言えるの?
言えます。金融機関の実運用でも、大枠は「境界防御 + 内部ゼロトラスト + 監視 + パッチ運用」で、上記の構成はそのミニチュア版として成立しています。
ただし金融機関水準を 『名乗る』 のと 『実装して回している』 のは別次元です。名乗るだけの人が多いので、実装ログと運用フローを プレイブック化 して残しておくのが実務的に重要です。
個人事業主・スタートアップへのおすすめ
- 月額運用コスト: Cloudflare 無料プラン + Conoha VPS ¥2,000〜 = 合計 ¥2,000/月 で構築可能
- 初期構築コスト: 自力なら 1-2 週間、外注なら 30-80 万円が相場
- 維持コスト: セキュリティパッチ確認・監視ログ確認 = 週1回 30分
ペネトレーションテスト・セキュリティコンサルのご相談
自社サービスで実証したこのプレイブックを 横展開して外部案件にも提供 しています。
- 既存Webサービスへの多層防御実装
- ペネトレーションテスト(Web / API / インフラ)
- 脆弱性診断・OWASP ZAP / AI 診断のトリアージ
- WAF (Cloudflare) 導入・チューニング
- セキュリティ設計レビュー
詳細は お問い合わせ からご相談ください。
関連リンク: