Synology NASで動かしているWordPressの脆弱性対策をやった話

はじめに

自宅のSynology NASで動かしているこのブログ、PHP 8.1のサポートが切れていたので、重い腰を上げて脆弱性対策をまとめてやりました。PHPを止めた瞬間にブログが見られなくなるところから始まり、管理画面が落ちたり、サイトが真っ白になったりと、なかなか波乱の1日でした。

同じように「NASでWordPressを自力で立てて、そのまま放置している」人の参考になればと思って、やったことと、ハマったところを書いておきます。

環境はこんな感じです。

  • NAS:Synology DS218play(メモリ1GB)、DSM 7.x
  • Webサーバー:Web Station(nginx+Apache 2.4)
  • DB:MariaDB 10
  • WordPress:自力で導入、テーマはCocoon

まずはバックアップ

何をするにも、まずはバックアップです。今回はこの2つを取りました。

  1. ファイル:File StationでWordPressのフォルダを丸ごとコピー
  2. DB:phpMyAdminでWordPressのデータベースをSQLとしてエクスポートし、PCに保存

ここで一つ気をつけたのが、コピー先を公開フォルダ(web)の外にすることです。web の中に「〇〇 – コピー」みたいなフォルダを作ると、それ自体がもう一つのWordPressとしてネットから見えてしまいます。wp-config.php の複製を .bak などの名前で置くと、DBのパスワードがそのまま読まれる危険もあります。

実際、過去の自分が web の中に古いWordPressのコピーやインストール用のzipを置きっぱなしにしていました。これも公開されない場所に移しました。

PHPを8.3に上げる

最初にやらかしたのがここです。パッケージセンターでPHP 8.1を止めたら、ブログが表示されなくなりました。Web Stationのウェブサービスが、PHP 8.1のプロファイルを使ったままだったからです。

SynologyでPHPのバージョンを変えるときは、次の順番でやるのが正解でした。

  1. パッケージセンターで新しいPHP(今回は8.3)をインストール
  2. Web Station →「スクリプト言語の設定」で、PHP 8.3のプロファイルを作る
  3. Web Station →「ウェブサービス」で、ブログのサービスのプロファイルを8.3に切り替える
  4. 動作を確認してから、古いPHPを止める・消す

拡張機能の入れ忘れ

切り替えたあと、表のサイトは見えるのに、管理画面だけ「重大なエラー」で開けなくなりました。wp-config.php で一時的にデバッグログを有効にして調べたところ、原因はzlib拡張機能が無効だったことでした。WordPressが更新確認の通信で圧縮データを展開するときに必要なので、管理画面だけが落ちていたわけです。

新しいプロファイルを作るときは、少なくとも次の拡張機能を有効にしておくのがお勧めです。

  • zlib、openssl、curl、mbstring、mysqli、iconv、zip、gd、exif、fileinfo、intl

あと、プロファイルの「PHPキャッシュを有効にする」がOPcacheのことです。これをオンにするだけで、表示がかなり速くなります。

デバッグログは使ったらすぐ消す

WP_DEBUG_LOG を有効にすると、wp-content/debug.log にログが書き出されます。このファイルはブラウザから誰でも読めます。サーバー内のパスなどが丸見えになるので、原因が分かったらすぐに設定を戻して、ログファイルも削除しましょう。

WordPress本体・プラグイン・テーマの更新

zlibを有効にした直後、WordPressがやっと外と通信できるようになったせいか、自動更新が勝手に走って本体が最新版(7.1.3)になりました。ここまではいいのですが、その直後にサイト全体が真っ白になりました。

原因は古いプラグイン「XML Sitemap & Google News」でした。新しいWordPress本体に追加された関数と同じ名前の関数を、このプラグインも定義していて、衝突していたんです。

管理画面に入れないときのプラグイン無効化

サイトが落ちていると、管理画面からプラグインを止めることもできません。そんなときは、File Stationで wp-content/plugins の中の該当フォルダの名前を変えます(例:xml-sitemap-feed → xml-sitemap-feed.disabled)。WordPressがプラグインを見つけられなくなって自動で無効化するので、サイトが復旧します。名前を戻せば元どおりなので、安全な応急処置です。

古いプラグインとテーマの更新

復旧後、プラグイン6件とテーマ7件をまとめて更新しました。2023年から更新していないものばかりでした。古いプラグインを放置すると、脆弱性が残るだけでなく、今回のように本体の更新で突然サイトが落ちる原因にもなります。

WordPressの更新画面。本体7.1.3が最新で、プラグイン・テーマ・翻訳もすべて最新版
更新後。本体・プラグイン・テーマ・翻訳がすべて最新になりました

サイトヘルスで見つかったREST APIのタイムアウト

WordPressの管理画面 →「ツール」→「サイトヘルス」は、設定の問題をまとめて教えてくれるので、一度は見ておくのがお勧めです。今回は「REST APIでエラーが発生しました(タイムアウト)」という致命的な問題が出ていました。あわせて「予約したイベントが遅れています」も出ていました。

