はじめに:自分のサイト、どれくらい見られてるの?
ConoHa VPS(KUSANAGI)でWordPressサイトを動かしていると、ふと「今日は何人くらい来てくれたのかな?」と気になりますよね。
そこで、Windowsに最初から入っている「PowerShell(パワーシェル)」を使って、サーバーの中にある「アクセスの記録(ログ)」をのぞいてみました。
すると…1日およそ3,000回、知らない誰かがWordPressにログインしようとしていることが発覚!
この記事では、
- PowerShellでアクセス数を調べる方法
- GoAccess(ゴーアクセス)でグラフ付きのレポートを作る方法
- 見つけた攻撃を、Jetpackアプリは使えるままブロックする方法
を、小学生でもわかるように、つまずいたポイントも全部ふくめて説明します。
この記事の作業環境
| 項目 | 内容 |
|---|---|
| サーバー | ConoHa VPS |
| OS | AlmaLinux 9 |
| KUSANAGI | Version 9.11 |
| Webサーバー | nginx 1.29 |
| 自分のパソコン | Windows(PowerShell) |
| サイト | WordPress 3サイト(Jetpack使用) |
まずは言葉の説明
むずかしい言葉が出てくるので、先にたとえ話で説明しておきます。
| 言葉 | たとえると… |
|---|---|
| VPS | インターネット上にある「自分専用の家」。サイトはこの家に住んでいます。 |
| PowerShell | 文字で命令を打ちこむ黒い(青い)画面。Windowsに最初から入っています。 |
| SSH | 自分のパソコンから、VPSという家に入るための「秘密のトンネル」。 |
| ログ | 家の玄関にある「来客ノート」。誰がいつ来て、どの部屋に行ったかが全部書かれています。 |
| nginx(エンジンエックス) | 玄関に立っている「門番」。お客さんを家に通すかどうか決めます。 |
| xmlrpc.php | WordPressの「裏口」。スマホアプリなどが使う入口ですが、悪い人にもよく狙われます。 |
| Jetpack | WordPressの便利プラグイン。スマホのJetpackアプリは、この裏口を通ってサイトとやりとりします。 |
| 200 | 門番の返事で「どうぞ、お入りください」。 |
| 403 | 門番の返事で「あなたは入れません!」。 |
手順1:PowerShellからVPSに入る
Windowsのスタートボタンを右クリックして「ターミナル」または「Windows PowerShell」を開きます。そして、次の命令を打ちます。
ssh -o ServerAliveInterval=60 -p 12345 root@203.0.113.1「12345」は自分のSSHポート番号、「203.0.113.1」は自分のVPSのIPアドレスに書きかえてください。日本語の「ポート番号」などをそのまま貼り付けても動きません(私はやりました…)。
-o ServerAliveInterval=60 は「60秒ごとに、まだつながってるよ!と合図を送る」という意味です。これを付けないと、しばらく放っておいたときに勝手に接続が切れてしまうことがあります。
パスワードを入れて、画面にKUSANAGIの大きなロゴが出たら入れました。
今どこにいるか見分けるコツ
これがとても大事です。画面の一番下の行を見てください。
| 表示 | 今いる場所 |
|---|---|
[root@vm-xxxx ~]# | VPSの中(サーバー) |
PS C:\Users\あなたの名前> | 自分のパソコン |
命令によって「VPSで打つもの」と「パソコンで打つもの」があるので、ここを間違えると動きません。
手順2:来客ノート(ログ)の場所を探す
KUSANAGIでは、サイトごと(プロファイルごと)にログが分かれています。まずはプロファイルの一覧を見ます。
ls /home/kusanagi/私の場合は kinri、mypc、nandemo、webcss の4つが出てきました。今回はmypcを例に進めます。
cd /home/kusanagi/mypc/log/nginx/
lsファイルがたくさん出てきます。
| ファイル名 | 中身 |
|---|---|
| access.log | http(鍵なし)のアクセス。ほとんどhttpsへの転送だけなので、あまり役に立ちません。 |
| ssl_access.log-日付 | https(鍵あり)のアクセス。本命はこっち! |
| 〜.gz | 過去の日のログを圧縮(ぎゅっと小さく)したもの。 |
| ssl_error.log | エラーの記録。 |
最初、私は access.log を数えて「75件しかない!?」とびっくりしました。今どきのサイトはほぼhttpsなので、ssl_access.log を見るのが正解です。
ちなみに ssl_access.log-20260922 は、9月22日に切り替わった「9月21日の1日分」のログでした。
手順3:ノートの書き方(形式)を確認する
ログの中身を3行だけ見てみます。
head -3 ssl_access.log-20260922こんな感じの行が出てきます(IPは例です)。
0.434 BYPASS - 203.0.113.50 - - [21/Sep/2026:00:01:16 +0900] "GET /pc/914.html HTTP/2.0" 200 5661 "-" "Mozilla/5.0 ..." "-"ここがポイントです。KUSANAGIのログは、ふつうのnginxのログと違って、先頭に「処理にかかった時間」と「キャッシュの状態」が付いています。そのため、ネットでよく見る集計コマンドをそのまま使うとズレてしまいます。
スペースで区切って、左から何番目に何があるかを数えるとこうなります。
| 番号 | 中身 | 例 |
|---|---|---|
| $1 | 処理時間(秒) | 0.434 |
| $2・$3 | キャッシュの状態 | BYPASS / – |
| $4 | 来た人のIPアドレス | 203.0.113.50 |
| $7・$8 | 日時(+0900が別扱いになる) | [21/Sep/2026:00:01:16 +0900] |
| $9 | やりかた(見る=GET、送る=POST) | “GET |
| $10 | 見たページのURL | /pc/914.html |
| $12 | 門番の返事(ステータス) | 200 |
手順4:コマンドでアクセス数を数える
毎回ファイル名を打つのは大変なので、「F」という箱に入れておきます。
F=ssl_access.log-20260922この箱は、SSHが切れるとからっぽになります。入りなおしたら、cdとこの行をもう一度打ってください。からっぽのまま命令を打つと、画面が止まったように見えます(そのときは Ctrl + C で止めます)。
全部で何回アクセスがあったか
wc -l $F結果:4,389回(ロボットや画像の読み込みも全部ふくみます)
何人来たか(ロボットを除く)
grep -viE 'bot|crawl|spider' $F | awk '{print $4}' | sort -u | wc -l結果:481人。名前に bot や spider が付いているロボットを除いて、IPアドレスの種類を数えています。
よく見られたページのランキング
grep -viE 'bot|crawl|spider' $F | awk '$12==200 {print $10}' | grep -vE '\.(css|js|png|jpe?g|gif|webp|svg|ico|woff2?)|^/wp-' | sort | uniq -c | sort -rn | head -20ロボット・画像・WordPressの管理系を除いて、ちゃんと表示された(200)ページだけを数えています。
すると、ランキングの中に見慣れないものが…
314 /
60 //xmlrpc.php
39 /feed
7 /xmlrpc.php
7 /pc/914.htmlxmlrpc.php(WordPressの裏口)に、1日で67回もアクセスが来ていました。
手順5:裏口に来たのは誰?
grep 'xmlrpc.php' $F | awk '{print $4}' | sort | uniq -c | sort -rn | head -10 61 34.61.45.60
2 162.241.63.88
1 192.0.112.206
...9月21日の時点で、1つのIPから61回! ちなみに 192.0.112.206 の1回は、WordPress.com(Jetpack)のサーバーのIPです。その日、私はスマホのJetpackアプリで1回サイトを見ていたので、おそらくその分だと思います。自分は1回しか見ていないのに、別のIPから61回来ている…あやしいです。
何をしてきたのか調べる
grep '34.61.45.60' $F | head -334.61.45.60 の部分は、手順5で自分のログから見つけた「回数が多いIP」に書きかえてください。このIPは私のサイトに来た攻撃者なので、そのままだと何も表示されません。
わかったことはこちら。
| ログに残っていたもの | 意味 |
|---|---|
| CMS-Checker/1.0 | 「このサイトは何で作られてる?」を調べる道具の名前 |
| Chrome/78 | 2019年の古いブラウザのふり。変装の定番です |
| //wp-includes/wlwmanifest.xml | WordPressにしかないファイル。「WordPressかどうか」の確認 |
つまり、「何のサイトか調べる」→「WordPressだと確認」→「裏口からログインを試す」という、典型的な自動攻撃ロボットでした。
ログインを試みた? 成功した?
grep '34.61.45.60' $F | grep xmlrpc | awk '{print $9, $12}' | sort | uniq -c 1 "GET 200
60 "POST 20060回「POST(送信)」=ログインを試していました。でも、xmlrpc.phpは、パスワードが間違っていても「200」を返すので、これだけでは成功したかわかりません。そこで「返事の大きさ」を見ます。
grep '34.61.45.60' $F | grep xmlrpc | awk '{print $13}' | sort | uniq -c 60 508
1 82260回ともぴったり同じ508バイト=全部「パスワードがちがいます」という同じ返事です。全部失敗していて一安心。2段階認証も入れていたので、二重に守られていました。
手順6:GoAccessでグラフにする
コマンドの結果は数字だらけで見にくいので、GoAccessというツールでグラフにします。WordPressの管理画面ではなく、サーバーに入れるツールです。
インストール(VPSで打つ)
dnf install -y epel-release
dnf install -y goaccess
goaccess --versionバージョン番号(私は1.11)が出ればOKです。
KUSANAGI用の設定でレポートを作る
手順3で見たとおり、KUSANAGIのログは特別な形なので、--log-format で形を教えてあげます。これが一番大事なポイントです。
cd /home/kusanagi/mypc/log/nginx/
zcat -f ssl_access.log-2026* | LANG=C goaccess - --log-format='%T %^ %^ %h %^ %^ [%d:%t %^] "%r" %s %b "%R" "%u" %^' --date-format='%d/%b/%Y' --time-format='%H:%M:%S' --ignore-crawlers -o /root/report.html| 部分 | 意味 |
|---|---|
| zcat -f ssl_access.log-2026* | 圧縮した過去のログも、今のログも、まとめて読む |
| LANG=C | ログの「Sep」などの英語の月を正しく読ませるおまじない |
| %T %^ %^ %h | 処理時間・(無視)・(無視)・IPアドレス、という順番だよ、と教える |
| –ignore-crawlers | ロボットを除く |
| -o /root/report.html | 結果をHTMLファイルにして保存 |
最後の -o /root/report.html を消すと、PowerShellの画面の中に直接表示されます(q キーで終了)。
パソコンにダウンロードする(パソコンで打つ)
ここはVPSではなく、自分のパソコンのPowerShell(PS C:\… と出ている画面)で打ちます。VPSの中で打つと「Could not resolve hostname c:」というエラーになります。
scp -P 12345 root@203.0.113.1:/root/report.html C:\Users\あなたのユーザー名\Desktopssh はポート指定が小文字の -p でしたが、scp は大文字の -Pです。注意!
デスクトップにできた report.html をダブルクリックすると、ブラウザでグラフ付きのレポートが見られます。

