
小規模なHTTPサービス向けのユーザー空間ボットおよびDDoS防御
DDoSやボットによる悪用を無駄な労力に変える、ユーザー空間のデセプション層。
Net WardはHTTPサービスの前面にリバースプロキシとして配置されます。正規のトラフィックはそのまま通過します。既知のプローブやフラッドには無害なミラー応答を返し、ボットの労力を消費させつつ、リクエストがアプリに到達することはありません — カーネルフックなし、ペイロードなし、報復なし、設計上フェイルオープンです。
Dragon Ladyによる開発・保守 — github.com/Dragon-Lady · X: @answerislove2 実環境で発生するサプライチェーン攻撃やボット悪用キャンペーンを追跡する独立系セキュリティ研究者。
ウェブサイト: dragon-lady.github.io/netward-standalone
python -m pip install --upgrade "netward>=0.4.12"
python -m netward --config example_config.json
バージョン0.4.12以降が、新規インストールおよびアップグレードにおける推奨ベースラインです。古いリリースも再現性のために引き続き利用可能ですが、新規デプロイでは現行リリースを使用してください。
またはソースから:
git clone https://github.com/Dragon-Lady/netward-standalone
cd netward-standalone
pip install -e .
Net Ward は listen_address で待ち受け、クリーンなトラフィックを upstream_target に転送します。
サンプル設定をコピーし、上流ターゲットを編集します:
cp example_config.json config.json
Net Ward を起動する前に、upstream_target を実際の HTTP サービスに向けてください。アップストリームに到達できない場合、一致しないリクエストは生のプロキシエラーを公開する代わりに、デフォルトのミラー応答を返します。
必須フィールド:
| フィールド | 意味 |
|---|---|
node_id | この Net Ward インスタンスの安定した名前 |
upstream_target | 保護対象の HTTP サービス |
listen_address | Net Ward がバインドするホストとポート |
オプションのフィールドは、ミラーの強度、ローカルストレージ、メッシュのプレースホルダー、アラートチャネル、アップストリームのタイムアウト、プローブログの保持を制御します。パターン一致またはリクエストフラッドの開始時に、アラートが SQLite に記録されます。アラートは種類、送信元、パターンごとに 5 分間重複排除されます。alert_channels リストが空の場合は stdout に送信されます。明示的な配信には stdout、email、slack、ntfy の任意の組み合わせを選択してください。送信配信はバックグラウンドで実行され、失敗したチャネルを再試行します。未配信の最近のアラートは起動時に再試行されます。
メールには alert_email、alert_smtp_host、alert_smtp_from が必要です。alert_smtp_port と alert_smtp_security(starttls、ssl、または none)を設定してください。none はループバック SMTP サーバーに対してのみ許可されます。認証が必要な場合は、alert_smtp_username と、パスワードを含む環境変数の名前を指定する alert_smtp_password_env を設定してください。Slack には alert_slack_webhook が必要です。ntfy には alert_ntfy_topic(ntfy.sh 上のトピック、またはセルフホストの完全なトピック URL)が必要です。保護されたトピックの場合は、そのベアラートークンを含む環境変数の名前を alert_ntfy_token_env に設定してください。HTTP の宛先は、ループバック以外では HTTPS を使用する必要があります。alert_timeout_secs のデフォルトは 5 秒です。Net Ward は起動時に要求された宛先を確認し、成功した配信の受領記録をアラートテーブルに保存します。アラートメッセージには送信元 IP、パターン ID、分類が含まれます。生のリクエストボディやヘッダーは含まれません。
| オプションフィールド | デフォルト | 意味 |
|---|---|---|
upstream_timeout_total | 10 | アップストリーム呼び出しのリクエスト全体の予算(秒) |
upstream_timeout_connect | 3 | 接続(DNS + TCP + TLS)タイムアウト(秒) |
upstream_timeout_sock_read | 5 | アップストリームのソケット読み取り間のアイドル時間(秒) |
upstream_max_concurrency | 64 | 処理中のアップストリームリクエスト数 |
upstream_max_body_bytes | 8388608 | バッファリングされるアップストリーム応答ボディの最大サイズ(8 MiB)。これより大きいボディはデフォルトのミラーへフェイルオープンします |
probe_retention_secs | 604800 | プローブログの TTL(7 日間) |
probe_max_rows | 10000 | 書き込み時パージ後のプローブログの最大行数 |
alert_timeout_secs | 5 | 送信アラート配信のチャネルごとのタイムアウト(秒) |
python -m netward --config config.json
トポロジーの例:
| コンポーネント | アドレス |
|---|---|
| Net Ward | 127.0.0.1:8080 |
| アップストリームアプリ | http://127.0.0.1:9000 |
| ストレージ | netward.db |
ロードバランサーまたはWebサーバーをNet Wardに向けてください。可能な限り、アップストリームアプリはホストまたは信頼されたネットワークからのみ到達可能にしてください。
Net Wardをlocalhost以外から到達可能にしたい場合にのみ、listen_addressを0.0.0.0:<port>に設定してください。
Linux/macOSでは、storage_pathを誰でも書き込み可能な状態にしないでください。例: chmod 600 netward.db、または監視のために意図的に読み取りアクセスが必要な場合にのみchmod 644 netward.db。
Net Wardは文書化されたボックスあたりの容量を継続的に維持しますが、Pythonランタイムのメモリプールは、持続的な高負荷の後にワーキングセットの状態を保持する場合があります。継続的な高トラフィック下でNet Wardを運用するオペレーターは、プロセスのリソース使用状況を監視し、定期的にデーモンを再起動してください。例えば週次、またはRSSがベースラインの2倍を超えたときなどです。v0.5では、自動テレメトリではなく、オペレーターのフィードバックとローカルテストの観測に基づいてこのガイダンスを改善する予定です。
クリーンなリクエストはアップストリームに到達するはずです:
curl -i http://127.0.0.1:8080/
既知のプローブはミラーリングする必要があります:
curl -i http://127.0.0.1:8080/wp-admin/
WordPress プローブは偽のログインページを返します。上流サービスはそのリクエストを受信しません。
上記の例のトポロジーでは、正常な初回実行は次のようになります:
127.0.0.1:9000 で小さな上流サービスを起動します。127.0.0.1:8080 で Net Ward を起動します。/ をリクエストし、上流のレスポンスが返ってくることを確認します。/wp-admin/ をリクエストし、代わりにミラーレスポンスが返ってくることを確認します。期待される結果:通常のトラフィックは上流アプリに到達し、既知のプローブは Net Ward のミラーレイヤーによって処理されます。これは、プロキシパス、パターンマッチ、およびミラーレスポンスがすべて機能していることを示す最もシンプルなシグナルです。
バンドルされたベンダーパターンセットをインストールまたは更新します:
python -m netward.cli --db netward.db install-patterns
python -m netward.cli --db netward.db install-patterns --force
アクティブなパターンを一覧表示します:
python -m netward.cli --db netward.db list-patterns
データベースに書き込まずにプローブレポートを読み取ります。レポートは集計カウントです。どのプローブファミリーが発火したか、それらのファミリーがヒットしたリクエストパスの合計、および関与したソースの数が含まれます。生のIPアドレスや地理情報は出力されません。--send は同じダイジェストを配信します — パスカウントを含み、生のIPは決して含みません。出力ファイルは所有者のみアクセス可能(0600)です。
python -m netward.cli --db netward.db report
python -m netward.cli --db netward.db report --since 7d --format md --output report.md
python -m netward.cli --db netward.db report --format html --output report.html
python -m netward.cli --db netward.db report --family wordpress --top 10
python -m netward.cli --db netward.db report --send --config config.json
保存されるプローブログは7日間または10,000行に制限されます。レポートはその期間を記述し、その旨を明示します。より厳格なパターンの候補はレビュー用に表示され、インストールはされません。
パターンを無効化または再有効化する:
python -m netward.cli --db netward.db disable-pattern wordpress_admin_probe
python -m netward.cli --db netward.db enable-pattern wordpress_admin_probe
上流のサービスが /admin で実際の管理パネルを公開している場合は、Net Ward をそのサービスの前に配置する前に、generic_admin_login_probe を無効化するか、より厳密なオペレーターパターンに置き換えてください:
python -m netward.cli --db netward.db disable-pattern generic_admin_login_probe
一部のベンダーパターンは同梱されていますが、デフォルトでは無効になっています。これは、上流がパターンの対象とするプロトコル機能を同じように使用している場合、正当なトラフィックを壊す可能性があるためです。
basic_auth_probeAuthorization: Basic <base64> を介したブルートフォースによるクレデンシャルスタッフィングを捕捉します。
有効化しても安全なのは次の場合のみです: 上流が HTTP Basic 認証をまったく使用していない場合。上流が実際のユーザーからの Basic 認証クレデンシャルを受け付ける場合、このパターンを有効にするとそれらのユーザーが無限の 401 ループに陥ります — Net Ward は偽のチャレンジを返し、ブラウザは再プロンプトを出し、このサイクルが繰り返されます。
有効化:
netward-cli --db netward.db enable-pattern basic_auth_probe
再度無効化します:
netward-cli --db netward.db disable-pattern basic_auth_probe
有効化後に動作していることを確認するには:
curl -i -H "Authorization: Basic dXNlcjpwYXNz" http://127.0.0.1:8080/api/admin
401 と WWW-Authenticate: Basic realm="Restricted" を返す必要があります。アップストリームはリクエストを受信してはなりません。
Net Ward はフェイルオープンかつユーザー空間のみで動作します:
ミラー層は自動化された悪用をそらすためのものであり、攻撃し返すためのものではありません。
ログイン値は収集対象の製品ではありません。機密ヘッダー(Authorization、Cookie、Set-Cookie、Proxy-Authorization など)およびパスワードらしきボディやクエリのキーは、プローブがローカルデータベースに書き込まれる前に秘匿化されます。残余リスクは残ります:その他のヘッダー、非構造化ボディ、およびそれらのキー名を使用しない値は、オペレーターの管理下でローカルに保存される可能性があります。プローブログを認証情報の保管庫として扱わないでください。また、公開レポートに実際のシークレットを含めないでください。
Net Ward はプロジェクトのメンテナにテレメトリを送信せず、オペレーターのトラフィックをいかなる外部目的にも使用しません。