FTPが使えない環境からサイトを更新する2つの方法——WordPress REST APIとHTTPS経由のファイル受け渡し

レンタルサーバーのファイルを更新する手段といえばFTPです。しかし作業する環境によっては、FTPそのものが使えないことがあります。認証情報は合っているのに、接続が成立しない。この状態から更新する方法を2つまとめます。

FTPが通らない環境がある

FTPは21番、SFTPは22番のポートを使います。社内ネットワーク、公衆Wi-Fi、クラウド上の実行環境などでは、この2つが閉じられていることがあります。

ポートが閉じている場合の症状には特徴があります。「パスワードが違います」とは出ません。応答が返らないまま時間切れになるか、接続を開いた直後に切断されます。

ここで認証情報を疑うと、時間を失います。FTPソフトの設定を何度も入れ直しても解決しません。判断の目安は次のとおりです。

症状 疑う場所
認証エラーが明示される ユーザー名・パスワード
応答がないまま時間切れ ポートが閉じている・接続方式
接続はできるがファイル一覧が出ない PASVモードなどの転送設定

FTPソフト側の設定で解決するケースについては、FFFTPで画像やファイルがアップロードできない!エラーを解消する設定と対処法にまとめています。

ポートが閉じている場合に残っているのは443番、つまりHTTPSです。ブラウザでそのサイトが表示できているなら、443番は通っています。ここを使います。

方法1:WordPress REST API

更新したいものが記事・固定ページ・画像であれば、これで足ります。WordPressは標準でREST APIを持っていて、HTTPS経由で投稿を作成・更新できます。追加のプラグインは要りません。

アプリケーションパスワードを発行する

WordPress 5.6以降には、アプリケーションパスワードという仕組みがあります。ログイン用のパスワードとは別に、外部アプリ用のパスワードを発行するものです。

発行場所は、管理画面の「ユーザー」から対象ユーザーの編集画面を開き、「アプリケーションパスワード」の欄です。用途の名前を入れて発行すると、4文字ずつ区切られた24文字が一度だけ表示されます。この画面を閉じると再表示できないため、その場で控えます。

使う側で不要になったら、同じ画面から個別に取り消せます。ログインパスワードを変えずに、そのアプリの権限だけを止められる点が、この仕組みの利点です。

HTTPSが必須です。公式ドキュメントでも、HTTPS経由での使用が前提とされています。

叩き方

Basic認証でユーザー名とアプリケーションパスワードを送ります。まず、権限の確認から始めるのが確実です。

curl --user "ユーザー名:xxxx xxxx xxxx xxxx xxxx xxxx" \
  "https://example.com/wp-json/wp/v2/users/me?context=edit"

rolescapabilities が返れば認証は通っています。投稿の作成は次のとおりです。

項目
エンドポイント POST /wp-json/wp/v2/posts
主な引数 titlecontentstatusslugcategoriesexcerpt
status に指定できる値 draftpublishpendingprivate

最初は draft で作るのが安全です。いきなり publish にすると、書式の崩れや文字化けが公開状態で表に出ます。下書きで作り、管理画面で表示を確認してから公開に切り替えます。

URLの形式はサーバーによって変わる

標準の形式は /wp-json/ です。ただしサーバー側のセキュリティ設定によって、この形式が403で弾かれることがあります。

× https://example.com/wp-json/wp/v2/posts      → 403
○ https://example.com/?rest_route=/wp/v2/posts → 200

実測した2件では、片方は /wp-json/ がそのまま通り、もう片方は403になって ?rest_route= 形式が必要でした。これはWordPressの不具合でも、認証情報の誤りでもありません。403を見て「アプリケーションパスワードが間違っている」と誤診しないことです。認証の誤りは401で返ります。

どちらの形式でも中身は同じREST APIです。まず /wp-json/ で試し、403なら ?rest_route= に切り替えます。

サーバー側で403を出している機能が何かを特定したい場合は、ロリポップで403エラーが出たとき——海外アタックガードとWAF、どちらが原因かの切り分けもあわせて参照してください。

方法2:HTTPSでファイルを受け渡す仕組みを置く

テーマファイル、静的HTML、CSS、画像といった記事以外のファイルを触る必要がある場合、REST APIでは届きません。この場合は、サーバー側に受信用のPHPを1つ置き、HTTPS経由で読み書きします。

ただし、これは最後の手段です。ファイルを書き込めるPHPを公開領域に置くことは、乗っ取りの入口を自分で作ることでもあります。合言葉が漏れれば、サイトの中身を書き換えられます。他に手段があるなら、そちらを選びます。

置くなら、最低限これを守る

守ること 理由
合言葉が合わなければ404を返す 「認証に失敗した」と返すと、そこに何かがあることを教えてしまう
公開フォルダの外へ出さない .. を潰したうえで realpath で範囲内に収める
.htaccess と自分自身は拒否する 設定ファイルを壊すとサイト全体が落ちる
削除機能を持たせない 取り返しがつかない操作を、そもそも実装しない
用が済んだら消す 常設すると、忘れた頃に残り続ける

不要になったファイルは、削除ではなく _to_delete/ のようなフォルダへ移動するだけにしておき、最終的な削除は管理画面やFTPから人の手で行います。間違えたときに戻せる形を先に用意してから始める、という考え方です。

書き込んだら md5 で照合する

この方法の利点は、転送後の照合ができることです。FTPソフトは転送したファイルの中身を照合しません。途中で切れた場合、サイズだけ合っていて中身が欠けている、という状態が起こり得ます。

受信側で書き込み後に md5_file() の値を返すようにしておけば、手元のファイルのmd5と突き合わせられます。一致していなければ、上げ直します。「上がったはず」ではなく「一致した」で判断できます。

弱点:最初の1回だけは人手が要る

受信用のPHPそのものは、FTPが通らない環境からは置けません。最初の設置だけは、サーバー会社のファイルマネージャーか、FTPが通る別の端末から行う必要があります。

使い分け

REST API 受信用PHP
触れるもの 記事・固定ページ・メディア 公開フォルダ内のファイル全般
初期設定 アプリケーションパスワードの発行のみ PHPを1つ、人手で設置
危険度 低い(権限は取り消せる) 高い(書き込み口が常に開く)
転送後の照合 投稿を取得し直して確認 md5で照合できる

記事を更新したいだけなら、REST APIで足ります。受信用PHPを検討するのは、テーマや静的ファイルを触る必要があり、かつFTPがどうしても通らない場合に限られます。

確認していないこと

  • /wp-json/ が403になる原因が、サーバー会社の既定設定なのか、個別の設定によるものなのかは切り分けていません。実測した2件の差でしかありません
  • ポートが閉じている環境で、FTPS(990番など)が通るかどうかは試していません
タイトルとURLをコピーしました