はじめに:なぜホームサーバーのセキュリティが重要なのか

ホームサーバーをインターネットに公開した瞬間、世界中のボットやハッカーがあなたのサーバーをスキャンし始めます。大げさではありません。実際に新しいサーバーをオンラインに上げると、数分以内にSSHブルートフォース攻撃が始まるのをログで確認できます。前編でネットワークとDDNS設定を完了したなら、今度はサーバーを安全に守る方法を学ぶ時です。

セキュリティは難しく複雑に見えますが、基本的な原則をしっかり守るだけでも、ほとんどの攻撃を防ぐことができます。この編では、ホームサーバー運営者なら必ず知っておくべきセキュリティ設定を一つずつ見ていきます。

1. UFWファイアウォール設定

1.1 ファイアウォールとは?

ファイアウォールは、サーバーに出入りするネットワークトラフィックを制御するセキュリティシステムです。簡単に言えば「誰がどの扉から入れるか」を決めることです。UbuntuではUFW(Uncomplicated Firewall)というツールを使えば、iptablesよりはるかに簡単にファイアウォールを管理できます。

1.2 UFWのインストールと基本設定

ほとんどのUbuntuバージョンにはUFWがデフォルトでインストールされています。インストール状況を確認し、なければインストールします。

# UFWインストール確認とインストール
sudo apt update
sudo apt install ufw

# UFW状態確認
sudo ufw status

最初は非アクティブ状態のはずです。有効化する前に必ずSSH接続を許可してください。そうしないと、ファイアウォールが有効化された瞬間、サーバーから締め出されることになります。

# デフォルトポリシー設定:すべての受信接続を拒否、送信接続を許可
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH許可(重要!)
sudo ufw allow ssh
# またはポート番号で指定
sudo ufw allow 22/tcp

# Webサーバーポート許可
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# UFW有効化
sudo ufw enable

1.3 サービス別ポート許可

運営するサービスに応じて必要なポートを開ける必要があります。

# 特定ポートの許可
sudo ufw allow 8080/tcp    # 代替Webポート
sudo ufw allow 32400/tcp   # Plexメディアサーバー

# ポート範囲の許可
sudo ufw allow 6000:6010/tcp

# 特定IPからのみアクセス許可
sudo ufw allow from 192.168.1.0/24 to any port 22

# 特定IPのブロック
sudo ufw deny from 123.45.67.89

# ルール確認
sudo ufw status numbered

# 特定ルールの削除(番号で)
sudo ufw delete 3
注意:リモートでサーバーを管理している場合、SSHポートをブロックしないよう特に注意してください。誤ってブロックすると、サーバーに物理的にアクセスする必要があります。

2. fail2banでブルートフォース攻撃を防御

2.1 fail2banとは?

fail2banはログファイルを監視し、異常なアクセス試行(例:繰り返しのログイン失敗)を検知すると、そのIPを自動的にブロックするツールです。SSHブルートフォース攻撃を防ぐのに非常に効果的です。

2.2 fail2banのインストールと設定

# fail2banインストール
sudo apt install fail2ban

# サービス開始と自動起動設定
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

fail2banの設定は/etc/fail2ban/ディレクトリにあります。デフォルトの設定ファイルを直接修正せず、localファイルを作成して使用することが推奨されます。

# ローカル設定ファイル作成
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

2.3 jail.local詳細設定

主要な設定オプションを見てみましょう。

[DEFAULT]
# ブロック時間(秒単位、-1は永久ブロック)
bantime = 3600

# ログイン試行監視時間範囲
findtime = 600

# 許容される失敗回数
maxretry = 5

# ブロックから除外するIP(自分のIPを追加)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24

# ブロック時のメール通知(オプション)
# action = %(action_mwl)s
# destemail = your@email.com
# sender = fail2ban@yourdomain.com

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400

# Nginx関連jail
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5

