
1.QMAC.JPの画面の改善
1-1. 静的アーカイブ(2007年以前のHP)をテーマの枠中に
1992〜2007年度の旧サイトHTML 39本が、ヘッダー・サイドバー・フッターの外に置かれていた
原本は書き換えず、配信のたびにPHPで変換する方式とした・・旧サイトの記録としての価値を損なわずに、見た目だけを揃る
/archive/2007/ → 00Index/Activities/2007(H19).htm を読む
→ の中身だけ抽出
→ 挿入ナビ・SSIコメント・重複フッターを除去
→ 相対パスを絶対URLに変換
→ .qmac-legacy で包んでテーマのテンプレートに流し込む
1-2. その他の改善
- 連絡先の移動・・ フッターは画面下端で見えないため、サイドバー最下部へ
- フッター 「© 2026 中国地区品質経営協会」のみ中央寄せ
- マニュアル
管理者・編集者以外にはサイドバーに表示しない - ログインボタン
ヘッダー右下。未ログイン時「ログイン」、ログイン時「管理画面」
2.QMAC.jpサイトのセキュリティ対策
2-1. 現状調査
| 観点 | 評価 |
| 攻撃されやすさ | 良好 — プラグイン1本、パーミッション適正、改ざんなし |
| 侵入時の被害 | やや弱い — 管理者が管理画面からPHPを書き換えられた |
| 気づけるか | 弱い — 改ざん検知なし |
| 戻せるか | 最も弱い — バックアップが全て同一サーバー内 |
| 続けられるか | 最も弱い — プラグイン・テーマの自動更新がオフ |
WordPressサイトの多くは「プラグイン20本・未更新・権限管理なし」という状態にあることが多い
主な発見
| 発見 | 深刻度 |
| プラグイン・テーマの自動更新がオフ | 高 |
| バックアップが同一サーバー内のみ | 高 |
| XML-RPC が有効(system.multicall が使える) | 中 |
| http://qmac.jp/ が暗号化されずに表示される | 中 |
| セキュリティヘッダがほぼ未設定 | 中 |
| 検証環境に wp-config.php.orig(DBパスワードが平文) | 中 |
| 公開フォルダに.bak系が25本 | 低 |
| DISALLOW_FILE_EDIT が未設定 | 中 |
2-2. 実施した対策
- ① wp-config.php.orig の削除・・検証環境の公開フォルダに、DBのパスワードが平文で書かれたファイルが置かれていた・・.orig はPHPとして処理されないため、Basic認証が外れた瞬間に中身がそのまま読める
- ② .bak 系61本を公開フォルダ外へ・・.bak → .new → php -l → mv という作業手順を守った結果、2日間で61本が蓄積していた・・手順そのものは正しいが、公開領域に残す理由がない
- ③ DISALLOW_FILE_EDIT・・管理画面からのテーマ・プラグイン編集を禁止・・管理者が乗っ取られても、PHPを書き込まれない・・ISALLOW_FILE_MODS は入れていない(自動更新まで止まるため)
2-3.自動更新の有効化
公式テーマとXserver製プラグインの自動更新で壊れる確率は低いので、自動更新にする
cloudsecure-wp-security → 自動更新 ON
twentytwentyfive(親) → 自動更新 ON
qmac / qmac-core(自作) → 対象外
2.4.HTTPS常時化とセキュリティヘッダ
http://qmac.jp/ がそのまま200で表示されていた。暗号化されない経路が生きている状態
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Header always set X-Content-Type-Options “nosniff”
Header always set X-Frame-Options “SAMEORIGIN”
Header always set Referrer-Policy “strict-origin-when-cross-origin”
Strict-Transport-Security と Content-Security-Policy は入れていない。設定ミスでサイトが開かなくなり、HSTSはブラウザが記憶するため取り消しが効きにくい
2-4.XML-RPC の無効化
system.multicall は1リクエストに数百通りのパスワードを詰められる。ログイン試行制限を実質的に回避される・・無効化の前に POST system.listMethods が 78メソッドを返すことを実測し、変更後に403になることを確認
2-5.ログイン保護(cloudsecure-wp-security)
移設時から無効のまま残っていたものを有効化・・30秒以内に5回失敗 → 600秒(10分)ロック
既定値(5秒/5回/60秒)は時間を空けて試す攻撃に無力であり、一方 3600秒は事務局への影響が大きい。中間を採った
締め出された場合の復旧手順を6通り整理し、SSHが使えない場合(phpMyAdmin、ファイルマネージャー)まで押さえた
2.6実施しなかったもの
| 機能 | 内容 |
| 定期バックアップ | 週1回・自動 |
| 世代管理 | 古いものを自動削除 |
| 復元 | 管理画面からボタン操作 |
3.QMAC.JPのバックアップ体制
3-1. UpdraftPlus (プラグイン) の導入
- 定期バックアップ・・週1回・自動
- 世代管理・・古いものを自動削除
- 復元・・管理画面からボタン操作
3-2. 保管先の変遷
- Google Drive(失敗)・・協会名義のGoogleアカウント「office QMAC」を作成し、認証を完了・・手動バックアップ1回が成功した・・しかし、これは認証直後の一時トークンで送れていただけだった
- FTP(sv13426)— 現在の構成・・FTP(sv13426)— 現在の構成・・・独立性は落ちるが、確実に動き続けて引き継げることを優先した・・・SSHで取りに行く方式(経路が暗号化され、より安全)も検討したが、自作スクリプトの保守と失敗通知の自作が引き継ぎ後に維持できないという理由で見送った
3-3. FTP設定で踏んだ問題
2度にわたり、バックアップがホーム直下に着地した
1度目:メインアカウントで送信・・サブアカウントの作成が完了していなかった・・平文FTPでパスワードが流れた(Xserver内・1回)そのパスワードが本番QMACのDBに保存された→ QMACが侵入されると sv13426 全体(iso_app本番を含む)へ波及・・・対処:メインアカウントのパスワードを変更。 古い値は無効になった
2度目:サブアカウントの接続先がホーム全体・・・ドメイン付きの正しいユーザー名で送信されたが、アクセス可能ディレクトリが制限されていなかった・・ メインアカウントのときと同じ危険があった・・・対処:接続先を /home/awl-web/qmac_updraft に変更
最終的な確認、FTPログイン後の位置は /
見えるのは qmac_updraft の中身だけ
ホーム全体は見えない、確認用ファイルは qmac_updraft 内に作られる、ホーム直下の更新時刻は変化しない、接続先の制限が効いていることを実測で確認
3-4. 復元テスト
検証環境 qmac.world に、本番のバックアップから復元できるかを試した
計画段階で発見した重大リスク・・本番のDBを world に取り込むと、UpdraftPlus の設定まで一緒に移る・・world の予約処理が一度でも動くと
→ world が本番と同じ保管先へ送信する
→ 保持世代の整理で、本番のバックアップを「自分の古い世代」とみなして削除しうる
対策として
- DISABLE_WP_CRON で予約処理を停止
- プラグイン本体を一時的にリネームして読み込まれないようにする
- DB取り込み直後、画面を開く前に設定を削除
の三重の防御を組んだ
結果
- ファイル展開・DB取り込み 約1秒
- 設定削除・URL置換(707か所) 約9秒
- 実処理の合計 約12秒
- 確認を含む作業全体 約6分
復元後の確認
- 認証なしで401(検証環境が公開状態にならないこと)
- 主要ページ200、旧URL140件すべて正常
- 行事200・固定ページ8・メディア387・ユーザー3名が本番と一致
- wp-config.php は復元対象外(DB接続先が本番に変わる事故を防止)
得られたもの
サーバーが生きている限り、復旧は12秒で済むという実測値。引き継ぎ資料に書ける数字になった・・そして何より、Google Drive が機能していないことを、この準備の過程で発見・・・テストをしなければ、10/5に失敗し、誰も気づかないまま「バックアップは取れている」と思い込むところだった

