
自己完結型のSSHハニーポットで、攻撃者の操作を捕捉し、構造化されたセキュリティインテリジェンスに変換します。
SSHintel は、Python と Paramiko を用いて構築された軽量な SSH ハニーポットです。偽の Linux シェルをシミュレートし、不正なアクセス試行を記録し、認証情報を捕捉し、制御された環境で攻撃者の挙動を分析します。
ls、cd、pwd、cat、echo、grep、find、tree、head、tail、wc、stat、ps、df、free、env、id、whoami など)--tarpit モードSSHintel は完全な Bash/Linux シェルではありません。攻撃者のテレメトリを収集するために、一般的なコマンドの説得力のあるサブセットをシミュレートします。コマンドは軽量なレジストリによってディスパッチされ、コマンドの追加とは小さなハンドラ関数を追加することを意味します。
pip install -r requirements.txt
注記: SSH ホスト鍵は初回実行時に自動生成されます。手動での鍵生成は不要です。
特定のポート、ユーザー名、パスワードを指定してハニーポットを実行します:
python3 run.py serve --port 2222 --username user1 --password pass123
デフォルトのポートは
2222、ホストは0.0.0.0です。
ハニーポットは初回実行時に、SSH ホストキーが存在しない場合、static/server.key に自動生成します。手動でのキー生成は不要です。
tarpit モードを有効にするには:
python3 run.py serve --port 2222 --username user1 --password pass123 --tarpit
SQLite テレメトリを無効化するには(JSONL のみ):
python3 run.py serve --port 2222 --username user1 --password pass123 --no-db
センサー設定は CLI > 環境 > 設定ファイル > デフォルト の順で使用されます。
明示的に指定された CLI フラグのみが他のソースを上書きします。これは
serve に適用されます。ダッシュボード/クエリコマンドは独自の CLI 設定を保持します。
Python 3.11 以降の場合:
cp sshintel.toml.example sshintel.toml
chmod 600 sshintel.toml
python3 run.py serve
Python 3.8/3.10 では、依存関係のない JSON 版を使用してください:
cp sshintel.json.example sshintel.json
chmod 600 sshintel.json
python3 run.py serve
デプロイ前にコピーしたファイルを編集してください。TOML には Python 3.11 以上が必要です。それより古いバージョンでは、JSON を使用するよう明確な指示とともに失敗します。明示的なファイルが指定されない場合、SSHintel はカレントディレクトリ内で sshintel.toml、次に sshintel.json を探します。別のファイルを選択するには serve --config /path/to/settings.json または HONEYPOT_CONFIG を使用します(--config が優先されます)。明示的に指定されたファイルが存在しない場合、ファイルが不正な場合、未知のキー、無効な値は、サーバーやデータベースが起動する前に失敗します。設定内のファイルパスは、設定ファイルではなくプロセスの作業ディレクトリからの相対パスです。
| ファイルキー | 環境変数 | デフォルト |
|---|---|---|
host | HONEYPOT_HOST | 0.0.0.0 |
port | HONEYPOT_PORT(レガシーエイリアス: PORT) | 2222 |
username | HONEYPOT_USERNAME | user1 |
password | HONEYPOT_PASSWORD | pass123 |
tarpit | HONEYPOT_TARPIT | false |
tarpit_max_seconds | HONEYPOT_TARPIT_MAX_SECONDS | 120 |
max_connections | HONEYPOT_MAX_CONNECTIONS | 50 |
auth_timeout | HONEYPOT_AUTH_TIMEOUT | 60 |
session_idle_timeout | HONEYPOT_SESSION_IDLE_TIMEOUT | 300 |
sensor_id | HONEYPOT_SENSOR_ID | 未設定 |
db_path | HONEYPOT_DB_PATH | data/sshintel.db |
no_db | HONEYPOT_NO_DB | false |
fetch_payloads | HONEYPOT_FETCH_PAYLOADS | false(予約済み) |
環境変数の真偽値は true/false、1/0、yes/no、on/off を受け付けます。HONEYPOT_PORT は PORT より優先されます。ポートは 1~65535 である必要があり、制限値とタイムアウトは正の整数である必要があります。優先度の低い true 設定を上書きするには、--no-tarpit、--db-enabled、または --no-fetch-payloads を使用します。データベースパスは既存の --db CLI フラグを使用します。ペイロード取得は実装されていません。fetch_payloads を有効にすると、黙って無視されるのではなく拒否されます。
ローカルの sshintel.toml/sshintel.json ファイルは、認証情報を含む可能性があるため、Git で無視され、Docker ビルドから除外されます。代わりに設定ファイルを読み取り専用でコンテナにマウントしてください。Docker は環境変数を直接消費し(シェルによる認証情報の補間なし)、既存の ENV デフォルトがマウントされたファイルより優先されます。必要に応じてこれらの変数を上書きするか、明示的な CLI フラグを使用してください。
SSHintel は、多数の同時接続や無期限に維持される接続によるリソース枯渇から保護します。これらは CLI で設定可能です:
| フラグ | デフォルト | 目的 |
|---|---|---|
--max-connections | 50 | 同時アクティブ接続の最大数。超過した接続は拒否され、connection_rejected イベントとしてログに記録されます |
--auth-timeout | 60(秒) | SSH ハンドシェイク/認証を完了するために許される時間。停止したクライアントは切断されます |
--session-idle-timeout | 300(秒) | 認証済みシェルの非アクティブタイムアウト。アイドル状態のセッションは終了しますが、活発に入力している攻撃者が強制終了されることはありません |
例:
python3 run.py serve --port 2222 --username user1 --password pass123 \
--max-connections 25 --auth-timeout 30 --session-idle-timeout 300
接続が多すぎる状態で開かれると、余分な接続は即座に閉じられ、connection_rejected セキュリティイベント(reason: connection_limit)が JSONL ログに書き込まれます。停止した認証は reason: auth_timeout の切断として記録され、アイドル状態のシェルは reason: idle_timeout で終了します。
Tarpit モードは攻撃者を引き留めるために意図的に出力を遅く送信するため、tarpit のバナーループは非アクティブタイムアウトの対象外です — ただし、tarpit セッションは接続制限にカウントされます。
SSHintel には、SQLite に保存されたセキュリティテレメトリを可視化するローカル Web ダッシュボードが含まれています。
python3 run.py dashboard
次に、ブラウザで http://localhost:5000 を開きます。
ダッシュボードはデフォルトで
data/sshintel.dbにある SQLite データベースから読み取ります。テレメトリが取得されるようにまずハニーポットを起動し、その後ダッシュボードを起動してデータが蓄積される様子を確認してください。
セッション ID をクリックする(または /session/<session_id> に移動する)と、セッション調査ビューが開き、単一の攻撃が時系列で再構築されます:
$ command 形式で表示# Terminal 1: start the honeypot
python3 run.py serve --port 2222 --username user1 --password pass123
# Terminal 2: start the dashboard
python3 run.py dashboard
# Terminal 3: simulate an attacker
ssh user1@localhost -p 2222
# (run some commands, then exit)
次に、http://localhost:5000 を開いてキャプチャされたアクティビティを確認します。
ダッシュボードはライブテレメトリをサポートしています — 2秒ごとにハニーポットをポーリングし、自動的に更新されます。新しいセッション、コマンド、イベントはページを更新することなくリアルタイムで表示されます。ライブインジケーター(● Live)が接続状態を示します。
2つ目のターミナルを開いて、接続を試みます:
ssh user1@localhost -p 2222
認証情報が一致すれば、エミュレートされたシェルにドロップされます。
古い SSH フィンガープリントを削除するには:
notepad "%USERPROFILE%\.ssh\known_hosts"
localhostまたはハニーポットの IP を含む該当行を削除します。
creds_logger に記録されますfunnel_logger を介して記録されますlog_files/events.jsonl に書き込まれます — 1 行につき 1 つの有効な JSON オブジェクトです各 JSONL イベントには、UTC ISO-8601 形式の timestamp、event_type、一意の session_id、および source_ip が含まれます。接続、認証の試行/結果、コマンド実行、ターピットの起動、切断はすべて構造化イベントとして記録されます。
受信する各 SSH 接続は、独自の session_id を持つ独立した セッション として追跡されます。セッションは送信元 IP、接続/切断時刻、認証結果、接続時間を記録し、その接続内で生成されるすべてのイベントは同じ session_id を持ちます(これにより、認証の試行、コマンド、切断を単一の接続に紐付けられます)。セッションは接続ごとに分離されており、同時接続するクライアント間で状態は共有されません。
また、各セッションには 独自の分離されたインメモリの偽ファイルシステム が割り当てられます — シミュレートされたファイルシステムは接続ごとに新規に作成され、接続が終了するとクリーンアップされます。ある攻撃者が作成または変更したファイル、ディレクトリ、作業ディレクトリは、同時に接続している別の攻撃者からは決して見えません。ファイルシステム全体は Python のメモリ内でシミュレートされ、実際のホストのファイルシステムには一切触れません。
現在の event_type の値: connect、auth_attempt、auth_success、auth_failure、command、disconnect、connection_rejected、tarpit。