
サイト改ざんに気づく仕組み|一人運用で始める改ざん検知の作り方
「サイトは毎日見ています。おかしくなっていたら、さすがに気づくと思います」
——保守を任されている人なら、たぶん一度はそう思ったことがあるはずです。私もそう思っていました。
けれど、サイトの改ざんは見た目が変わらないまま起きることが少なくありません。トップページは今日も普通に開く。管理画面も普通に入れる。でも公開ディレクトリのどこかに、見覚えのないファイルが1つ増えている。検索エンジンから来た人にだけ、別のページが返っている。そういう形のほうが、むしろ多いのです。
だから「毎日見ているから大丈夫」は、残念ながら検知の仕組みにはなりません。かといって、高価な製品を入れるのも、一人運用の現場では現実的でないことが多い。この記事では、いま手元にあるもの(サーバー・ログ・Git・無料のツール)だけで、改ざんに気づく側に回るやり方を、小さい順に整理します。
結論:改ざん検知は、気づく入口を3つ持つと一気に楽になります。①外から(サイトの見え方の変化・検索エンジンからの通知)/②中から(ファイルの追加・更新の検知)/③記録から(ログイン・POST・更新の記録)。この3つのどれか1つでも仕込めば、気づける確率は大きく変わります。最初の一歩としていちばん費用対効果が高いのは、「昨日から更新されたファイルの一覧を、毎朝1通受け取る」こと。find 1行とcron1行で始められます。
なお、この記事は自分が管理を任されているサイト・サーバーに対して行う確認を前提にしています。他人の管理するサイトへの調査行為は対象外です。もし読んでいる途中で「これはもう改ざんされているかもしれない」と思ったら、検知の話より先に初動です。不正アクセスの疑いがあるときの初動と保全へ先に進んでください。
何が起きているか:改ざんは「隠れているほうが得」だから隠れる
昔ながらの「トップページが真っ黒になって犯行声明が出る」タイプの改ざんは、今では少数派です。理由は単純で、すぐバレると攻撃側の得にならないからです。
いま多いのは、気づかれないほうが長く使えるタイプです。
- SEOスパムの埋め込み:ページの中に、まったく関係のない業種の隠しリンクや、大量の別ページが仕込まれる。人の目には見えず、検索エンジンにだけ見えるように作られていることがあります。
- 条件付きのリダイレクト:検索エンジン経由で来た人、スマートフォンの人、初回訪問の人にだけ、別サイトへ飛ばす。管理者は普段ブックマークから直接開くので、いつまでも気づけません。
- アップロード用のファイル(Webシェル)の設置:画像置き場のような書き込み可能なディレクトリに、外から操作するための小さなファイルが1つ置かれる。見た目には何も起きません。
- 設定ファイルへの追記:
.htaccessや設定ファイルの末尾に数行足されるだけ。ファイルは増えないので、一覧を眺めても気づきにくい形です。 - 正規のファイルへの1行追記:もともとある
index.phpや共通の読み込みファイルに、難読化された1行が足される。ファイル名も更新日時の並びも自然に見えることがあります。
つまり、「異常が目に見える」という前提そのものが成り立たない。これは注意力の問題ではなく、そういう作りになっているだけです。見落としていたとしても、それはあなたの落ち度ではありません。
だからこそ、目でなく仕組みに見張ってもらう。ここから先は、その仕組みをいちばん軽いものから並べていきます。
気づく入口は3つある

