メインコンテンツまでスキップ

Apache単体で作る簡易ハニーポットWebページ設計

文書番号:2605.00005

本記事の位置づけ​

この記事では、Apache単体で動作する簡易ハニーポットWebページの実装設計を整理するのだ。

ハニーポットでどこまで情報を収集するか、POST本文や認証情報らしき入力を扱うかといった判断材料は、ハニーポットでどこまで情報を収集するべきか に分けるのだ。本記事は、その判断のうち「POST本文は保存しない」「Apacheログ中心で観測する」方針を採った場合の構成メモなのだ。

前提は次のとおりなのだ。

  • WebサーバはApache単体
  • PHP、CGI、Python、Node.js、DBは使わない
  • HTML、CSS、JavaScriptでログイン画面風のWebページを作る
  • ID/PASS入力欄を置く
  • POSTは受ける
  • ただしPOST本文は保存しない
  • 最優先は「侵害され、踏み台にされないこと」
  • 次点で「公開面への探索や認証試行のメタデータを観測すること」

この構成は、攻撃者を深く誘い込む高対話型ハニーポットではないのだ。インターネットに置かれた「攻撃の入口に見える観測点」として設計するのだ。

目次​

1. 基本方針​

今回のハニーポットは、攻撃者を深く誘導するものではないのだ。「ログイン画面らしきもの」をインターネットに置き、そこに対する探索、スキャン、認証試行の痕跡を観測するためのものなのだ。

最も重要なのは、ハニーポット自体が侵害され、第三者攻撃の踏み台にされないことなのだ。そのため、設計思想は次のようになるのだ。

  • 機能を増やさない
  • 動的処理を持たない
  • 認証成功を作らない
  • フォームPOST本文をアプリケーションで保存しない
  • アップロード機能を作らない
  • コマンド実行機能を作らない
  • 内部ネットワークに接続しない
  • 重要情報を同居させない
  • 観測はApacheログ中心にする

つまり、「攻撃者に触らせる面」は作りますが、「攻撃者が利用できる機能」は作らないのだ。

2. なぜApache単体にするのか​

ハニーポットというと、攻撃者の操作を深く観測するために、SSH、Telnet、Webアプリ、疑似DB、疑似ファイルシステムなどを用意する構成もあるのだ。しかし、今回の優先順位ではそれは過剰なのだ。

最優先が「侵害され、踏み台にされないこと」である以上、アプリケーション実装はできるだけ削るべきなのだ。Apache単体にする理由は明確なのだ。

  1. 実装バグを減らせる PHP、Python、Node.jsなどを使わなければ、アプリケーション層の脆弱性を大幅に減らせるのだ。
  2. 攻撃面を減らせる ファイルアップロード、DB接続、認証処理、セッション管理を持たないため、悪用できる機能が少なくなるのだ。
  3. 運用が単純になる Apacheの設定、静的ファイル、ログだけを管理すればよくなるのだ。
  4. 監視対象が明確になる アクセスログ、エラーログ、OSログに絞れるのだ。
  5. 壊れても業務影響が小さい 本番業務システムと切り離せば、可用性より安全性を優先できるのだ。

3. ハニーポットの目的を絞る​

この構成で得たい情報は、攻撃者の「侵入後の行動」ではないのだ。得たいのは、攻撃者が最初に何を探し、どのようなパターンでアクセスしてくるかなのだ。

収集範囲の一般論は、収集範囲の論点 を参照する必要があるのだ。本記事では、Apacheログで取得できる範囲に絞るのだ。

3.1 得たい情報​

  • どのIPアドレスから来たか
  • どのUser-Agentを使っているか
  • どのHostヘッダでアクセスしてきたか
  • どのパスを探索しているか
  • どのHTTPメソッドを使っているか
  • どの程度の頻度でアクセスしてくるか
  • POST /login を試したか
  • WordPress狙いか
  • .env や .git 狙いか
  • 管理画面狙いか
  • VPNやリモートアクセス基盤狙いか
  • APIや開発用エンドポイント狙いか

3.2 得ない情報​

逆に、今回の構成では次の情報は積極的に取得しないのだ。

  • 入力されたID
  • 入力されたパスワード
  • POST本文
  • 認証成功後の操作
  • 攻撃者が設置したファイル
  • マルウェアの挙動
  • C2通信
  • 攻撃者のシェル操作

ここを割り切ることが重要なのだ。深い情報を取りに行くほど、ハニーポット自体が危険なシステムになるのだ。

4. やること・やらないこと​

