こんな状態になっていませんか?
WordPressの運用で実際に困ることは、だいたい次の4つに絞られます。
当てはまるものがあれば、その答えのところから読んでください。
RESULT
本番で動いているサーバから取った数字
- 直近7日に自動で遮断したリクエスト
- 5,940 件
- 検査した64,700件の約9%
- 攻撃をどう捌くかを、人が毎回選別しなくてよい
- SSHへの総当たり攻撃
- 0 件
- 公開をやめて以降、ログに1件も残っていない
- SSHを守り切ったのではなく、攻撃の対象から消えている
- トップページの応答
- 0.06〜0.15 秒
- 3サイトともキャッシュから返している
- アクセスが集中しても、WordPress本体を忙しくさせない
- 再起動から全サービス復帰まで
- 約75 秒
- 2026-08-13 の再起動テストで実測
- 再起動のあと、担当者がログインしなくても全サービスが戻る
いずれも2026年8月25日に本番サーバで取得した実測値です(構築時の実機検証は2026年8月13日)。
このサーバは自社サービス「モトネタツーシン」を載せている環境で、構築も運用も自社で行っています。
落ちる場所を、先に無くしておく
「落ちないように頑張る」のではなく、「落ちる場所を先に無くしておく」。
攻撃を捌く仕組みを足すより、攻撃される場所を閉じるほうが確実だからです。
速くする仕掛けを足すより、そもそも重い処理を走らせないほうが確実なのも同じ理由です。
この先の4つの節は、この方針を「速さ」「攻撃」「障害」「運用」の4方向へ具体的に適用した結果です。
それぞれ、読者と運用者から見て何がどう変わるのかを先に書いてあります。
約束1
速い ― アクセスが集中しても、WordPress本体を忙しくさせない
「アクセスが集まると重くなる」の原因は、たいてい高速化プラグインの不足ではありません。
1回の表示にどれだけの処理が走る作りになっているか、という設計の問題です。
この基盤では、読者に返すHTMLをWordPressの手前で折り返しています。
普通のWordPressで何が起きているか
読者が1ページ開くたびに、PHPが起動し、データベースに何十回も問い合わせ、HTMLを組み立てて返します。
アクセスが10倍になれば、この処理も10倍走ります。プラグインが増えるほど1回が重くなり、ある地点で急に落ちます。
重さの正体は、読者の人数ではなく「読者1人あたりに走る処理の量」です。
この基盤の作り ― 手前のキャッシュで折り返す
-
ログインしていない読者のGETリクエストは、一定時間キャッシュから返します。
その間、PHPもデータベースも動きません。
同じページに短時間で人が集まっても、WordPressが動くのは最初の1回だけです。
-
記事の更新は時間の経過で自然に反映されます。
キャッシュを消して回る仕組みは作っていません。
消し忘れ・消し漏れという事故の種を持たないほうが、少し待つより確実だからです。
-
応答ヘッダに
X-Cache: HIT を出しているので、キャッシュが効いているかは誰でも確認できます。
3サイトともキャッシュから返っており、gzip圧縮あり(2026年8月時点の実測)。
約束2
攻撃されにくい ― ログイン画面を守るのではなく、公開インターネットから消す
パスワードを長くする、試行回数を制限するプラグインを入れる。どれも有効ですが、
扉が開いている限り、誰かが叩き続けることに変わりはありません。
この基盤で採ったのは、扉を強くする方向ではなく扉そのものを公開インターネットから消す方向でした。
横にスクロールできます →
公開インターネットから触れるのは読者向けの配信だけ。管理画面・ログイン画面・REST API・XML-RPC、
そしてSSH・データベース・検索エンジンは外から到達できない側に置いてある。
管理経路へはVPNのトンネルの中からしか入れない。
外から来たリクエストは、WordPressに届く前に403(拒否)で終わります。
xmlrpc.php に至っては応答を返さずに接続を切り、存在すら見せません。
運営者も、記事を投稿するシステムも、VPNのトンネルの中からしか管理経路へ入れません。
効きどころは「守りが固い」ことではない
攻撃者が試行する対象そのものが存在しないので、総当たりが原理的に成立しません。
破られる確率を下げたのではなく、試行の回数がゼロになる場所へ移した、という違いです。
トンネルが落ちれば「トンネル内の住所から来たパケット」自体が消えるため、追加の仕掛けなしに全面拒否へ倒れます。
安全側に倒れることが、機構ではなく構造として保証されています。
公開面に残る部分は、繰り返す送信元だけを自動で遮断しています。
1回踏んだだけでは遮断しません(打ち間違いの読者を巻き込むためです)。
再犯するほど遮断は長くなり、繰り返す相手ほど実質的な恒久遮断へ近づきます。
正規の検索エンジンのクローラは遮断対象から除外してあり、
誤って遮断した場合もコマンド1つで解除できます。
「攻撃対策を入れたらGoogleに巡回されなくなった」は実際によくある事故なので、
解除できることまでを設計に含めてあります。
来ているのは「WordPressを狙った攻撃」だけではありません。
そのサイトが使ってもいないソフトの既知の脆弱性まで、直近7日で22種類が機械的に試されています(2026年8月時点の実測)。
管理機能を外部から閉じたうえで、公開面には軽量な遮断ルールと自動遮断を採用しました。
汎用のルールセット型WAFは、処理負荷と継続的な誤検知の調整がこの構成に見合わないと判断し、採用していません。
対策が効いたことの、直接の証拠
SSHへの探査は、公開を止めて以降ログに1件も残っていません。
「攻撃が来ていた」→「遮断した」→「来なくなった」が観測できているという意味で、
これは設計の説明ではなく結果そのものです。2026年8月25日の再確認でも、探査は戻ってきていません。
約束3
壊れても、全体を止めない ― 障害を分離して、公開面を残す
壊れないことを前提にした設計は、壊れた瞬間に打つ手がなくなります。
この基盤は壊れる前提で、壊れたときに読者から何がどう見えるかを先に決めてあります。
キャッシュには猶予保持を持たせ、裏側が応答しなくなっても最大6時間は公開面が記事を返し続けます。
そのぶん、障害の連絡を受けてから対応するまでの時間に余裕ができます。
壊れたときに、読者から何が見えるか
いずれも机上の想定ではありません。PHPを停止したまま公開面が正常応答を返し続けることと、
検索エンジンを停止しても記事の閲覧が続き、データベース検索へ落ちないことを、
それぞれ実機で確認しています。
構築時に見つけた失敗 ― 猶予保持がエラーを配り続けた
当初、この猶予保持には欠陥がありました。裏でこっそり取りに行った再取得がエラー(502)を持ち帰ると、
そのエラーがキャッシュ上の正常なページを上書きしてしまい、復旧後もエラーを配り続けたのです。
構築時の検証で発見し、「裏の再取得が失敗したら、古い正常なページのほうを守る」よう直しました。
検証しなければ、本番で初めて出会っていた不具合です。
約束4
手離れがよい ― 更新・バックアップ・監視・復旧が、担当者の記憶に依存しない
派手さはありませんが、運用を任せる相手を選ぶときに実際に効いてくるのはこの領域です。
「作って納品して終わり」ではなく、誰も触らない日が続いても回り続ける状態を設計しました。
担当者が代わっても、引き継ぐのは手順の記憶ではなく設定そのものです。
更新は自動、ただし何でも自動にはしない
困る場面
脆弱性を放置はできません。かといって機能追加の更新が勝手に入ると、ある日サイトが壊れます。
この基盤の答え
OSのセキュリティ更新だけを自動で適用し、機能追加の更新は自動では入れません。WordPress本体・プラグイン・PHP・検索エンジンは版を固定し、更新は人が版を決めて実施します。
運用者にとっての結果
更新作業を思い出さなくてよく、それでいて知らないうちに挙動が変わることもありません。
証拠
再起動が必要なときだけ、バックアップの完了後に自動で再起動します。再起動テストでは約75秒で全サービスが復帰し、公開面が正常応答を返すことを実測しました。
バックアップは「戻せること」まで確認してある
困る場面
取っているつもりで復元できないバックアップは、無いのと同じです。
この基盤の答え
データベースを日次7世代、アップロードを週次と日次差分で保存し、社内へ複製したうえで、公開鍵暗号で暗号化してオフサイトにも保管します。復号できる秘密鍵はサーバ上に置いていません。
運用者にとっての結果
サーバが侵害されても、保管先の事業者からも、バックアップの中身は読めません。
証拠
復元リハーサルを実施し、後片付けまで完了しています。
異常のときだけ、1回だけ知らせる
困る場面
障害中に同じ通知が繰り返し届くと、受け取る側が通知を見なくなり、本当の障害を見落とします。放置したサーバが死ぬ原因の第1位はたいていディスクフルで、証明書の自動更新が失敗していることに気づかないのも同じくらい怖い状態です。
この基盤の答え
5分おきにサービスの死活・各サイトの疎通・証明書を点検し、同じ異常についての通知は再送しません。証明書は更新処理が失敗状態になっていないかと、残り日数とを別々に見ています(残り日数が減っていること自体が、更新の失敗が続いている兆候になります)。ログは種別ごとに保存期間と容量の上限を決めてあり、標準では設定が入らないものは自分で書きました。
運用者にとっての結果
通知が来たときだけ見ればよい状態になります。ディスクの空きも、証明書の期限も、担当者が見に行かなくて済みます。
証拠
疑似障害を起こし、実際に通知が受信箱へ届くところまで確認済みです。公開から12日でログの総量は91MB、ディスク使用率は2%にとどまっています。
問題が起きたら、元に戻せる
困る場面
「進むしかない移行」は、失敗したときに打つ手がありません。
この基盤の答え
移行と切り戻しの手順を用意し、DNSの向き先を戻すだけで旧環境へ帰れる構成にしてあります。
運用者にとっての結果
移行の判断が「やってみて、駄目なら戻す」で済むようになります。
アクセスログの保存期間は、ディスクを埋めないためだけに決めているわけではありません。
読者のIPアドレスを持ちすぎないためのプライバシー配慮でもあります。
どう実現しているか
ここまでが、読者と運用者から見た結果です。
ここから先は、それをどう実現しているかの話になります。
実現手段は3つあります。読者に返すHTMLをどこで折り返すか、
サーバにとって重い処理である検索を、どこで受けるか、
そしてそれらを、どれだけ小さな機械の上で成立させるかです。
リクエストが通る道
横にスクロールできます →
読者へ返すHTMLは、WordPressの手前のキャッシュで折り返して戻る。
PHPとデータベースまで届くのは、キャッシュの有効期間が切れた最初の1回だけ。
管理経路とバックエンドは、公開インターネットから到達できない側にまとめて置いてある。
検索は、標準を使わずに作り替えた
検索は、ページの表示とは比べものにならないほどサーバにとって重い処理です。
それでいて運営者にとっては「重くなる原因」であると同時に「読者が欲しがる機能」でもあるので、外すという選択は取れません。
そこで外すのではなく、WordPressの標準検索を使わず、専用の検索エンジンへ分離しました。
標準検索は無効化したのではなく、通らない経路にしてあります。
専用の検索エンジンを選んだ一番の理由は、機能が多いことではなく、
同時に処理する件数へ運営側から上限を置けることでした。
標準検索の実体はデータベースへの部分一致検索なので、「同時に何件まで受けるか」を運営側で決められず、
データベースが受けられるだけ受けてしまいます。記事が増えるほど検索1回が重くなるため、連打されたときの影響も大きくなっていきます。
分離すれば、ここに線が引けます。
処理しきれない量が来たら受付を止め、新着記事とカテゴリの導線へ切り替えます。
止まったときにデータベース検索へ落とさないのも同じ理由で、落としてしまえば結局そこが詰まるからです。
実機で検索エンジンを停止した状態で検索しても、サイトは正常応答を返し続け、
データベース検索へは一度も落ちませんでした。検索が止まっても、記事の閲覧は続きます。
これを、VPS1台の上でやっている
専用サーバでも、クラウドの大型インスタンスでもありません。
ごく一般的なVPSを1台借りて、その上に3サイトを載せています。
ここまで書いてきた速さも、攻撃への強さも、障害の分離も、
機械を大きくすることで買ったものではありません。
3サイト分すべて込みの値(2026年8月時点の実測)。
重い処理をそもそも走らせない作りにすれば、必要な資源は小さくなります。
読者に返すHTMLはWordPressまで届かず、検索は同時に処理する件数に上限を持ち、
攻撃の大半はWordPressを起動せずに入口で切れている ――
その結果が、この使用量です。
サーバの費用は、設計の結果として決まります。
- コンテナも、複数台の冗長構成も使っていない。すべてOS標準の仕組みで動かしているため、障害時に「どこを見ればいいか」が素直で、追加の学習コストを運用者に押しつけない
- サイトを増やすときは、設定ファイルを1つ置いてコマンドを1回。証明書の作業は発生しない(ワイルドカード1枚で全サイトを賄う設計のため)
- 構築手順はすべて手順書とスクリプトになっている。上から順に実行すれば同じ環境が再現でき、属人化しない
検証ハイライト
「設計上そうなるはず」と「実際にそうだった」は別物です。
構築時(2026年8月13日)に実機で確かめた項目から、代表的なものを抜き出しました。
使用技術
- Ubuntu Server 26.04 LTS(コンテナを使わないsystemd構成)
- nginx(TLS終端・遮断ルール・アクセス制御・レート制限)
- Varnish(キャッシュ。猶予保持つき)
- PHP 8.3-FPM(サイトごとに独立したプロセス群・上限)
- MariaDB 11.8(サイトごとにスキーマと権限を分離)
- Meilisearch v1.48(サイトごとに独立した検索エンジンのプロセス。WordPressとの連携は自作)
- WireGuard(管理経路のVPN)
- CrowdSec(ログ解析による自動遮断+nginxへの適用)
- Let's Encrypt ワイルドカード証明書(DNS認証・自動更新)
- unattended-upgrades / logrotate / systemd タイマー(自動更新・ログ整理・バックアップ・死活監視)
- age(バックアップの公開鍵暗号)/ rclone(オフサイト転送)
- WordPress(ブロックテーマ・mu-pluginsは最小構成)
記事生成側も公開サーバとは分離しており、片方の障害がもう片方へ波及しない構成です。
記事生成システムの詳細は別の実績で紹介しています。
この設計を、いまのWordPress環境に合わせてご提供できます
ここまで書いてきたのは、自社サービスとして自社で構築し、自社で運用している環境です。
お客様の環境で試した事例ではなく、私たち自身が毎日動かしているサーバの設計と実測です。
この構成をそのまま当てはめられるかは、サイトの性質によります。
たとえば会員向けのページやカートのようにログインした利用者ごとに中身が変わる部分は、
同じようにキャッシュで折り返すわけにはいきません。
どこを手前で返し、どこをWordPressまで通すのか ――
その線引きから、既存のサイトに合わせて設計します。
- WordPressの管理画面・APIを公開インターネットから外す構成への移行
- キャッシュ層の導入(プラグインに頼らず、アクセス集中に耐える高速化)
- 標準検索からの脱却(検索が重い・検索を叩かれると落ちるサイトの是正)
- 攻撃の自動検知・遮断の導入と、誤遮断を解除できる運用手順の整備
- セキュリティ更新・ログ整理・バックアップ・死活監視の自動化
- バックアップの暗号化オフサイト保管と、復元リハーサルまで含めた設計
- 既存環境を止めずに移行し、問題があれば戻せる移行計画と手順書の作成
サイトが落ちてから連絡が来る運用ではなく、落ちる前に落ちる場所を無くしておく運用を設計します。