改ざんに気づくルートは、大きく3つに分けられます。全部そろえる必要はありません。まず1つ。慣れたらもう1つ。それで十分に前進です。
① 外から気づく:サイトの「見え方」の変化を拾う
サーバーの中に入らず、外から見える変化で気づく方法です。手間がいちばん少なく、条件付きリダイレクトのような中を見ても分かりにくい改ざんに強いのが利点です。
- Google Search Console の通知を受け取れるようにしておく:サイトの所有者として登録しておくと、検索エンジン側で問題が検出されたときに知らせが届きます。すでに登録済みなら、通知先のメールアドレスがいま使っているものかだけ確認しておきます。退職者のアドレスのまま、というのは珍しくありません。
- 検索結果での自サイトの見え方をたまに見る:サイト名で検索して、身に覚えのないページタイトルや説明文が混じっていないか。SEOスパム型は、ここにいちばん早く出ます。
- 外形監視に「文字列チェック」を足す:すでに死活監視をしているなら、「HTTPステータスが200か」だけでなく、トップページに必ずあるはずの文字列(会社名など)が含まれているかまで見るようにします。多くの監視サービスに、応答本文のキーワード判定の設定があります。
- HTMLそのものの変化を見る:ブラウザではなくコマンドで取得して、ハッシュ(内容の指紋)を比べます。動的に変わる部分があると毎回変化してしまうので、変化の少ないページで試すのがコツです。
# 自分が管理しているサイトのトップページのHTMLを取得し、内容の指紋(ハッシュ)を出す
curl -s https://example.com/ | sha256sum
毎日の値を1行ずつファイルに残しておけば、変わった日が分かります。更新の多いサイトでは毎日変わってしまうので、その場合は「特定の1ページだけ」「フッターだけ」に絞ると使えます。
② 中から気づく:ファイルの追加・更新を検知する
いちばん本命の方法です。公開ディレクトリのファイルは、自分が触ったとき以外は変わらないはず——この当たり前を、機械に確認してもらいます。
いちばん軽い一歩は「昨日から更新されたファイルの一覧」を毎朝見ることです。
# 直近1日以内に更新されたファイルを、更新日時つきで一覧にする
# (公開ディレクトリのパスは自分の環境に置き換える)
find /var/www/html -type f -mtime -1 \
-not -path "*/cache/*" -not -path "*/logs/*" \
-printf '%TY-%Tm-%Td %TH:%TM %p\n' | sort
-printf はGNU版の find の書式なので、環境によっては使えません。その場合は -ls に置き換えれば同じ目的を果たせます。キャッシュやログのように毎日変わる場所は、-not -path で最初から除いておくと、一覧が「見る気になる長さ」に収まります。ここを面倒がると、たいてい続きません。
これをcronに1行入れて、結果を自分宛てに送ります。
# 毎朝6時、昨日更新されたファイルの一覧をメールで受け取る(送信コマンドは環境に合わせる)
0 6 * * * find /var/www/html -type f -mtime -1 -not -path "*/cache/*" -ls | mail -s "[daily] 昨日更新されたファイル" you@example.com
慣れてきたら、ベースライン(正常時のひかえ)と比べます。 更新日時は書き換えられることがあるので、内容そのものの指紋を取っておくとより確かです。
# 正常だと分かっている時点で、ハッシュの台帳を「公開ディレクトリの外」に作る
find /var/www/html -type f -print0 | xargs -0 sha256sum > /var/backups/baseline.sha256
# 後日、変化したファイルだけを洗い出す(OK以外の行=中身が変わった/消えたファイル)
sha256sum -c /var/backups/baseline.sha256 2>/dev/null | grep -v ': OK$'
ひとつ大事な注意点があります。ハッシュの台帳は「新しく置かれたファイル」を見つけられません。 台帳に載っていないので、比べようがないからです。Webシェルの設置はまさにこの型なので、ファイル一覧そのものの差分も一緒に見ます。
# 正常時のファイル一覧を控えておく
find /var/www/html -type f | sort > /var/backups/files-base.txt
# 後日、いまの一覧と比べる(「>」で始まる行が、新しく増えたファイル)
find /var/www/html -type f | sort | diff /var/backups/files-base.txt -
台帳は、必ず公開ディレクトリの外(できれば別サーバーやバックアップ先)に置きます。同じ場所にあると、いざというとき台帳ごと書き換えられている可能性が残ってしまいます。
Gitでソースを管理しているなら、すでに強力な検知の仕組みを持っています。
# 本番の作業ディレクトリで、管理下のファイルに差分がないかを見る
git status --short
git diff
身に覚えのない差分が出れば、それが答えです。まだGit管理でないなら、バージョン管理なしのソースをGitに載せる手順から始めると、改ざん検知は副産物としてついてきます。
WordPressなら、公式が配っているファイルとの照合が使えます。
# コアファイルが公式配布物と一致しているかを確認する(WP-CLI)
wp core verify-checksums
# 公式ディレクトリ由来のプラグインについても同様に確認する
wp plugin verify-checksums --all
自分でカスタマイズしたテーマや、公式ディレクトリ外のプラグインは対象外になります。「対象外のものが何か」を把握したうえで使うのが要点です。
もう少し本格的にやるなら、ファイルの改変検知に特化した仕組み(AIDEなど、OSのパッケージで導入できるもの)もあります。ただ、最初からこれを目指して力尽きるより、find 1行を毎朝受け取るほうがずっと価値があります。続くほうが強い、というのは運用の一般則です。
③ 記録から気づく:入られた痕跡を見る
ファイルが変わる前に、必ず誰かが入るか、何かが送られています。その記録から気づく入口です。
- 管理画面へのログイン成功の記録:見覚えのない時間帯・見覚えのないIPからの成功があれば、それだけで確認する理由になります。失敗ではなく成功を見るのがポイントです。
- SSH・FTPのログイン記録:
/var/log/auth.logや/var/log/secure(環境で名前が変わります)に、接続の成否が残ります。FTPは平文の場合があるので、記録と併せて使用そのものを見直す機会にもなります。 - アクセスログのPOSTリクエスト:ファイルを置くには、たいてい書き込みを伴うリクエストが要ります。POSTを時系列に並べると、不自然なパスが浮かびます。
# nginxの既定ログ形式の例。POSTのリクエストを時刻・送信元・パス・ステータスで拾う
grep '"POST ' /var/log/nginx/access.log | awk '{print $4, $1, $7, $9}' | tail -50
# 画像置き場など「本来プログラムが無いはずの場所」への .php アクセスを探す
grep -iE "/(uploads|files|images)/[^ ]*\.php" /var/log/nginx/access.log | tail -50
- ユーザーアカウントの増減:管理画面のユーザー一覧、サーバーのアカウント一覧に、追加された覚えのないものがないか。改ざん後に「戻ってこられる出口」として作られることがあります。
ログは、保存期間が短いとそもそも遡れません。ローテーションの世代数を確認して、少なくとも数週間は残るようにしておくと、いざというときの助けになります。
具体例:ある朝の「1件だけ増えたファイル」
小さな会社のコーポレートサイトを、ほかの業務と兼務で守っている担当者の例で、順番をたどってみます。
- 仕込んでいたもの:3か月前に、
find -mtime -1の結果を毎朝6時にメールで受け取るcronを1行だけ入れていた。ほとんどの日は「該当なし」で、正直あまり読まずに消していた。 - ある朝:一覧に1行だけ載っていた。
/var/www/html/wp-content/uploads/2026/07/の下に、.phpのファイルが1つ。画像しか置かないはずの場所に、プログラムのファイル。ここで手が止まった。 - 確認:中身は長い1行の難読化されたコード。心当たりはまったくない。この時点で「改ざんの可能性が高い」と判断し、消さずに初動へ切り替えた。ファイルの日時とパスを控え、アクセスログの同時刻を確認すると、そのファイルへのPOSTが数十件並んでいた。
- その後:関係者へ一報を入れ、被害の拡大を止める対応と、侵入経路(更新が止まっていたプラグイン)の特定へ進んだ。復旧後、
findの一覧に加えて、ハッシュの台帳を別サーバーへ置く運用を追加した。
この例で効いたのは、高機能な製品ではありません。「置いた覚えのない場所に、置いた覚えのない種類のファイルがある」と気づけたこと。それだけです。そして、もし気づいていなければ、その .php は何か月も静かに使われ続けていたはずです。
もうひとつ大事なこと:この担当者は、見つけたファイルをすぐに消しませんでした。消すのがいちばん自然な反応ですが、消すと侵入経路の手がかりも一緒に消えます。詳しい順番は不正アクセスの疑いがあるときの初動と保全にまとめています。
影響:仕組みを持つと、何が変わるか
改ざん検知を仕込むと、防御力が上がる以上に、日々の気持ちの持ちようが変わります。
- 「たぶん大丈夫」から「昨日までは大丈夫だった」に変わる。根拠のない安心ではなく、確認済みの範囲がはっきりします。
- 気づくまでの時間が縮む。改ざんの被害は、多くの場合気づかれずに経過した期間で大きくなります。半年後に検索エンジン経由で知らされるのと、翌朝の一覧で気づくのとでは、その後の作業量がまるで違います。
- 上司や取引先に説明できるようになる。「毎朝、公開ディレクトリの更新を確認しています」と言えるのは、想像以上に強い一言です。セキュリティ製品の予算が取れない現場でも、やっていることを示せるのは意味があります。
- 調べるときの土台になる。何かあったとき、ベースラインがあれば「どこが変わったか」を短時間で絞れます。無い状態から探すのとは別の作業です。
そして、いちばん大きいのはこれかもしれません。気づける仕組みがあると、四六時中気にしなくてよくなります。 常に不安を抱えているより、朝の1通に任せるほうが、心も業務も持続します。
明日やること:cronを1行だけ足す
大きな設計は要りません。明日できる、いちばん小さな一歩はこれです。
- 公開ディレクトリの正確なパスを確認する。Webサーバーの設定(
DocumentRootやrootの行)で確かめます。思い込みのパスで監視していた、は本当によくあります。 findを手で1回叩いてみる。find <公開ディレクトリ> -type f -mtime -1 -lsを実行して、普段どのくらい変わるのかを体感します。ここで大量に出るなら、キャッシュ・ログ・アップロード先を-not -pathで除きます。- 1行だけcronに入れる。毎朝、その結果を自分が必ず見る場所(メールでもチャットでも)へ送ります。まずは毎日「該当なし」が届く状態を作れば十分です。
- Search Console の通知先メールアドレスを確認する。登録していなければ登録を、していれば宛先が現役のアドレスかを見るだけです。5分で終わります。
- 「見覚えのないものが出たら消さずに相談」とメモに1行書いておく。将来のいちばん焦っている自分に向けた申し送りです。
1と3だけでも、今日と明日で確実に変わります。完璧な検知より、明日から動いている検知のほうが、現場では強いです。
改ざん検知チェックリスト
いま自分の現場でどこまでできているかを見る項目です。全部そろえる必要はありません。
まず外せない最低ラインはこの3つです。ここだけ押さえられれば十分に前進です。
- 【最低ライン】公開ディレクトリの「昨日から更新されたファイル」を、毎日どこかで見られる状態にしたか
- 【最低ライン】検知の通知先(メールなど)が、いま自分が必ず見る宛先になっているか
- 【最低ライン】見覚えのないファイルを見つけたとき、消す前にやることを決めてあるか
次の項目は、余裕ができたときに1つずつ足していく分です。当てはまらないものは飛ばして大丈夫です。
- 正常時のハッシュ台帳(ベースライン)を作り、公開ディレクトリの外に保管しているか
- ファイル一覧の差分も見ているか(ハッシュ台帳だけでは新規追加に気づけないため)
- ソースがGit管理下にあり、本番で
git statusを確認できる状態か - WordPressなら、コア・プラグインのファイル照合を定期的に実行しているか
- アップロード先など書き込み可能なディレクトリで、プログラムの実行を止めているか
- Search Console など、検索エンジン側からの通知を受け取れる状態か
- 死活監視に「本文の文字列チェック」を足しているか(200が返るだけでは中身は分からないため)
- 管理画面・SSH・FTPのログイン成功の記録を、たまに見ているか
- ログの保存期間が、後から数週間さかのぼれる長さになっているか
- 改ざん前に戻せるバックアップがあり、戻せることを試したことがあるか
- 検知したあとの連絡先(社内・ベンダー・相談窓口)を、すぐ引ける場所に書いてあるか
全部に○が付かなくても大丈夫です。最低ラインの1つ目、find の一覧を毎朝受け取る。ここまで来ていれば、昨日までとは違う場所に立っています。
よければ、こちらも
改ざん検知は、単体で完結する仕事ではありません。周りを少しずつ整えると、検知そのものも軽くなります。
- 不正アクセスの疑いがあるときの初動と保全|まず止める順番:見つけたあとの順番です。検知の仕組みと対になるので、先に一度読んでおくと落ち着いて動けます。
- 公開ディレクトリの置きっぱなしファイル棚卸し|外から見えていないか:ベースラインを作る前に不要なファイルを減らしておくと、差分がぐっと読みやすくなります。
- セキュリティパッチ適用の判断と手順|止められない本番との付き合い方:侵入経路をふさぐ側の話です。検知と両輪で効きます。
- バックアップから戻せるかを確かめる|リストア訓練の手順:改ざんが見つかったときの復旧は、バックアップの中身しだいです。戻せることを一度確かめておくと安心です。
- バージョン管理なしのソースをGitに載せる手順|安全な最初の一歩:Git管理そのものが、日々の改ざん検知として働きます。

改ざんの話がしんどいのは、「気づけていないだけかもしれない」という疑いに終わりがないからだと思います。何も起きていない日でも、心のどこかが少し落ち着かない。ひとりで守っていると、その感覚を分け合う相手もいません。
でも、その落ち着かなさは、あなたが真面目に責任を持っている証拠でもあります。そして、その不安の大半は、確認を仕組みに預けることでずいぶん軽くなります。毎朝1通、「昨日は何も増えていません」と届く。それだけで、疑い続けなくてよくなります。
今日いきなり全部そろえなくて大丈夫です。まずは公開ディレクトリのパスを1つ確かめて、find を1回叩いてみるところから。それがもう、気づく側に回った最初の一歩です。
ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。