4.1 やること​

  • Apacheで静的HTMLを配信する
  • ログイン画面風のページを作る
  • ID/PASS入力欄を置く
  • form method="POST" action="/login" を設定する
  • POST /login を受ける
  • 常にログイン失敗画面へ遷移させる
  • Apacheアクセスログを詳細化する
  • 404や403の探索パスを記録する
  • User-Agent、Host、X-Forwarded-Forを残す
  • DocumentRootを読み取り専用に近づける
  • 不要なApacheモジュールを無効化する
  • ログローテーションを設定する
  • サーバを本番環境から分離する
  • 外向き通信を制限する

4.2 やらないこと​

  • 本物のログイン処理を作らない
  • 認証成功画面を作らない
  • DBを使わない
  • PHPを使わない
  • CGIを使わない
  • PythonやNode.jsを使わない
  • ファイルアップロードを作らない
  • 管理画面を作らない
  • Cookieやセッションを発行しない
  • JWTを発行しない
  • POST本文を保存しない
  • フォームPOST本文のID/PASSを保存する処理を実装しない
  • 外部APIに送信しない
  • 外部CDNを使わない
  • 実在企業名や実在ロゴを使わない
  • 攻撃者に反撃しない

5. 案A:POST先も静的に扱う​

今回採用するのは「案A」なのだ。

5.1 案Aの概要​

案Aでは、POST /login を受けますが、アプリケーションとして処理しないのだ。Apacheの設定で、POST /login をログイン失敗画面へリダイレクトするのだ。

つまり、サーバ側では次のことをしないのだ。

  • IDを読まない
  • パスワードを読まない
  • POST本文をパースしない
  • 認証判定をしない
  • DBに保存しない
  • セッションを発行しない

一方で、Apacheのアクセスログには、POST /login が来たという事実は残るのだ。

5.2 案Aのメリット​

  • 最も安全寄り
  • 動的処理がない
  • 実装バグが入りにくい
  • POST本文を保持しないため管理リスクが低い
  • ハニーポット自体が踏み台化されにくい
  • Apacheログだけで運用できる

5.3 案Aのデメリット​

  • 入力されたID/PASSの中身は分からない
  • クレデンシャルスタッフィングの詳細分析はできない
  • 攻撃者の侵入後行動は観測できない
  • 高対話型ハニーポットとしての情報量は少ない

5.4 なぜ案Aでよいのか​

今回の最優先は「踏み台化されないこと」なのだ。そのため、脅威インテリジェンス取得のために動的処理を増やすより、機能を削り、安全性を優先するのだ。

認証情報そのものよりも、次の情報に価値を置くのだ。

  • 誰が来たか
  • どのパスを探ったか
  • どの頻度で来たか
  • どのUser-Agentか
  • どのHostヘッダか
  • POST /login を試したか
  • 404探索の傾向は何か

これであれば、Apache単体でも十分に観測できるのだ。

6. 全体アーキテクチャ​

