PR

自動投稿が403で止まった日の切り分け手順 サーバー設定が原因のとき何を見るか

毎朝10時に動いていた自動投稿が、2026年8月31日の朝だけ動きませんでした。原因はWordPressでもAIでもなく、サーバー側の設定でした。

切り分けそのものは3ステップで終わります。同じ場所で止まる人が多い箇所なので、手順をそのまま残しておきます。

ステップ1 その403を出したのは誰か

外部から記事を投稿する窓口に「XML-RPC」があります。スマホアプリや外部ツールから記事を送るための、古くからある仕組みです。ここが 403 Forbidden を返しました。

最初にやることは1つだけです。エラー画面の出どころを確かめます。

curl -s -o /dev/null -w "%{http_code}\n" https://example.com/xmlrpc.php
→ 405

405は「POSTしか受け付けない」という意味です。つまり窓口自体は生きています。ここで404が返るなら話は別で、ファイルごと無い状態です。

次にPOSTを送ります。返ってきたのは403でした。ただし中身のHTMLがWordPressのものではありません。文字コードがEUC-JPで、著作権表記にレンタルサーバー会社の社名が入っていました。

ここが分かれ道です。

  • WordPressが出した403 → JSON、またはサイトのデザインに沿った画面
  • サーバーが出した403 → ホスティング会社の定型ページ

後者だった場合、プラグインをいくら疑っても直りません。原因が管理画面の外にあるからです。ここを見ずにプラグインを1つずつ停止していくと、半日が消えます。

ステップ2 設定名ではなく説明文を読む

使っているのはエックスサーバーです。公式マニュアル「WordPressセキュリティ設定」に、該当する項目がありました。

「XML-RPC API アクセス制限」の説明はこうです。国外及び一部の国内ホスティングサービス環境のアドレスからの接続を制限する、と書かれています。

この項目が置かれている見出しは「国外アクセス制限設定」です。だから国内からなら関係ない、と読みたくなります。実際は違いました。国内の環境でも対象になり得ると、本文にはっきり書いてあります。

ここが今回いちばんの落とし穴でした。設定名で判断せず、説明文を最後まで読む。この1点だけで調査時間がかなり縮みます。

同じページには、もう1つ効く記述があります。「REST API アクセス制限」をONにすると記事の編集・保存が行えない場合があります、と公式自身が明記しています。つまり迂回路も同時に塞がっている可能性がある、という注意書きです。

ステップ3 401は「わざと間違えて」比べる

XML-RPCが駄目なら、新しいREST APIで投げればいい。そう考えて切り替えました。今度は 401 Unauthorized です。

ここで多くの人の手が止まります。パスワードが違うのか、それとも別の原因か。エラーだけ見ても判断がつきません。

そこでわざと存在しないIDとデタラメなパスワードで、同じリクエストを投げます。正しい認証情報の結果と並べると、一発で分かります。

ユーザー名とアプリパスワードを Basic 認証で送る
 → https://example.com/wp-json/wp/v2/users/me

【1回目】正しい認証情報 → 401 rest_not_logged_in
【2回目】デタラメな認証情報 → 401 rest_not_logged_in

読み方はこうなります。

  • 正しい方だけ通る → 認証情報の問題。アプリパスワードを作り直す
  • 間違えた方が incorrect_password を返す → やはり認証情報の問題
  • 両方とも rest_not_logged_in → 認証情報がWordPressまで届いていない

今回は3つ目でした。サーバーが途中で Authorization ヘッダーを捨てています。WordPressから見ると、誰もログインしていないリクエストに見えるわけです。この状態では、パスワードを何度作り直しても直りません。

比較対象を1つ作るだけで、原因の候補が半分に減ります。この考え方は他のAPI連携でもそのまま使えます。

直し方と、触る前の注意

WordPress公式のドキュメントでは、REST APIの認証にアプリケーションパスワードを使い、Basic認証のヘッダーで渡す方式が案内されています。裏を返せば、ヘッダーが届かない環境では動きません。

対処は .htaccess に次の1行を足すことです。

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

SetEnvIf は Apache の標準機能です。条件に合うリクエストへ環境変数を設定します。ここでは受け取った Authorization ヘッダーを、PHPが読める名前に入れ直しています。

念のため補足します。これは防御を弱める設定ではありません。認証情報を通すための設定です。

ただし .htaccess は書き間違えるとサイト全体が500エラーになります。触る前に必ずコピーを取ってください。自信がなければ、ここだけは分かる人に頼んだほうが安全です。

自動化している人が本当に持ち帰るべきこと

今回の教訓は技術ではありません。止まったことに気づく仕組みがあるかです。

自動投稿は、動いているあいだ何も知らせてきません。5日続けて公開できていたので、正直こちらも油断していました。止まったのは連休でも深夜でもなく、平日の朝です。

そのため公開処理を走らせる前に、その日すでに記事が出ているかを機械で確認する手順を入れてあります。今回もそこで異常に気づきました。人の目視は当てにしていません。

逆のことも書いておきます。更新が週1〜2本なら、自動投稿の仕組みは持たないほうがいいと考えています。壊れる部品が増えるだけです。管理画面から手で書くほうが速くて確実な規模は、確かにあります。

まとめ

  • 403はまず発行元を見る。ホスティング会社の画面ならサーバー設定を疑う
  • 設定名ではなく説明文を読む。「国外制限」が国内に効くことがある
  • 401は、わざと間違えた認証情報と比べる。それだけで原因が半分に絞れる
  • 自動化には「止まったら分かる」仕掛けを先に付けておく

出典

タイトルとURLをコピーしました