NASが自分のドメインにたどり着けない原因

WordPressは動作確認や予約投稿のために、自分自身のURLに通信します。ところが、NASのDNS設定が「自動(ルーター任せ)」だと、NASから自分のドメインを引くとグローバルIPが返ってきます。家のルーターがこの「内から外向きの住所への折り返し」(NATループバック)に対応していないと、通信が届かずタイムアウトします。

NAS自身のDNSを使う

うちのNASには、もともと DNS Server パッケージで「自分のドメイン → NASのLAN内IP」を返す設定がしてありました。なので、NAS自身にそれを使わせるだけで解決しました。

  • コントロールパネル → ネットワーク →「全般」→「DNS Server の手動設定」
  • 優先DNS:127.0.0.1(NAS自身)、代替DNS:ルーターのIP

DNS Server側で、外部の名前を Google Public DNS などに転送する設定(フォワーダ)が有効になっていることも確認しておきましょう。これがないと、NASがインターネットの名前を引けなくなります。

ちなみに、同じ理由で、家のWi-Fiにつないだスマホからは自分のブログが見られません(モバイル回線なら見えます)。こちらは今回は放置しました。

対策後のサイトヘルス。ステータスは「良好」で、残りはおすすめの改善2件だけ
対策後のサイトヘルス。「良好」になりました

使わないものは消す・止める

セキュリティの基本は「攻撃される入り口を減らす」ことです。今回はこのあたりを片付けました。

  • 停止中のプラグインとテーマを削除しました。止めていても、ファイルが残っていれば脆弱性を突かれることがあります。テーマは使用中の子テーマと親テーマ(Cocoon)、それに予備の標準テーマを1つだけ残しました。
  • DBを丸ごと操作できるphpMyAdminの画面が、インターネットから開ける状態になっていました。WordPressの動作には関係ないので、パッケージセンターで「停止」にしておき、使うときだけ起動することにしました。
  • 公開フォルダの古い複製は先ほど書いたとおり移動しました。

phpMyAdminを常に使いたい場合は、Web Stationのアクセス制御で家のLANからだけ許可する方法もあります。ただ、ブログと同じポータルに入っていると、ブログまで外から見えなくなるので注意が必要です。

NAS側の整理

WordPressだけでなく、NAS本体も見直しました。

  • DSMを最新に更新しました。NAS本体の脆弱性対策としては、これが一番効きます。
  • 使っていないPHP 8.4と、サポートが終了したNode.js v18をアンインストールしました。Node.js v20/v22は他のパッケージが依存していたので残しています。Python2はDSMのシステム用なので、そもそも削除できません。
  • テレビ録画用のアプリをやめて、録画の共有フォルダごと削除しました。これで約156GB空きました。

NASの再起動

作業中にNASが重くなったので再起動したところ、「不適切にシャットダウンされました」という通知が出ました。起動後しばらくは、ブログが502や504エラーになりました。メモリ1GBのNASだと、起動直後に全パッケージが立ち上がるまでかなり時間がかかります。再起動はDSM右上のメニューから行い、終わったら10分ほど待つのが無難です。

ページキャッシュでの高速化

サイトヘルスで最後に残ったのが「ページキャッシュが検出されず、サーバーのレスポンスが遅い」でした。応答時間の中央値は約1.4秒で、推奨の0.6秒を大きく超えていました。

そこで、定番のキャッシュプラグインのWP Super Cacheを入れて、「簡単」タブで「キャッシング利用(推奨)」にしました。結果はこんな感じです。

ページキャッシュなしキャッシュあり
トップページ約1.6秒約0.05秒
記事ページ約2.4秒約0.03秒

ログイン中のユーザーにはキャッシュが効かない設定なので、記事の編集やプレビューには影響しません。非力なNASでWordPressを動かすなら、ほぼ必須だと思います。

WP Super Cacheの「簡単」タブで「キャッシング利用(推奨)」を選んだ画面
WP Super Cacheの設定は「簡単」タブで「キャッシング利用」を選ぶだけ

NAS+WordPressの脆弱性対策チェックリスト

今回やったことを、チェックリストにしておきます。

  • ファイルとDBのバックアップを、公開フォルダの外に取る
  • PHPをサポート中のバージョンに上げる(プロファイルの拡張機能とOPcacheも忘れずに)
  • WordPress本体・プラグイン・テーマを最新にする
  • 停止中のプラグイン・テーマを削除する
  • サイトヘルスの「致命的な問題」をゼロにする
  • 公開フォルダに、古い複製や .bak、debug.log を置かない
  • phpMyAdminなどの管理画面を、外から開けないようにする
  • DSMとパッケージを最新にし、使わないパッケージは消す

一番の教訓は「長く放置するほど、更新したときに壊れやすい」ということでした。2〜3年分の更新を一気にやったので、PHP・本体・プラグインの変更が重なってトラブルが連鎖しました。これからは、少なくとも月に1回は更新を確認しようと思います。

NAS運用
スポンサーリンク
nacre@nacre72をフォローする

コメント