WordPress 管理画面に対して IP 制限を行っている場合に、テーマエディターやプラグインエディターなどでファイルを編集しようとすると「致命的なエラーをチェックするためにサイトと通信できないため、PHP の変更は取り消されました。」と表示されて編集できないことがあります。
このチェックをしてエラーメッセージを出しているのは wp-admin/includes/file.php
のこの部分
https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/file.php#L550-L633
WordPress は、まずループバックチェックをする対象のURLを決定します。
ループバックチェック対象のURLは、プラグインかテーマの編集いずれかによって変わります。
- プラグイン編集中の場合は
/wp-admin/plugin-editor.php?plugin=${plugin}&file=${file}
- テーマ編集中の場合は
/wp-admin/theme-editor.php?theme=${stylesheet}&file=${file}
- それ以外の場合は
/wp-admin/
// Attempt loopback request to editor to see if user just whitescreened themselves.
if ( $plugin ) {
$url = add_query_arg( compact( 'plugin', 'file' ), admin_url( 'plugin-editor.php' ) );
} elseif ( isset( $stylesheet ) ) {
$url = add_query_arg(
array(
'theme' => $stylesheet,
'file' => $file,
),
admin_url( 'theme-editor.php' )
);
} else {
$url = admin_url();
}
次に、その URL に対して__サーバから__ wp_remote_get()
で HTTP リクエストが行われます。
$url = add_query_arg( $scrape_params, $url );
$r = wp_remote_get( $url, compact( 'cookies', 'headers', 'timeout', 'sslverify' ) );
$body = wp_remote_retrieve_body( $r );
$scrape_result_position = strpos( $body, $needle_start );
なお WordPress 管理画面に BASIC 認証が設定されている場合に関しての考慮は wp-admin/includes/file.php#L536-L539
で行われているので安心です。
// Include Basic auth in loopback requests.
if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
$headers['Authorization'] = 'Basic ' . base64_encode( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) . ':' . wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );
}
話がずれましたが wp_remote_get()
の結果に $needle_start
("###### wp_scraping_result_start:$scrape_key ######"
) が含まれない場合は、管理画面へのループバックチェックが失敗したとみなされて、エラーとして処理されます。
if ( false === $scrape_result_position ) {
$result = $loopback_request_failure;
} else {
$error_output = substr( $body, $scrape_result_position + strlen( $needle_start ) );
$error_output = substr( $error_output, 0, strpos( $error_output, $needle_end ) );
$result = json_decode( trim( $error_output ), true );
if ( empty( $result ) ) {
$result = $json_parse_failure;
}
}
if ( true !== $result ) {
// Roll-back file change.
file_put_contents( $real_file, $previous_content );
wp_opcache_invalidate( $real_file, true );
if ( ! isset( $result['message'] ) ) {
$message = __( 'Something went wrong.' );
} else {
$message = $result['message'];
unset( $result['message'] );
}
return new WP_Error( 'php_error', $message, $result );
}
なので、WordPress 管理画面に IP制限を設定している場合は、自分のサーバのIPアドレスからのリクエストも許可するように設定しましょう。
AutoScaling などで、サーバのIPが固定できない場合は wp-admin/plugin-editor.php
, wp-admin/theme-editor.php
へのリクエストのみ IP 制限をかけないようにするか、そもそも WordPress 管理画面からテーマやプラグインの編集をしないようにしてください。
サーバ管理してる身としては「WordPress 管理画面からテーマやプラグインの編集をしないように」してもらった方がトラブルも少ないのでありがたいです。
現場からは以上です。