[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2

設定を変更した後はfail2banを再起動する必要があります。

# 設定適用
sudo systemctl restart fail2ban

# 現在のブロック状態確認
sudo fail2ban-client status
sudo fail2ban-client status sshd

# 特定IPの手動ブロック解除
sudo fail2ban-client set sshd unbanip 123.45.67.89

3. SSHセキュリティ強化

3.1 SSHポートの変更

デフォルトのSSHポート(22)を変更すると、自動化されたボット攻撃のかなりの部分を避けることができます。完璧なセキュリティ対策ではありませんが、攻撃ログが明らかに減るのを実感できます。

# SSH設定ファイル編集
sudo nano /etc/ssh/sshd_config

# 以下の行を見つけて修正(コメント解除とポート番号変更)
Port 2222

ポートを変更する前に、必ずUFWで新しいポートを許可してください。

# 新しいSSHポートを許可
sudo ufw allow 2222/tcp

# SSHサービス再起動
sudo systemctl restart sshd

# 新しいポートで接続
ssh -p 2222 username@server_ip

3.2 SSH鍵認証のみ許可

パスワード認証よりSSH鍵認証の方がはるかに安全です。鍵認証を設定し、パスワードログインを無効化することを強くお勧めします。

# クライアント(自分のPC)でSSH鍵生成
ssh-keygen -t ed25519 -C "your_email@example.com"

# 生成された公開鍵をサーバーにコピー
ssh-copy-id -p 2222 username@server_ip

# または手動でコピー
cat ~/.ssh/id_ed25519.pub | ssh -p 2222 username@server_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

鍵認証が正常に動作することを確認した後、パスワード認証を無効化します。

# SSH設定ファイル編集
sudo nano /etc/ssh/sshd_config

# 以下の設定を見つけて修正
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
PermitEmptyPasswords no
ChallengeResponseAuthentication no

# SSH再起動
sudo systemctl restart sshd
重要:パスワード認証を無効化する前に、必ずSSH鍵で接続できることを確認してください。そうしないとサーバーから完全に締め出される可能性があります。

3.3 追加SSH セキュリティ設定

# /etc/ssh/sshd_configに追加設定
# 特定ユーザーのみSSH接続許可
AllowUsers username1 username2

# 接続待機時間制限
LoginGraceTime 30

# 最大認証試行回数
MaxAuthTries 3

# 同時未認証接続数制限
MaxStartups 10:30:60

# X11フォワーディング無効化(必要ない場合)
X11Forwarding no

4. SSL/TLS証明書(Let's Encrypt)

4.1 HTTPSが必要な理由

HTTP通信は暗号化されていないため、途中でデータを盗み見ることができます。HTTPSはSSL/TLS証明書を使用して通信を暗号化し、サーバーの身元を保証します。Let's Encryptを使用すると、無料で信頼性のある証明書を発行できます。

4.2 Certbotインストールと証明書発行

# Certbotインストール
sudo apt install certbot python3-certbot-nginx

# Nginxを使用する場合(自動設定)
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# 証明書のみ発行(手動設定)
sudo certbot certonly --standalone -d yourdomain.com

# 証明書発行確認
sudo certbot certificates

4.3 証明書自動更新

Let's Encrypt証明書は90日ごとに更新が必要です。Certbotは自動更新のためのタイマーを設定します。

# 自動更新タイマー確認
sudo systemctl status certbot.timer

# 手動更新テスト
sudo certbot renew --dry-run

# cronで直接自動更新設定(オプション)
sudo crontab -e
# 以下の行を追加(毎日深夜3時に更新試行)
0 3 * * * /usr/bin/certbot renew --quiet

5. リバースプロキシとHTTPS

5.1 Nginxリバースプロキシ設定

リバースプロキシを使用すると、一つのサーバーで複数のサービスをドメインやパスで分岐できます。また、SSL証明書を一か所で管理できるので便利です。

# /etc/nginx/sites-available/reverse-proxy
server {
    listen 80;
    server_name yourdomain.com;

    # HTTPをHTTPSにリダイレクト
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    # SSL証明書設定
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # SSLセキュリティ設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # HSTSヘッダー
    add_header Strict-Transport-Security "max-age=63072000" always;

    # メインアプリケーションへプロキシ
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    # APIサーバーへプロキシ
    location /api/ {
        proxy_pass http://localhost:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
# 設定有効化
sudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/

# 設定テストと適用
sudo nginx -t
sudo systemctl reload nginx

6. セキュリティアップデート自動化

6.1 unattended-upgrades設定

セキュリティアップデートを見逃すと、既知の脆弱性にさらされる可能性があります。Ubuntuのunattended-upgradesを使用すると、セキュリティアップデートを自動的に適用できます。

# パッケージインストール
sudo apt install unattended-upgrades apt-listchanges

# 自動アップデート設定
sudo dpkg-reconfigure -plow unattended-upgrades

6.2 詳細設定

# 設定ファイル編集
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

主要な設定オプション:

// 自動アップデートするパッケージソース
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}";
    "${distro_id}:${distro_codename}-security";
    "${distro_id}ESMApps:${distro_codename}-apps-security";
    "${distro_id}ESM:${distro_codename}-infra-security";
};

// 自動削除する未使用カーネルパッケージ
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

// 自動再起動(必要時)
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

// メール通知
Unattended-Upgrade::Mail "your@email.com";
Unattended-Upgrade::MailReport "on-change";

7. 侵入検知の基礎

7.1 ログ監視

サーバーログを定期的に確認すると、異常な兆候を早期に発見できます。

# 認証ログ確認(SSH接続試行)
sudo tail -f /var/log/auth.log

# 失敗したログイン試行確認
sudo grep "Failed password" /var/log/auth.log | tail -20

# 成功したログイン確認
sudo grep "Accepted" /var/log/auth.log | tail -20

# システムログ確認
sudo journalctl -xe

# 最近のログイン記録
last
lastb  # 失敗したログイン

7.2 AIDEを使ったファイル整合性チェック

AIDE(Advanced Intrusion Detection Environment)はファイルシステムの変更を検知するツールです。

# AIDEインストール
sudo apt install aide

# 初期データベース作成
sudo aideinit

# データベース適用
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# 整合性チェック実行
sudo aide --check

# cronで定期チェック設定
sudo crontab -e
# 毎日深夜4時にチェック
0 4 * * * /usr/bin/aide --check | mail -s "AIDE Report" your@email.com

7.3 rkhunterでルートキットチェック

# rkhunterインストール
sudo apt install rkhunter

# データベース更新
sudo rkhunter --update

# 属性更新
sudo rkhunter --propupd

# ルートキットチェック実行
sudo rkhunter --check

# 自動チェック設定(cron)
sudo crontab -e
0 5 * * * /usr/bin/rkhunter --check --skip-keypress 2>&1 | mail -s "rkhunter Report" your@email.com

8. セキュリティチェックリスト

ホームサーバーセキュリティのためのチェックリストをまとめました。

項目 設定状態 重要度
UFWファイアウォール有効化 必須
SSH鍵認証設定 必須
SSHパスワード認証無効化 推奨
fail2banインストールと設定 推奨
SSHポート変更 オプション
rootログイン無効化 推奨
SSL/TLS証明書適用 必須(Webサービス)
自動セキュリティアップデート 推奨
定期的なログ確認 推奨

まとめ

セキュリティは一度設定して終わりではなく、継続的に管理する必要がある領域です。この編で扱った基本的なセキュリティ設定をしっかり行っておけば、ほとんどの自動化された攻撃からサーバーを保護できます。

次の編では、サーバー運用に欠かせないバックアップ戦略とモニタリングについて見ていきます。いくらセキュリティを徹底しても予期せぬ事態は発生する可能性があるので、バックアップとモニタリングで万が一の事態に備えることが賢明です。

質問や問題があれば、コメントで残してください。一緒に解決していきましょう。