セキュリティ

VPS を公開する前にやる最低限のハードニング — SSH・ufw・fail2ban・Cloudflare

VPS を立てて IP が割り当てられた瞬間から、SSH への総当たりは始まります。
「まだ誰にも教えていないから大丈夫」は通用しません。
公開前に必ずやっている最低限の手順です。

1. SSH をパスワード認証から外す

これが最も効きます。鍵認証だけにして、root ログインも止めます。

# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

設定を反映する前に、別のターミナルで鍵ログインできることを必ず確認してください。
確認せず systemctl restart sshd して締め出される事故が定番です。

ポート変更は攻撃を防ぐ効果はほぼありませんが、
ログのノイズが激減するので運用上の意味はあります。

2. ufw で必要なポートだけ開ける

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80,443/tcp
ufw enable

default deny incoming が本体です。
DB のポート(5432 や 3306)が外に開いていないか、必ず確認します。

ss -tlnp    # 0.0.0.0 で LISTEN しているものを確認

PostgreSQL や Redis が全インターフェースで待ち受けていたら、
localhost のみに絞ります。

3. fail2ban で総当たりを遮断する

# /etc/fail2ban/jail.local
[sshd]
enabled = true
maxretry = 3
bantime = 3600
findtime = 600

10分間に3回失敗したら1時間 BAN、という設定です。
Nginx の認証エラーやボット的なアクセスにも同じ考え方で適用できます。

fail2ban-client status sshd   # 実際に BAN されているか確認

4. Cloudflare を前段に置く

DNS を Cloudflare 経由(プロキシ ON)にすると、
オリジンサーバーの実IPが隠れます。これが一番大きい効果です。

同時に、オリジン側で Cloudflare の IP レンジ以外を弾いておきます。
そうしないと、実IPが知られた時点で Cloudflare を迂回されます。

# Cloudflare の公開レンジのみ 443 を許可する例
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
    ufw allow from $ip to any port 443 proto tcp
done

忘れがちな2つ

自動セキュリティ更新を入れておきます。

apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

そして .env.git が Web から見えていないか
これは公開直後から必ず狙われます。

location ~ /\. { deny all; }

実際、サイトを公開した直後のログには
/.env /.env.local /config/.env といったリクエストがすぐに並びます。

まとめ

対策 効果
SSH 鍵認証のみ 総当たりが原理的に通らなくなる
ufw で最小開放 意図しない待ち受けを塞ぐ
fail2ban 繰り返し攻撃を自動遮断
Cloudflare プロキシ 実IP秘匿 + WAF

どれも1時間もかからない作業ですが、やる・やらないの差は非常に大きいです。