WordPressが突然表示されなくなった原因は「サーバー障害」ではなかった話(ERR_CONNECTION_REFUSEDの正体)

背景

ある日、WordPressで作っているサイトにアクセスすると、突然表示されなくなりました。

ブラウザには「ERR_CONNECTION_REFUSED」。

SSHではサーバーに入れるのに、Webだけ死んでいる状態です。

最初はよくあるパターンで疑いました。

  • WordPressの不具合?
  • プラグイン更新ミス?
  • PHPエラー?

結論から言うと、どれも違いました。

原因は「サーバーのメモリ不足(OOM)」でした。

環境

  • OS:CentOS系
  • Webサーバー:Apache(mpm_prefork)
  • PHP:8.1系
  • メモリ:約487MB(VPS)
  • CMS:WordPress

原因

ログを追うと、次の事実が分かりました。

  • httpd が oom-killer によって強制終了されている
  • xmlrpc.php に対して大量のPOSTリクエスト
  • 同一IPから数秒おきにアクセス

つまり今回の原因は👇

xmlrpc.phpへの攻撃 → PHP処理増加 → メモリ枯渇 → Apache停止

WordPressのバグではなく、攻撃+リソース不足の組み合わせでした。

試したこと

① Apacheの状態確認

systemctl status httpd

結果:failed / killed

→ 自発的ではなく外部要因で停止

② OOMの確認

journalctl -k

結果:httpd invoked oom-killer

→ メモリ不足確定

③ プロセス確認

ps -ylC httpd --sort:rss

結果:

  • 軽いプロセス:7MB前後
  • 重いプロセス:40〜48MB

→ 一部の処理でメモリが膨張

④ アクセスログ確認

grep xmlrpc.php access_log

結果:

  • POST連打
  • 数秒間隔
  • 同一IP

→ 攻撃確定

解決手順

① Apacheを起動

systemctl start httpd

② xmlrpc.phpをブロック

<Files "xmlrpc.php">
    Require all denied
</Files>

③ Apache再起動

systemctl restart httpd

これでサイトは復旧し、攻撃も遮断できました。

なぜそうなるのか

今回のポイントは3つです。

  • xmlrpc.phpは外部からPOSTできる入口
  • POSTはPHPを実行するため負荷が高い
  • preforkはプロセス単位でメモリを消費する

この3つが重なると👇

少メモリ環境では簡単にOOMに到達します。

まとめ

  • ERR_CONNECTION_REFUSEDはアプリではなくサーバー層を疑う
  • httpdがkilledならOOMを確認
  • xmlrpc.phpは攻撃の入口になりやすい
  • 使っていないならブロック推奨

今回のようなケースは、WordPressの問題ではなくインフラの問題

より詳しい判断軸や、同じような障害で詰まらないための思考プロセスについては、noteでまとめています。

・なぜ最初にサーバーを疑うべきなのか
・xmlrpc攻撃の見分け方
・OOMの切り分け手順

気になる方は参考にしてみてください。

この記事はこんな人向け WordPressサイトが突然表示されなくなった ERR_CONNECTION_REFUSED が出て焦っている サーバー再起動で直るけ…
note.com