baserCMS WafController プラグインを作ってみました。
4系少しでもご安全に!プロジェクト第 1 弾です。
では、いつもの通りreadme.mdの写し。
WafController for baserCMS 4
ロリポップ!レンタルサーバーをはじめとする国内主要サーバーのWAF(SiteGuard Lite)による「管理画面での403誤検知エラーや502エラー」をサーバーインフラへの負荷をかけずに解決するbaserCMS 4系専用の自動WAFバイパスプラグインです。
概要
ロリポップ!などのレンタルサーバーのWAFは、ドメイン単位でしかオン/オフが設定できず、特定の管理画面URLだけを除外することができません。そのため、利便性のために「常時WAFオフ」という状態でサイト運用されるケースが多く見受けられます。
本プラグインは、「常時WAFオン」の安全な状態を維持したまま、「管理画面にログインして現在アクティブに操作している管理者のIPアドレスのみ」 を安全に検知し、.htaccess を動的に書き換えてWAFのシグネチャ検査を一時的に除外(バイパス)します。
通常の公開側アクセス(フロント画面)の裏ではプログラムは起動しないため、サーバーへのディスクI/O負荷やファイル破損リスク、表示速度低下の心配がない超軽量・安全設計です。また、管理画面のURLルーティング(カスタムプレフィックス)が変更されている環境であっても、自動的に追従して正常に動作します。
対象サーバー環境
- Apacheモジュール版
SiteGuard Liteが導入されているWebサーバー環境 - ロリポップ!レンタルサーバー(ライト・スタンダードプランで動作実証済み)
- その他、ヘテムル(heteml)/ さくらのレンタルサーバ / CPIサーバー など
参考: baserCMS公式サイト - レンタルサーバー毎の設定
セキュリティ設計と機能
- ピンポイント除外: WAFが解除されるのは、ログイン中の管理者の接続元IPアドレスのみです。
- 多重書き込み・競合の排除: 既に
.htaccess内に自分のIP設定が記述されている場合は、無駄なファイルの再書き込み(上書き保存)を自動でスルーするため、WAFシステムの連続リロードによる502エラーを防止します。 - 鉄壁のDoS防御機能: 外部からの悪意ある削除要求パケット(大量リクエスト)が届いた場合でも、
.htaccess内に該当するIPハッシュが存在しない時はファイルの書き込み(ロック)を一切発生させずに手前で即座に遮断(門前払い)します。 - 確実なタイムアウトとクレンジング機能: 管理者が画面を完全に閉じたり、30分間無操作の状態が続いたときはブラウザ側の死活監視機能が連動します。また、明確な「ログアウト」ボタンの押下時には、ブラウザの通信切断に影響されないPHP側の内部フックが直接動作し、サーバー上の
.htaccessから自分のIP設定だけをピンポイントで確実に自動消去(クレンジング)します。 - 拡張性(ユーザーグループID判定): リスナーファイルの配列に数字を追記するだけで、システム管理者だけでなく、ブログ執筆者や外部ライターなどの特定の「ユーザーグループID」を一括してバイパス対象に含めることができます。
- IPv4 / IPv6 完全対応: 接続環境を問わず、動作します。
ファイルの構成
app/Plugin/
└── WafController/
├── Config/
│ └── setting.php
├── Event/
│ └── WafControllerControllerEventListener.php
└── webroot/
└── js/
└── waf_dead_timer.js
動作要件・導入前の準備(重要)
本プラグインは、サーバー全体の安全性を維持しながら管理者のアクセスを最適化するため、.htaccess ファイルおよびサーバー環境に対して以下の要件と準備が必要です。導入前に必ずご確認ください。
1. サーバー環境の要件
- リバースプロキシ環境(Cloudflare等)でのご利用について:
リバースプロキシやCDNを経由している環境で本プラグインを正常に動作させるには、Webサーバー(Apache)側で
mod_remoteipなどのIP復元設定が正しく行われ、PHPの$_SERVER['REMOTE_ADDR']に「真の接続元クライアントIP」が安全に格納されている必要があります。
2. .htaccess への専用マーカーの配置(推奨)
サーバー環境の違い(Apacheのバージョンや既存のRewriteルール等)による 500 Internal Server Error や記述順序の矛盾を防ぐため、.htaccess 内の安全な位置に本プラグイン専用の「挿入マーカー」を記述することを推奨します。
設定手順
サイトのルート直下にある .htaccess ファイルをテキストエディタで開き、以下のコメント行(マーカー)を 1行だけ 手動で書き加えて保存してください。
# [WAF_CONTROLLER_MARKER]
推奨される配置位置
Apacheの書き換えエンジンが有効化される記述の直後に配置するのが安全です。RewriteEngine On のすぐ下、または既存の書き換えルールの直前に配置してください。
記述例:
<IfModule mod_rewrite.c>
RewriteEngine On
# 本プラグイン用のマーカーをここに配置
# [WAF_CONTROLLER_MARKER]
RewriteBase /
RewriteRule ^index\.php\$ - [L]
...
</IfModule>
※ マーカーを配置しない場合は、自動的に .htaccess の最先頭へ除外設定が追記(フォールバック)されます。マーカーなしの状態であっても、IPハッシュによる重複チェック機能が働くため、設定が無限に増殖することはありません。
3. .htaccess ファイルへの書き込み権限の確認(パーミッション)
プラグインが動的に設定の追加・削除を行うため、.htaccess ファイルにPHPからの書き込み権限(サーバー環境に応じた 604 や 644 などの適切なパーミッション)が与えられているか確認してください。
設定ファイルの運用・カスタマイズ
本プラグインは、環境、運用に合わせた動作変更を行えるように専用の設定ファイルを設置しています。 設定を変更したい場合は、以下のファイルをテキストエディタで開き、配列内の数値を調整して保存してください。
- 設定ファイルのパス:
app/Plugin/WafController/Config/setting.php
カスタマイズ可能な項目
1. WAFバイパス対象グループの追加(target_group_ids)
デフォルトでは「システム管理者(ID: 1)」のみがWAF除外の対象となっています。ブログ執筆者や外部ライターなどの特定グループにもWAFバイパスを適用させたい場合は、ユーザーグループ一覧の「No」に記載されているIDを配列に追記してください。
'target_group_ids' => array(
1, // システム管理者(デフォルト)
2, // 例:ブログ編集者
3 // 例:外部ライター
),
2. 死活監視タイマーの有効時間変更(timeout_seconds)
管理画面を操作しない状況(管理画面を完全に開いたまま席を外す等)が 30分経過すると、ブラウザ側で警告ポップアップを表示すると同時に、サーバー上の .htaccess から該当のIP設定だけを自動消去(クレンジング)します。
タイマーの有効時間('timeout_seconds')は、秒数で設定変更できます。デフォルトは30分(1800秒)です。
'timeout_seconds' => 1800 // 実際の記事執筆時間を考慮し、極端に短い時間(15分未満)の設定は推奨しません。
なお、タイマーの有効期限は、ユーザーによる入力、保存などの操作が行われると自動で延長されます。
導入手順
インストール要件
- CMS本体: baserCMS 4.7.x以上(admin-second / admin-third テーマ対応)
- 動作環境: PHP 7.x 以上(PHP 8.x 対応)
インストール方法
- 本リポジトリをダウンロードし、フォルダ名を
WafControllerに変更します。 - baserCMS の
app/Plugin/ディレクトリ配下に配置します。 - baserCMS 管理画面の「設定」>「プラグイン管理」より、「WafController」 のインストールボタンをクリックして有効化します。
プラグインの仕様と動作ルール
本プラグインは、サーバー全体の安全性を維持しながら管理者のアクセスを最適化するため、以下の仕様と動作ルールに基づいて設計されています。
1. サーバー側WAF設定について
ロリポップ!等のコントロールパネル側でWAFが「有効」になっていることを前提に、.htaccess 側で特定IPの検査をスキップさせる仕組みです。プラグイン有効化後は、サーバー側のWAF設定を「有効(オン)」のまま運用してください。
2. .htaccess の書き込み権限(パーミッション)
公開領域トップ(WWW_ROOT)にある .htaccess に対し、PHP(プログラム)からの書き込み権限が必要です。通常は標準のパーミッション(604 や 644)のままで動作しますが、万が一除外設定が追記されない場合は、パーミッション設定を確認してください。
3. 端末のIPアドレスが変動した場合の挙動
モバイル回線(4G/5G)や一部のプロバイダ環境では、接続元のグローバルIPアドレスが短時間で変動することがあります。操作中にIPアドレスが変わると、直後の保存処理などで一時的に403エラー(WAF誤検知)が発生する場合があります。
- 対処法: 本プラグインが新しいIPアドレスを自動検知して
.htaccessを即座に更新するため、ブラウザの画面を一度リロード(再読み込み)するか、もう一度保存ボタンを押し直すことで、そのまま作業を続行できます。
4. 無操作タイムアウト(30分放置時の挙動)
管理画面を「開いたまま」の状態で30分以上操作を行わなかった場合、セキュリティのためWAF除外設定は自動的にタイムアウト(失効)します。
-
同一画面内で「30分間のカウントダウンがリセット(残り時間が30分に巻き戻る)」となる対象:
- 管理画面内での「クリック(click)」
- 管理画面内での「キーボード入力(keydown)」 (※これらのユーザー操作を検知した瞬間に、古いタイマーをその場でリセットし、再び残り30分からカウントダウンをやり直します。この間、サーバーへの余計な通信は一切発生しません)
-
画面の再読み込み(リロード)や、別メニューへ移動した場合: ページ遷移が発生した場合は、その移動先のページが起動した最初の1回のみサーバーにIPが維持(または再登録)され、そこから新しく30分間のカウントダウンが開始されます。
-
タイムアウト時の挙動: 完全に無操作のまま30分が経過すると、ブラウザ側で警告ポップアップを表示すると同時に、サーバー上の
.htaccessから該当のIP設定だけを自動消去(クレンジング)します。
5. プラグイン無効化(アンインストール)時の動作
baserCMSの管理画面から本プラグインを「無効化」する際、コアシステムのアラートよりも先に、本プラグイン独自のメッセージが起動します。
- 表示メッセージ:
このプラグインを無効化する準備を行います。よろしいですか?サーバー内にこのプラグインが作成した設定を安全な状態に戻します。...
これにより、アンインストール後に .htaccess 内に不要な記述が残るリスクを100%防ぎ、サーバー環境を確実に安全な初期状態(白紙)へと復元させます。
ライセンス
本プラグインは MIT License のもとで公開・配布されています。
HATTANTOCO