レポートでわかったこと
| 項目 | 結果(8/1〜9/22) |
|---|---|
| 訪問者数(Unique Visitors) | 39,218人(1日600〜900人くらい) |
| リクエスト数のグラフ | ときどき2〜3万回にはね上がる日がある。でも訪問者数は増えていない=攻撃の日 |
手順7:攻撃の全体を数える
1か月半ぶんで、どこにPOST(送信)が来たかを数えます。
zcat -f ssl_access.log-2026* | awk '$9=="\"POST" {print $10}' | sort | uniq -c | sort -rn | head -10 126603 /xmlrpc.php
36949 //xmlrpc.php
2215 /wp-json/wordpress-popular-posts/v2/views/31
1863 /wp-login.phpxmlrpc.phpへの送信が約16万3千回。1日平均3,000回ペースでした。
Jetpackの「総当たり攻撃からの保護」はONになっていましたが、これはWordPressが動いた「後」で止める仕組みです。つまり毎日3,000回、WordPress(PHP)がむだに働かされていました。
そこで、玄関の門番(nginx)の時点で追い返すことにしました。
手順8:なぜ裏口を「全部」ふさがないの?
「xmlrpc.phpを全部ブロックすればいいじゃん」と思いますよね。でも、スマホのJetpackアプリは、WordPress.comのサーバーを通って、このxmlrpc.phpでサイトとやりとりしています。全部ふさぐと、アプリでサイトが見られなくなります。
そこで作戦はこうです。
| 来た人 | 門番の対応 |
|---|---|
| Jetpack(WordPress.com)のサーバー | どうぞ(許可) |
| それ以外の全員 | お帰りください(403) |
許可するIPは、Jetpack公式ページ「How to add Jetpack IPs to an allowlist」に載っているものを使います。このIPは変わることがあるので、ときどき公式ページを確認してください。
手順9:門番(nginx)の設定を書きかえる
設定ファイルの場所
cd /etc/opt/kusanagi/nginx/conf.d/
lsKUSANAGI 9では、サイトごとに3つのファイルがあります。
| ファイル | 役割 |
|---|---|
| mypc.conf | メインの設定 |
| mypc.wp.inc | WordPress用の設定(今回いじるのはここ) |
| mypc.proxy.inc | キャッシュ関係 |
まずはバックアップ
失敗してもすぐ戻せるように、コピーを取っておきます。
cp mypc.wp.inc mypc.wp.inc.bak中身を確認
grep -n -A3 '^#location ~\* /xmlrpc' mypc.wp.inc45:#location ~* /xmlrpc.php(/|$) {
46-# satisfy all;
47-# deny all;
48-#}KUSANAGIは、最初からxmlrpc.phpをブロックする設定を用意してくれています。でも、行の頭に # が付いていますね。これは「コメントアウト」といって、門番はこの行をただのメモとして無視します。つまり、今は効いていません。
しかも中身は deny all;(全員おことわり)なので、# を外すだけだとJetpackアプリまで使えなくなります。なので、この4行を「Jetpackだけ許可」版に置きかえます。
新しい設定を別ファイルで作る
エディタ(nano)で編集しようとしたら、キーが反応しなくて大失敗しました。なので、コピペだけでできる方法にしました。次の11行を、まとめて貼り付けてEnterします。
cat > mypc.xmlrpc.inc << 'EOF'
location ~* /xmlrpc.php(/|$) {
allow 122.248.245.244;
allow 54.217.201.243;
allow 54.232.116.4;
allow 192.0.64.0/18;
allow 195.234.108.0/22;
deny all;
include conf.d/fastcgi.inc;
}
EOF| 行 | 意味 |
|---|---|
| location ~* /xmlrpc.php | 「xmlrpc.phpに来た人には、次のルールを使うよ」 |
| allow 〜 | Jetpackのサーバーは通してOK |
| deny all; | それ以外は全員おことわり |
| include conf.d/fastcgi.inc; | 通した人は、ちゃんとWordPressにつなぐ(これがないとJetpackも動きません) |
Jetpack公式には 192.0.80.0/20・192.0.96.0/20・192.0.112.0/20 も載っていますが、これらは全部 192.0.64.0/18 の中に入っているので、まとめて1行にしています。
できたか確認します。
cat mypc.xmlrpc.inc#の4行を「読みこみ」の1行に置きかえる
sed -i '/^#location ~\* \/xmlrpc\.php/,/^#}/c\include conf.d/mypc.xmlrpc.inc;' mypc.wp.inc「#location ~* /xmlrpc.php の行から #} の行までを、include conf.d/mypc.xmlrpc.inc; の1行に置きかえてね」という命令です。
確認します。
grep -n -B2 -A2 'mypc.xmlrpc' mypc.wp.inc43-}
44-
45:include conf.d/mypc.xmlrpc.inc;
46-
47-location ~ [^/]\.php(/|$) {45行目に入りました。ふつうのPHPの設定(47行目)より前にあるのが大事です。門番は上から順番にルールを見るからです。
設定にまちがいがないかチェック
ここでつまずきました。nginx -t と打つと「コマンドが見つかりません」。KUSANAGI 9では、nginxが特別な場所に入っています。本当の場所を調べます。
ps aux | grep 'nginx: master'root 927734 ... nginx: master process /opt/kusanagi/nginx129/sbin/nginx場所がわかったので、フルパスでチェックします(nginx129の数字はバージョンによって変わります)。
/opt/kusanagi/nginx129/sbin/nginx -tnginx: the configuration file /etc/opt/kusanagi/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/opt/kusanagi/nginx/nginx.conf test is successful「syntax is ok」と「test is successful」の2つが出るまで、次に進んではいけません。
反映する
/opt/kusanagi/nginx129/sbin/nginx -s reload何も表示されずに戻ってくればOK。reload(リロード)はサイトを止めずに設定だけ読みなおすので、見ている人に迷惑はかかりません。
手順10:ちゃんと効いているか確認
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://example.com/xmlrpc.php
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/example.com は自分のサイトのURLに書きかえてください。
| 確認したもの | 結果 | 意味 |
|---|---|---|
| xmlrpc.php | 403 | 裏口は門前払い。成功! |
| トップページ | 200 | ふつうのページは今まで通り見られる |
最後に、スマホのJetpackアプリでサイトが今まで通り見られるかも確認しました。バッチリ動きました!
ほかのサイトにも同じ設定をする
同じVPSのnandemoとwebcssにも、同じ手順でやりました。中身は同じなので、ファイルをコピーするだけです。
cd /etc/opt/kusanagi/nginx/conf.d/
cp nandemo.wp.inc nandemo.wp.inc.bak
cp webcss.wp.inc webcss.wp.inc.bak
cp mypc.xmlrpc.inc nandemo.xmlrpc.inc
cp mypc.xmlrpc.inc webcss.xmlrpc.inc
sed -i '/^#location ~\* \/xmlrpc\.php/,/^#}/c\include conf.d/nandemo.xmlrpc.inc;' nandemo.wp.inc
sed -i '/^#location ~\* \/xmlrpc\.php/,/^#}/c\include conf.d/webcss.xmlrpc.inc;' webcss.wp.inc
grep -n 'xmlrpc.inc' nandemo.wp.inc webcss.wp.inc
/opt/kusanagi/nginx129/sbin/nginx -tチェックがOKなら反映します。
/opt/kusanagi/nginx129/sbin/nginx -s reloadcurlで確認して、403・200・403・200と出れば完了です。
もしJetpackアプリが動かなくなったら(元に戻す方法)
バックアップを取っておいたので、2行ですぐ元に戻せます。
cp /etc/opt/kusanagi/nginx/conf.d/mypc.wp.inc.bak /etc/opt/kusanagi/nginx/conf.d/mypc.wp.inc
/opt/kusanagi/nginx129/sbin/nginx -s reloadつまずいたポイントまとめ
| こまったこと | 原因 | 解決方法 |
|---|---|---|
| access.log が見つからない | ホーム(~)にいた | cd でログのフォルダに移動する |
| アクセスが75件しかない | http側のログを見ていた | ssl_access.log を見る |
| IPが1種類しか出ない | KUSANAGIはログの列がずれている | IPは$4、URLは$10、ステータスは$12 |
| 急に操作できなくなる | 放っておいてSSHが切れた | -o ServerAliveInterval=60 を付けて入りなおす |
| 命令を打つと止まる | 入りなおして $F がからっぽ | Ctrl + C で止めて、cd と F= をやりなおす |
| Could not resolve hostname c: | scpをVPSの中で打った | exit でパソコンに戻ってから打つ |
| nanoでキーが反応しない | 接続切れやキーの横取り | cat と sed のコピペ方式にする |
| nginx: コマンドが見つかりません | KUSANAGI 9は特別な場所にある | ps aux で場所を調べてフルパスで打つ |
まとめ
PowerShellとGoAccessでアクセス数を調べたら、1日3,000回ペースのログイン攻撃が見つかりました。
- 2段階認証とJetpackの保護で、ログインは全部失敗していた
- それでもWordPressがむだに働かされていたので、nginxの時点でブロック
- Jetpackのサーバーだけ許可したので、スマホアプリはそのまま使える
- KUSANAGIの「#付きの用意された設定」は、そのままでは効いていない
こういう攻撃は、WordPressサイトならどこでも毎日のように来ています。「自分のサイトは小さいから大丈夫」ではなく、一度ログをのぞいてみることをおすすめします。






コメント