2026年5月20日

2026年5月20日

WordPressのSSHアクセスをセキュアにする方法

はじめに

SSHはWordPressサーバーへの最も重要なアクセス経路です。デフォルト設定のままにしておくと、ブルートフォース攻撃・パスワード総当たり・不正ログインの標的になります。公開鍵認証への切り替えと適切な設定でリスクを大幅に削減できます。

症状・原因

  • /var/log/auth.logにSSHへのログイン試行が大量に記録されている
  • rootアカウントへの直接SSHログインが有効になっている
  • パスワード認証が有効でブルートフォース攻撃を受けている
  • SSHがデフォルトの22番ポートで動作しており攻撃を受けやすい

解決手順

ステップ1:現在のSSH設定を確認する

# SSH ログイン試行状況を確認
sudo grep "Failed password" /var/log/auth.log | tail -20
sudo grep "Invalid user" /var/log/auth.log | tail -20

# 攻撃元IPのランキング
sudo grep "Failed password" /var/log/auth.log \
    | awk '{print $(NF-3)}' \
    | sort | uniq -c | sort -rn | head -10

# 現在の SSH 設定を確認
sudo sshd -T | grep -E "permitrootlogin|passwordauthentication|port|pubkeyauthentication"

# 接続中のSSHセッションを確認
who
ss -tnp | grep :22

ステップ2:SSH 公開鍵認証を設定する

# クライアント側(自分のPC)で SSH キーペアを生成
ssh-keygen -t ed25519 -C "wordpress-server" -f ~/.ssh/wordpress_key
# → ~/.ssh/wordpress_key(秘密鍵)
# → ~/.ssh/wordpress_key.pub(公開鍵)

# サーバーに公開鍵を登録
ssh-copy-id -i ~/.ssh/wordpress_key.pub user@server-ip
# または手動で登録:
cat ~/.ssh/wordpress_key.pub | ssh user@server-ip \
    "mkdir -p ~/.ssh && chmod 700 ~/.ssh && \
     cat >> ~/.ssh/authorized_keys && \
     chmod 600 ~/.ssh/authorized_keys"

# 公開鍵でログインできることを確認してから次のステップへ
ssh -i ~/.ssh/wordpress_key user@server-ip

# クライアントの ~/.ssh/config に設定を追加
cat >> ~/.ssh/config << 'EOF'
Host wordpress-server
    HostName server-ip-or-domain
    User your-username
    IdentityFile ~/.ssh/wordpress_key
    IdentitiesOnly yes
EOF

ステップ3:SSH 設定を強化する

# /etc/ssh/sshd_config を編集
sudo nano /etc/ssh/sshd_config
# /etc/ssh/sshd_config: セキュリティ強化設定

# ポートを変更(22以外に変更してスキャンを回避)
Port 2222

# rootの直接ログインを禁止
PermitRootLogin no

# パスワード認証を無効化(公開鍵認証のみ許可)
PasswordAuthentication no
ChallengeResponseAuthentication no

# 空のパスワードを禁止
PermitEmptyPasswords no

# 公開鍵認証を明示的に有効化
PubkeyAuthentication yes

# 認証試行回数を制限
MaxAuthTries 3

# 接続数を制限
MaxSessions 3
MaxStartups 3:50:10

# ログインタイムアウト
LoginGraceTime 30

# 接続元IPを制限(自社IPのみ許可する場合)
# AllowUsers your-user@203.0.113.0/24

# X11フォワーディングを無効化
X11Forwarding no

# TCPKeepAlive
TCPKeepAlive yes
ClientAliveInterval 300
ClientAliveCountMax 2
# 設定を検証
sudo sshd -t

# SSH を再起動
sudo systemctl restart sshd

# ※ 必ず別のターミナルで接続テストをしてから元のセッションを閉じる
ssh -p 2222 -i ~/.ssh/wordpress_key user@server-ip

ステップ4:Fail2ban で SSH を保護する

# Fail2ban をインストール
sudo apt install fail2ban -y

# SSH 用の設定ファイルを作成
sudo nano /etc/fail2ban/jail.d/sshd.conf
# /etc/fail2ban/jail.d/sshd.conf

[sshd]
enabled  = true
port     = 2222
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 3
findtime = 300
bantime  = 3600
ignoreip = 127.0.0.1/8 203.0.113.0/24
# Fail2ban を起動
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban

# 状態確認
sudo fail2ban-client status sshd

# BAN されている IP を確認
sudo fail2ban-client status sshd | grep "Banned IP"

# 誤ってBAN された IP を解除
sudo fail2ban-client set sshd unbanip 203.0.113.1

ステップ5:WordPress から SSH 接続状況を監視する

// functions.php: SSH ログイン失敗をWordPressの通知と連携

// 毎時SSHログを解析して異常なアクセスを管理者に通知
add_action('wp', function(): void {
    if (!wp_next_scheduled('hourly_ssh_monitor')) {
        wp_schedule_event(time(), 'hourly', 'hourly_ssh_monitor');
    }
});

add_action('hourly_ssh_monitor', function(): void {
    $log_file = '/var/log/auth.log';
    if (!file_exists($log_file) || !is_readable($log_file)) return;

    // 過去1時間のログを解析
    $one_hour_ago = date('M d H', strtotime('-1 hour'));
    $failed_attempts = 0;
    $attacking_ips = [];

    $lines = file($log_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    foreach (array_reverse($lines) as $line) {
        if (strpos($line, $one_hour_ago) === false) continue;
        if (strpos($line, 'Failed password') !== false) {
            $failed_attempts++;
            if (preg_match('/from ([\d.]+)/', $line, $matches)) {
                $ip = $matches[1];
                $attacking_ips[$ip] = ($attacking_ips[$ip] ?? 0) + 1;
            }
        }
    }

    // 1時間に50回以上の失敗は警告
    if ($failed_attempts >= 50) {
        arsort($attacking_ips);
        $top_ips = array_slice($attacking_ips, 0, 5, true);
        $ip_list = '';
        foreach ($top_ips as $ip => $count) {
            $ip_list .= "  {$ip}: {$count}回\n";
        }

        wp_mail(
            get_option('admin_email'),
            '[警告] SSH ブルートフォース攻撃を検出',
            "過去1時間のSSH認証失敗: {$failed_attempts}回\n\n"
            . "攻撃元TOP5:\n{$ip_list}\n"
            . "Fail2ban で自動BAN されています。\n"
            . "確認: sudo fail2ban-client status sshd"
        );
    }
});

注意事項

  • SSHポート変更後・パスワード認証無効化前に、必ず新しい設定で接続できることを別ターミナルで確認してください。接続できなくなるとサーバーコンソール(VNCなど)からしか修復できません
  • 秘密鍵ファイル(~/.ssh/wordpress_key)は絶対に他人に渡さないでください。万が一漏洩した場合はすぐに~/.ssh/authorized_keysから対応する公開鍵を削除してください
  • クラウドサーバー(AWS EC2・GCP等)ではセキュリティグループ/ファイアウォールでSSHポートを自社IPのみに制限することを推奨します

まとめ

SSHのセキュア化は①ssh-keygen -t ed25519で鍵ペアを生成してssh-copy-idで公開鍵を登録、②sshd_configPasswordAuthentication noPermitRootLogin noMaxAuthTries 3Port 2222に設定、③設定テスト後に別ターミナルで接続確認してからsystemctl restart sshd、④Fail2banのmaxretry=3bantime=3600でブルートフォースを自動BAN、⑤WordPress cronで1時間ごとにSSHログを解析して50回以上の失敗でメール警告します。

お気軽にご相談ください

お見積りへ お問い合わせへ