Internet
|
| HTTP / HTTPS
v
Apache
- 静的HTML配信
- CSS配信
- JavaScript配信
- POST /login 受付
- 303で失敗画面へ遷移
- アクセスログ記録
- エラーログ記録
|
| read only
v
/var/www/honeypot
- index.html
- login-failed.html
- assets/style.css
- assets/app.js
- error/*.html

ログ:
/var/log/apache2/honeypot_access.log
/var/log/apache2/honeypot_error.log

この構成で重要なのは、Apacheの背後にアプリケーションが存在しないことなのだ。攻撃者がPOSTしても、そこにログイン処理はないのだ。攻撃者が怪しいパスを探索しても、存在しないパスは404になるのだ。.env や .git などは明示的に403にするのだ。

7. 機能要件​

F-001 トップページ表示

ログイン画面風の静的HTMLを表示するのだ。

  • URL: GET /
  • 応答: 200 OK、index.html
  • 補足: 実在企業、実在製品、実在ロゴは使わないのだ。
F-002 ID/PASS入力欄

ログイン画面にID入力欄とパスワード入力欄を表示するのだ。

  • 入力項目: user、password
  • HTML属性: <form method="POST" action="/login" autocomplete="off">
  • 補足: フォームPOST本文はアプリケーションで保存しないのだ。URLやRefererはアクセスログに残り得るのだ。
F-003 POST受付

POST /login を受け付けるのだ。

  • URL: POST /login
  • 応答: 303 See Other でログイン失敗画面へ遷移
  • Location: /login-failed.html

方針は次のとおりなのだ。

  • 認証判定しない
  • 成功画面を返さない
  • セッションを発行しない
  • POST本文を保存しない
F-004 ログイン失敗画面

認証失敗風の静的画面を表示するのだ。

  • URL: GET /login-failed.html
  • 表示文言例: Authentication failed. Please check your credentials and try again.
  • 注意: 成功画面、管理画面、ダッシュボード画面へは進ませないのだ。
F-005 エラー画面

403、404、405、500用の静的エラー画面を表示するのだ。Apache標準エラーをそのまま出さず、見た目を統一するのだ。

  • /error/403.html
  • /error/404.html
  • /error/405.html
  • /error/500.html
F-006 静的アセット配信

CSSとJavaScriptを配信するのだ。

  • 外部CDNを使わない
  • 外部フォントを使わない
  • 外部画像を使わない
  • JavaScriptは演出のみに使う
F-007 ログ記録

記録対象は次のとおりなのだ。

  • 日時
  • 送信元IP
  • HTTPメソッド
  • パス
  • クエリ文字列
  • ステータスコード
  • レスポンスサイズ
  • Referer
  • User-Agent
  • Host
  • X-Forwarded-For
  • 処理時間
  • TLS有無

記録しない対象は次のとおりなのだ。

  • POST本文
  • 入力されたID
  • 入力されたパスワード
  • Cookie値
  • Authorizationヘッダ全文

8. 非機能要件​

8.1 安全性​

  • Apache単体で稼働する
  • 動的実行機能を無効化する
  • DocumentRoot配下は原則読み取り専用
  • Apache実行ユーザーに不要な権限を与えない
  • 外向き通信を遮断する
  • 重要情報を配置しない

8.2 可用性​

このハニーポットは業務システムではないため、高可用性は最優先ではないのだ。落ちても業務影響がない構成にするのだ。ただし、ログ肥大化によるディスク枯渇は避けるのだ。

8.3 保守性​

  • ファイル数を少なくする
  • Apache設定を単純にする
  • ログ分析は別環境で行う
  • ハニーポット本体に分析機能を持たせない

8.4 観測性​

  • アクセスログを厚めに取る
  • 404パスを分析しやすくする
  • POST試行を識別しやすくする
  • User-AgentとHostヘッダを残す

8.5 法務・倫理面​

  • フォームPOST本文の認証情報を保存する処理を実装しない
  • 実在企業名や実在サービス名を使わない
  • 第三者を誤認させるブランド表現を避ける
  • 攻撃者に反撃しない
  • 外部への能動的アクセスをしない

9. 画面設計​

9.1 画面一覧​

ID画面名パス
S1ログイン画面/
S2ログイン失敗画面/login-failed.html
S3403画面/error/403.html
S4404画面/error/404.html
S5405画面/error/405.html
S6500画面/error/500.html

9.2 S1 ログイン画面​

表示項目は次のとおりなのだ。

  • サービス名風タイトル
  • サブタイトル
  • User ID入力欄
  • Password入力欄
  • Sign inボタン
  • 監視文言
  • バージョン番号風表記

入力項目は user と password なのだ。送信先は POST /login とするのだ。

「本物の社内システム」と断定される表現は避けるのだ。実在企業、実在サービス、実在製品を模倣しないのだ。

9.3 S2 ログイン失敗画面​

表示項目は次のとおりなのだ。

  • Authentication failed
  • Please check your credentials and try again.
  • Back to sign in

遷移は / に戻るリンクのみなのだ。成功画面や管理画面には遷移させないのだ。

9.4 エラー画面​

403、404、405、500は静的HTMLで用意するのだ。Apache標準のエラー画面をそのまま見せないことで、見た目を統一できるのだ。

10. URL設計​

パスMethod挙動
/GETログイン画面
/index.htmlGETログイン画面
/loginPOST303で失敗画面へ遷移
/login-failed.htmlGETログイン失敗画面
/assets/style.cssGETCSS
/assets/app.jsGETJavaScript
/error/403.htmlGET403画面
/error/404.htmlGET404画面
/error/405.htmlGET405画面
/error/500.htmlGET500画面

10.1 POST /login の扱い​

POST /login は303で /login-failed.html に遷移させるのだ。

POST /login
↓
303 See Other
↓
GET /login-failed.html

この方式には次の利点があるのだ。

  • POST本文を処理しない
  • ブラウザ再読み込み時の再POSTを避けられる
  • アクセスログ上はPOST /login の事実が残る
  • 成功画面を作らずに済む

11. ディレクトリ設計​

/var/www/honeypot/
index.html
login-failed.html
assets/
style.css
app.js
error/
403.html
404.html
405.html
500.html

Apache設定ファイルは次の場所に置く想定とするのだ。

/etc/apache2/sites-available/honeypot.conf

ログは次のように分けるのだ。

/var/log/apache2/honeypot_access.log
/var/log/apache2/honeypot_error.log

11.1 権限方針​

対象所有者グループ権限
/var/www/honeypotrootroot755
静的ファイルrootroot644
assetsディレクトリrootroot755

Apache実行ユーザーには、DocumentRootへの書き込み権限を与えないのだ。

12. Apache設定設計​

12.1 基本方針​

Apache設定では、次の点を重視するのだ。

  • Apacheの情報露出を抑える
  • ディレクトリ一覧を無効化する
  • .env や .git を拒否する
  • CGIを使わない
  • Overrideを許可しない
  • POSTサイズを制限する
  • タイムアウトを短くする
  • ログを専用ファイルに分ける

12.2 必須設定​

ServerTokens Prod
ServerSignature Off
TraceEnable Off
Options -Indexes -FollowSymLinks
AllowOverride None
LimitRequestBody 8192
ErrorDocument 403 /error/403.html
ErrorDocument 404 /error/404.html
ErrorDocument 405 /error/405.html
ErrorDocument 500 /error/500.html

12.3 ログフォーマット​

この設定は観測情報を広く記録する設計例なのだ。%rは要求行を、%{Referer}i等は要求ヘッダーを記録するため、URLやヘッダーに機微情報が入ればログにも残り得るのだ。クエリだけを除いてもパスや他のヘッダーへの混入までは防げないのだ。公開前に収集項目、閲覧権限、保持期間、削除方法を決め、必要性のない項目を除くのだ。

ログ記法の根拠:https://httpd.apache.org/docs/2.4/mod/mod_log_config.html

LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\" \"%{X-Forwarded-For}i\" %D" honeypot
項目意味
%vVirtualHost名
%h送信元IP
%t時刻
%rリクエストライン
%>s最終ステータスコード
%bレスポンスサイズ
Referer参照元
User-Agentクライアント情報
HostHostヘッダ
X-Forwarded-Forプロキシ経由情報
%D処理時間、マイクロ秒

12.4 Apache設定サンプル​

ServerTokens Prod
ServerSignature Off
TraceEnable Off

LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Host}i\" \"%{X-Forwarded-For}i\" %D" honeypot

<VirtualHost *:80>
ServerName example.invalid
DocumentRoot /var/www/honeypot

ErrorLog ${APACHE_LOG_DIR}/honeypot_error.log
CustomLog ${APACHE_LOG_DIR}/honeypot_access.log honeypot

LimitRequestBody 8192
RequestReadTimeout header=10-20,MinRate=500 body=10,MinRate=500

<Directory /var/www/honeypot>
Options -Indexes -FollowSymLinks
AllowOverride None
Require all granted
</Directory>

<FilesMatch "^\.">
Require all denied
</FilesMatch>

<LocationMatch "^/(\.git|\.env|server-status|cgi-bin|phpmyadmin|phpMyAdmin)">
Require all denied
</LocationMatch>

RewriteEngine On
RewriteCond %{REQUEST_METHOD} =POST
RewriteRule ^/login$ /login-failed.html [R=303,L]

ErrorDocument 403 /error/403.html
ErrorDocument 404 /error/404.html
ErrorDocument 405 /error/405.html
ErrorDocument 500 /error/500.html
</VirtualHost>

12.5 必要モジュール​

必要なモジュールは次のとおりなのだ。

  • mod_rewrite
  • mod_reqtimeout
  • mod_log_config

通常有効なモジュールは次のとおりなのだ。

  • mod_authz_core
  • mod_authz_host
  • mod_mime
  • mod_dir

不要または無効化候補は次のとおりなのだ。

  • mod_cgi
  • mod_cgid
  • mod_php
  • mod_proxy
  • mod_proxy_http
  • mod_status
  • mod_autoindex
  • mod_userdir
  • mod_include

使わない機能は無効化するのだ。特に、CGI、PHP、Proxy、SSI、Status公開は避けるのだ。

13. HTML/CSS/JavaScript設計​

13.1 HTML設計​

HTMLは静的ファイルとするのだ。外部CDN、外部フォント、外部画像は使わないのだ。

index.html は次のようにするのだ。

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Secure Access Portal</title>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
<main class="page">
<section class="card">
<div class="brand">
<div class="logo">S</div>
<div>
<h1>Secure Access Portal</h1>
<p>Restricted system access</p>
</div>
</div>
<form method="POST" action="/login" autocomplete="off" id="loginForm">
<label for="user">User ID</label>
<input id="user" name="user" type="text" maxlength="64" required>
<label for="password">Password</label>
<input id="password" name="password" type="password" maxlength="128" required>
<button type="submit">Sign in</button>
</form>
<p class="notice">
Unauthorized access is prohibited. Activity may be monitored.
</p>
<p class="version">
Portal Version 4.2.1
</p>
</section>
</main>
<script src="/assets/app.js"></script>
</body>
</html>

13.2 ログイン失敗画面​

login-failed.html は次のようにするのだ。

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Authentication Failed</title>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
<main class="page">
<section class="card">
<div class="brand">
<div class="logo">S</div>
<div>
<h1>Authentication failed</h1>
<p>Secure Access Portal</p>
</div>
</div>
<p class="notice">
Please check your credentials and try again later.
</p>
<a class="link-button" href="/">Back to sign in</a>
<p class="version">
Portal Version 4.2.1
</p>
</section>
</main>
</body>
</html>

13.3 CSS設計​

assets/style.css は次のようにするのだ。

* {
box-sizing: border-box;
}

body {
margin: 0;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background: linear-gradient(135deg, #101827, #1f2937);
color: #111827;
}

.page {
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
}

.card {
width: 100%;
max-width: 420px;
background: #ffffff;
border-radius: 14px;
padding: 28px;
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.35);
}

.brand {
display: flex;
gap: 14px;
align-items: center;
margin-bottom: 24px;
}

.logo {
width: 48px;
height: 48px;
border-radius: 12px;
background: #1f2937;
color: #ffffff;
display: grid;
place-items: center;
font-weight: 700;
font-size: 24px;
}

h1 {
font-size: 22px;
margin: 0;
}

.brand p {
margin: 4px 0 0;
color: #6b7280;
font-size: 14px;
}

label {
display: block;
margin: 14px 0 6px;
font-size: 14px;
color: #374151;
}

input {
width: 100%;
padding: 12px;
border: 1px solid #d1d5db;
border-radius: 8px;
font-size: 16px;
}

button,
.link-button {
width: 100%;
display: inline-block;
margin-top: 22px;
padding: 12px;
border: 0;
border-radius: 8px;
background: #1f2937;
color: #ffffff;
font-size: 16px;
text-align: center;
text-decoration: none;
cursor: pointer;
}

button:hover,
.link-button:hover {
background: #111827;
}

button:disabled {
cursor: default;
opacity: 0.75;
}

.notice {
margin-top: 20px;
color: #6b7280;
font-size: 12px;
line-height: 1.5;
}

.version {
margin-top: 12px;
color: #9ca3af;
font-size: 11px;
text-align: right;
}

13.4 JavaScript設計​

JavaScriptは演出だけに使うのだ。入力値の送信、保存、外部通信はしないのだ。

assets/app.js は次のようにするのだ。

const form = document.getElementById("loginForm");

if (form) {
form.addEventListener("submit", function () {
const button = form.querySelector("button");

if (button) {
button.disabled = true;
button.textContent = "Signing in...";
}
});
}

13.5 JavaScriptでやらないこと​

  • fetch しない
  • XMLHttpRequest しない
  • localStorage に保存しない
  • sessionStorage に保存しない
  • Cookieを書かない
  • eval を使わない
  • 外部スクリプトを読み込まない
  • 入力されたID/PASSを加工しない
  • 入力されたID/PASSを別URLへ送らない

14. ログ設計​

14.1 アクセスログ​

ファイルは /var/log/apache2/honeypot_access.log なのだ。目的は、攻撃者のアクセス傾向を観測することなのだ。

主な分析項目は次のとおりなのだ。

  • IP
  • Host
  • Method
  • Path
  • Status
  • User-Agent
  • Referer
  • X-Forwarded-For
  • 処理時間

14.2 エラーログ​

ファイルは /var/log/apache2/honeypot_error.log なのだ。目的は、Apache側の異常、拒否、設定不備を観測することなのだ。

主な分析項目は次のとおりなのだ。

  • 存在しないファイルへのアクセス
  • 拒否されたアクセス
  • 設定エラー
  • 過大リクエスト
  • タイムアウト

14.3 保存処理を設けないデータとアクセスログの限界​

  • POST本文
  • フォームPOST本文のID入力値
  • フォームPOST本文のPassword入力値
  • Cookie値
  • Authorizationヘッダ全文

Authorizationヘッダをログに残す設計は避けるのだ。Basic認証の試行を見たい場合でも、ヘッダ全文を保存すると認証情報らしきものを保持することになるのだ。

本設計はフォームPOST本文の保存処理を実装しないのだ。一方、要求行・URL・Referer・User-Agent等には送信者が任意の値を入れられるため、アクセスログに入力値や認証情報が一切残らないとはいえないのだ。

15. 観測できる攻撃パターン​

15.1 WordPress探索​

例は次のとおりなのだ。

  • /wp-login.php
  • /wp-admin/
  • /xmlrpc.php

汎用BotによるCMS探索である可能性があるのだ。WordPressを使っていないサーバにも大量に来るため、インターネット上の一般的なスキャン傾向を把握しやすいアクセスなのだ。

15.2 設定ファイル探索​

例は次のとおりなのだ。

  • /.env
  • /.git/config
  • /config.php
  • /settings.py

設定ファイル、認証情報、ソースコード管理情報の露出を狙った探索なのだ。実環境でも同様のパスが露出していないか確認する材料になるのだ。

15.3 管理画面探索​

例は次のとおりなのだ。

  • /admin/
  • /administrator/
  • /manager/html
  • /phpmyadmin/

既知管理画面への総当たり探索なのだ。Tomcat Manager、phpMyAdmin、CMS管理画面などを広く探している可能性があるのだ。

15.4 リモートアクセス基盤探索​

例は次のとおりなのだ。

  • /vpn/
  • /remote/login
  • /owa/
  • /ecp/
  • /rdweb/

VPN、メール、リモートデスクトップ、リモートアクセス基盤を狙っている可能性があるのだ。この種のアクセスが増えている場合、実環境のVPN、IdP、メール基盤のログと比較する価値があるのだ。

15.5 API探索​

例は次のとおりなのだ。

  • /api/
  • /v1/
  • /swagger/
  • /openapi.json
  • /actuator/

API、管理エンドポイント、開発用エンドポイントの露出を狙っている可能性があるのだ。Spring Boot Actuator、Swagger UI、OpenAPI定義ファイルなどは特に観測対象になりやすいパスなのだ。

15.6 POST /login 連続試行​

ブルートフォース、クレデンシャルスタッフィング、ログインフォーム探索の可能性があるのだ。今回の設計ではフォームPOST本文をアプリケーションで保存しないため、試行内容ではなく、頻度、送信元、User-Agent、時間帯を見るのだ。

16. セキュリティ設計​

S-001 動的処理排除

PHP、CGI、Python、Node.jsなどを使わないのだ。これにより、アプリケーション実装バグによる侵害を避けるのだ。

S-002 POST本文非保存

フォームPOST本文のID/PASSをアプリケーションで保存しないのだ。認証情報らしき情報を保持すると、管理責任が増えるのだ。今回の目的は「認証情報収集」ではなく「攻撃入口の観測」なのだ。

S-003 認証成功なし

どのID/PASSでも成功させないのだ。成功後画面を作ると、その画面自体が新たな攻撃面になるのだ。

S-004 DocumentRoot書き込み禁止

Apache実行ユーザーにDocumentRootへの書き込み権限を与えないのだ。Webシェル配置、改ざん、ファイル生成を防ぐためなのだ。

S-005 外向き通信遮断

OSまたはクラウド側ファイアウォールで外向き通信を制限するのだ。万一侵害されても、第三者への攻撃、C2通信、踏み台化をしにくくするのだ。

S-006 管理ポート非公開

SSHをインターネットに公開しないのだ。やむを得ず公開する場合は、接続元IPを限定するのだ。ハニーポットよりもSSH自体が狙われる可能性が高いためなのだ。

S-007 情報露出抑制

ApacheバージョンやOS情報を出しにくくするのだ。不要な攻撃材料を与えないためなのだ。

S-008 ログ保護

ログファイルの権限を制限するのだ。攻撃観測情報の改ざんや削除を防ぐのだ。

S-009 容量制限

リクエストボディサイズ、ログローテーション、ディスク監視を設定するのだ。ログ肥大化による停止を防ぐのだ。

17. ネットワーク設計​

17.1 公開ポート​

  • 80/tcp
  • 443/tcp

17.2 非公開ポート​

  • 22/tcp
  • DBポート
  • 管理ポート
  • メトリクスポート
  • その他すべて

17.3 外向き通信​

原則拒否するのだ。例外候補は次の程度に留めるのだ。

  • OSアップデート用のリポジトリ
  • ログ転送先
  • 時刻同期

ただし、MVPでは外向き通信なしでもよいのだ。

17.4 推奨配置​

  • 専用VPS
  • 専用VM
  • 専用クラウドインスタンス
  • 内部ネットワークと接続しない
  • 本番環境と同居しない
  • 重要な認証情報を置かない

18. 運用設計​

18.1 初期構築時​

  1. 専用サーバを用意
  2. Apacheを最小構成で導入
  3. 不要モジュールを無効化
  4. 静的ファイルを配置
  5. Apache設定を適用
  6. 権限を読み取り中心に設定
  7. SSHを制限
  8. 外向き通信を制限
  9. logrotateを設定
  10. 動作確認

18.2 日次運用​

  • アクセスログ確認
  • エラーログ確認
  • ディスク容量確認
  • POST /login 件数確認
  • 404上位パス確認

18.3 週次運用​

  • 攻撃パス集計
  • 送信元IP集計
  • User-Agent集計
  • 新規探索パス確認
  • 403/404/405の傾向確認

18.4 月次運用​

  • 傾向レポート作成
  • 本番環境との関連確認
  • 不要な機能追加がないか確認
  • OSとApacheの更新状況確認
  • FW/WAF/SIEM側に反映すべき観点の整理

18.5 logrotate設計​

ログ肥大化による停止を防ぐため、日次ローテーションを設定するのだ。

/var/log/apache2/honeypot_access.log
/var/log/apache2/honeypot_error.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 root adm
sharedscripts
postrotate
/usr/sbin/apachectl graceful > /dev/null 2>&1 || true
endscript
}

19. 動作確認項目​

19.1 トップページ確認​

curl -i http://example.invalid/

期待結果は 200 OK なのだ。

19.2 POST /login 確認​

curl -i -X POST http://example.invalid/login -d 'user=test&password=test'

期待結果は次のとおりなのだ。

303 See Other
Location: /login-failed.html

19.3 ログイン失敗画面確認​

curl -i http://example.invalid/login-failed.html

期待結果は 200 OK なのだ。

19.4 存在しないパス確認​

curl -i http://example.invalid/wp-login.php

期待結果は 404 Not Found なのだ。

19.5 .env 拒否確認​

curl -i http://example.invalid/.env

期待結果は 403 Forbidden なのだ。

19.6 .git 拒否確認​

curl -i http://example.invalid/.git/config

期待結果は 403 Forbidden なのだ。

19.7 TRACE拒否確認​

curl -i -X TRACE http://example.invalid/

期待結果は 405 Method Not Allowed または拒否なのだ。

19.8 ディレクトリ一覧拒否確認​

curl -i http://example.invalid/assets/

期待結果は 403 Forbidden または 404 Not Found なのだ。

19.9 アクセスログ確認​

tail -f /var/log/apache2/honeypot_access.log

期待結果は、GET、POST、404、403が記録されることなのだ。

19.10 POST本文非保存確認​

確認内容は、honeypot_access.log に user=test や password=test が出ていないことなのだ。期待結果は、POST本文が保存されないことなのだ。

20. 受入基準​

20.1 安全性​

  • PHPが無効である
  • CGIが無効である
  • Proxyが不要なら無効である
  • DocumentRootへApache実行ユーザーが書き込めない
  • SSHが公開されていない、またはIP制限されている
  • 外向き通信が制限されている

20.2 画面​

  • ログイン画面が表示される
  • ID/PASS欄がある
  • POSTできる
  • ログイン成功しない
  • 失敗画面が表示される
  • 外部CDNを使っていない

20.3 ログ​

  • POST /login がアクセスログに残る
  • 404探索パスがアクセスログに残る
  • User-Agentが残る
  • Hostヘッダが残る
  • X-Forwarded-Forが残る
  • POST本文は残らない

20.4 運用​

  • logrotateが設定されている
  • ディスク容量を確認できる
  • Apache再起動後も設定が有効
  • エラー画面が表示される

21. 将来拡張​

21.1 Phase 1:MVP​

  • Apache静的ハニーポット
  • POST本文なし
  • アクセスログ分析

まずはここまででよいのだ。最初から高対話型にしないのだ。

21.2 Phase 2:ログ分析強化​

  • ログを別環境へ転送
  • 簡易ダッシュボード化
  • IP、AS番号、国別集計
  • 本番環境ログとの突合

本体に分析機能を持たせず、別環境で分析するのが望ましいのだ。

21.3 Phase 3:検知専用mod_security​

  • mod_securityを検知専用で導入
  • ルールヒット情報を取得
  • ブロック目的ではなく観測目的

ただし、設定ミスや運用負荷が増えるため、MVPの後で検討するのだ。

21.4 Phase 4:高対話型ハニーポット​

  • 別環境で高対話型ハニーポットを検討
  • SSH、疑似ファイルシステム、疑似サービス等
  • 今回のApache単体構成とは分離する

高対話型にする場合は、今回の構成とは別物として扱うべきなのだ。

22. 結論​

今回の簡易ハニーポットは、攻撃者を中に入れる罠ではなく、攻撃の入口を観測するための装置なのだ。

設計の中心は次の考え方になるのだ。

Apache単体
+
静的ログイン画面
+
ID/PASS入力欄
+
POST /login
+
303で失敗画面
+
POST本文非保存
+
404探索ログ分析
+
サーバ分離
+
外向き通信制限

得られる情報は、入力された認証情報そのものではないのだ。得るべき情報は次のようなメタデータなのだ。

  • 誰が来たか
  • どのパスを探ったか
  • どのUser-Agentか
  • どのHostヘッダか
  • どのHTTPメソッドか
  • POST /login を試したか
  • どの頻度で来たか
  • どのような404探索をしたか

逆に、取得しない情報も明確にするのだ。

  • 入力されたID
  • 入力されたパスワード
  • POST本文
  • 認証成功後操作
  • 攻撃者のファイル
  • マルウェア
  • コマンド履歴

ハニーポットは、情報を取りに行きすぎるほど危険になるのだ。今回のように「侵害され、踏み台にされないこと」を最優先にするなら、収集能力を増やしすぎないことが重要なのだ。

安全なハニーポットとは、攻撃者を深く誘い込むものではなく、攻撃者に余計な機能を与えず、入口の痕跡を静かに観測するものなのだ。

付録A:最小ファイル一覧​

/var/www/honeypot/
index.html
login-failed.html
assets/
style.css
app.js
error/
403.html
404.html
405.html
500.html
/etc/apache2/sites-available/
honeypot.conf
/etc/logrotate.d/
honeypot-apache

付録B:MVPチェックリスト​

  • Apacheのみで動いている
  • PHPを使っていない
  • CGIを使っていない
  • DBを使っていない
  • 外部CDNを使っていない
  • ログイン画面が表示される
  • ID/PASS入力欄がある
  • POST /login ができる
  • 認証成功しない
  • 303で失敗画面へ遷移する
  • POST本文がログに残らない
  • 404探索パスがログに残る
  • User-Agentがログに残る
  • Hostヘッダがログに残る
  • DocumentRootがroot所有である
  • Apache実行ユーザーがDocumentRootに書き込めない
  • .env が403になる
  • .git/config が403になる
  • ディレクトリ一覧が無効である
  • TRACEが無効である
  • logrotateが設定されている
  • SSHが制限されている
  • 外向き通信が制限されている
  • 本番環境と分離されている

付録C:この設計で十分なケース・不十分なケース​

十分なケースは次のとおりなのだ。

  • インターネット上のスキャン傾向を知りたい
  • どのようなパスが狙われるか見たい
  • POST /login の試行有無を見たい
  • User-AgentやIPの傾向を見たい
  • 踏み台化リスクを極小化したい
  • 低コストで始めたい
  • Apacheだけで完結させたい

不十分なケースは次のとおりなのだ。

  • 攻撃者の侵入後操作を観測したい
  • 入力されたID/PASSの傾向を分析したい
  • マルウェアの配置挙動を見たい
  • C2通信を見たい
  • 攻撃者のシェル操作を見たい
  • 高対話型ハニーポットを作りたい

この場合は、別環境で高対話型ハニーポットを検討するのだ。ただし、その場合でも本番環境とは完全に切り離すべきなのだ。

保存範囲を確認するための受入試験​

このページは設計例であり、掲載設定を使った実ログの受入試験は未実施なのだ。隔離した検証環境で、実際の認証情報の代わりに別々のダミー文字列をPOST本文、URLパス、クエリ、Referer、User-Agentへ入れ、アクセスログ・エラーログ・転送先を確認するのだ。保存された場所と削除結果を記録し、非保存を保証できる範囲だけを運用方針に書くのだ。

Apacheの基本ディレクティブ:https://httpd.apache.org/docs/2.4/mod/core.html