koide e1686d7acb
All checks were successful
Deploy Docusaurus Site / deploy (push) Successful in 37s
Add: 自宅ネットワークにIDSを導入した話
2026-02-28 07:49:37 +00:00

12 KiB
Raw Blame History

sidebar_position, title, description, hide_table_of_contents, displayed_sidebar, image
sidebar_position title description hide_table_of_contents displayed_sidebar image
2 自宅ネットワークにIDSを導入した話 — Proxmox LXC で Suricata + ntopng Proxmox VE の LXC コンテナで Suricata と ntopng を使った自宅ネットワーク監視環境を構築した記録。TEEミラーリング、カスタムルール、Zabbix連携まで。 false null ./banner.png

自宅ネットワークにIDSを導入した話

きっかけ

自宅サーバーを運用してると、外向きのサービスも増えてくるし、IoTデバイスも増える。リバースプロキシの裏で何が起きてるか、正直あんまり把握できてなかった。

最近 OpenClawAIアシスタント基盤を自宅で動かし始めて、外部APIとの通信も増えてきた。「そろそろネットワークの中身ちゃんと見ないとまずいかも」と思って、とりあえずやってみることにした。

構成

うちの環境は Proxmox VE でクラスタを組んでて、サービスは基本 LXC コンテナで動かしてる。専用のミラーリングスイッチとかは持ってないから、Proxmox の機能でなんとかする方針。

最終的な構成図

インターネット
  │
  ├─ Nginx Proxy Manager (LXC, 192.168.1.189)
  │    │
  │    ├─ 各種サービス (Gitea, Docusaurus, etc.)
  │    │
  │    └─ [TEE mirror] ──→ Suricata + ntopng (LXC, 192.168.1.187)
  │                              │
  │                              ├─ eth0: サービスネットワーク (192.168.1.0/24)
  │                              └─ eth10: データプレーン (192.168.10.0/24)
  │
  ├─ Proxmox VE ノード x4
  │    └─ [TEE mirror] ──→ (同上)
  │
  └─ Zabbix (LXC, 192.168.1.172)
       └─ Suricata アラート監視

使ったもの

コンポーネント 役割
Suricata 6.0.4 IDS侵入検知
ntopng Community トラフィック可視化・フロー分析
Zabbix 7.4 アラート集約・通知
Proxmox TEE パケットミラーリング

LXC コンテナの作成

Proxmox の Web UI から Ubuntu 22.04 の LXC を作成。ポイントはいくつかある。

スペック

  • CPU: 2コア
  • メモリ: 4GBSuricata のルール読み込みで結構食う)
  • ディスク: 20GB
  • NIC: 2つサービス用 + データプレーン用)

特権コンテナにすること(重要)

最初は非特権コンテナで作ったんだけど、Suricata の af-packetパケットキャプチャが動かない。ルールの読み込みまでは成功するのに、キャプチャスレッドが起動しない。

ログにはこう出る:

48714 rules successfully loaded, 0 rules failed
48719 signatures processed.

でも All AFP capture threads are running. が出ない。eve.json も更新されない。

原因は af-packet のプロミスキャスモードに必要な権限が非特権コンテナだと制限されるから。

# /etc/pve/lxc/<CTID>.conf
# unprivileged: 1  ← これを削除

特権コンテナにしたら一発で動いた。

NIC 設定

net0: name=eth0,bridge=vmbr0,ip=dhcp,type=veth
net1: name=eth10,bridge=vmbr1,ip=192.168.10.187/24,type=veth
  • eth0: 管理・サービス用192.168.1.0/24
  • eth10: TEE ミラートラフィック受信用192.168.10.0/24

ゲートウェイの設定を忘れずに。 DHCPじゃない場合、gw=192.168.1.1 を net0 に追加しないと外部に出られない(パッケージインストールで詰む)。

Suricata のインストールと設定

sudo apt update
sudo apt install -y suricata suricata-update
sudo suricata-update

suricata.yaml の設定ポイント

HOME_NET

HOME_NET: "[192.168.1.0/24]"

HTTP_PORTS を拡張する

デフォルトだと HTTP_PORTS: "80" だけ。自宅サーバーは 8006Proxmox、3000ntopng/Grafana、8080Zabbixとか色んなポートで HTTP 使ってるから、これを広げないと HTTP の中身をパースしてくれない。

HTTP_PORTS: "[80,443,3000,3128,8006,8007,8080,8443,9876]"

これに気づくまでかなりハマった。カスタムルールが全然発火しなくて、ログを見たら HTTP イベント自体が記録されてなかった。

ルールファイル

rule-files:
  - suricata.rules
  - local.rules

suricata-update で取得したルールは /var/lib/suricata/rules/suricata.rules に保存される。/etc/suricata/rules/ にシンボリックリンクを作っておくと楽。

sudo ln -s /var/lib/suricata/rules/suricata.rules /etc/suricata/rules/suricata.rules

カスタムルールの作成

ET Open のルールセットだけだと、よくある Web 探索行為(.env を探すボットとか)は検知できない。自分で書く。

# === 探索行為の検知 ===
alert http any any -> $HOME_NET any (msg:"Scan: wp-admin access"; content:"/wp-admin"; http_uri; sid:2000001; rev:1;)
alert http any any -> $HOME_NET any (msg:"Scan: .env access"; content:"/.env"; http_uri; sid:2000002; rev:1;)
alert http any any -> $HOME_NET any (msg:"Scan: phpmyadmin access"; content:"/phpmyadmin"; nocase; http_uri; sid:2000003; rev:1;)
alert http any any -> $HOME_NET any (msg:"Scan: xmlrpc access"; content:"/xmlrpc.php"; http_uri; sid:2000004; rev:1;)
alert http any any -> $HOME_NET any (msg:"Scan: .git directory access"; content:"/.git/"; http_uri; sid:2000005; rev:1;)
alert http any any -> $HOME_NET any (msg:"Scan: admin panel probe"; content:"/admin"; http_uri; sid:2000009; rev:1;)

# === SQLインジェクション試行 ===
alert http any any -> $HOME_NET any (msg:"SQLi: UNION SELECT attempt"; content:"UNION"; nocase; http_uri; content:"SELECT"; nocase; http_uri; sid:2000011; rev:1;)

# === ディレクトリトラバーサル ===
alert http any any -> $HOME_NET any (msg:"Traversal: ../ attempt"; content:"../"; http_uri; sid:2000013; rev:1;)

# === ブルートフォース ===
alert http any any -> $HOME_NET any (msg:"Brute: login page flood"; content:"/login"; http_uri; threshold:type both, track by_src, count 20, seconds 60; sid:2000014; rev:1;)

テストは curl で簡単にできる:

curl -s http://192.168.1.187:3000/.env
# → eve.json に "Scan: .env access" のアラートが記録される

TEE によるパケットミラーリング

専用のミラーリングスイッチがなくても、Proxmox ホスト上で iptables の TEE ターゲットを使えばパケットをコピーできる。

# サービスネットワーク経由のトラフィックをデータプレーンにミラー
iptables -t mangle -A PREROUTING -i vmbr0 -j TEE --gateway 192.168.10.187
iptables -t mangle -A POSTROUTING -o vmbr0 -j TEE --gateway 192.168.10.187

データプレーンvmbr1, 192.168.10.0/24を別に用意してるのは、ミラートラフィックでサービス帯域を圧迫しないため。

ntopng でトラフィック可視化

ntopng は Web UI でリアルタイムのトラフィック状況が見れる。Community 版でも十分使える。

sudo apt install -y ntopng

設定ファイル:

-i=eth0
-w=3000
-m=192.168.1.0/24

API でホストラベルを設定

ntopng の REST API でホストにわかりやすい名前をつけられる:

curl -X POST -H "Authorization: Token <API_TOKEN>" \
  "http://localhost:3000/lua/rest/v2/set/host/alias.lua" \
  -d "host=192.168.1.7&custom_name=db975i"

アラートフローの確認

curl -H "Authorization: Token <API_TOKEN>" \
  "http://localhost:3000/lua/rest/v2/get/flow/active.lua?ifid=2&alert_type=1"

:::warning ntopng の Suricata 連携は Enterprise 版のみ Community 版では ntopng 上で Suricata のアラートを直接表示できない。Zabbix 等の別ツールで集約する必要がある。 :::

Zabbix 連携

Suricata のアラートを Zabbix で監視・通知する。

Zabbix Agent2 のインストール

wget -O /tmp/zabbix-release.deb \
  https://repo.zabbix.com/zabbix/7.4/release/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.4+ubuntu22.04_all.deb
sudo dpkg -i /tmp/zabbix-release.deb
sudo apt update && sudo apt install -y zabbix-agent2

eve.json パーススクリプト

Zabbix の log[] アイテムだと JSON のフィルタが難しいので、UserParameter + スクリプトで対応。

#!/bin/bash
MODE=${1:-count}
SECONDS_AGO=${2:-60}
CUTOFF=$(date -u -d "-${SECONDS_AGO} seconds" +%Y-%m-%dT%H:%M:%S)

case $MODE in
  count)
    grep '"event_type":"alert"' /var/log/suricata/eve.json | \
      awk -F'"timestamp":"' '{print $2}' | cut -d'"' -f1 | \
      awk -v c="$CUTOFF" '$0 >= c' | wc -l ;;
  custom_count)
    grep 'signature_id.*200000' /var/log/suricata/eve.json | \
      awk -F'"timestamp":"' '{print $2}' | cut -d'"' -f1 | \
      awk -v c="$CUTOFF" '$0 >= c' | wc -l ;;
  last)
    grep '"event_type":"alert"' /var/log/suricata/eve.json | tail -1 ;;
esac

監視アイテムとトリガー

アイテム 種別 間隔
全アラート数 (60s) 数値 30秒
カスタムルール数 (60s) 数値 30秒
個別アラートログ ログ 10秒

トリガーはカスタムルール検知で「警告」、大量アラート100件/分超)で「重大」に設定。

やってみてわかったこと

ハマりポイント

  1. 非特権 LXC だと af-packet が動かない — 特権コンテナ必須
  2. HTTP_PORTS がデフォルト 80 のみ — 自宅サーバーのポートを追加しないと HTTP パースされない
  3. LXC のゲートウェイ設定漏れ — パッケージインストール時に外に出られなくて詰む
  4. suricata.rules のパスsuricata-update/var/lib/ に保存するが、設定は /etc/suricata/rules/ を見る

実際に検知されたもの

初回スキャンで検知されたのは:

  • Corosync (UDP:5405) のクラスタ通信
  • Proxmox UI (8006/8007) のアクセス
  • MDNS、SMB、SSH のプロトコル異常
  • Tuya IoT デバイスの通信

セキュリティ上の脅威はゼロだった。 自宅ネットワークなので当たり前といえば当たり前だけど、「異常がない」ことを確認できるのが大事。

Postfix がデフォルトで開いてる問題

Proxmox VE ノードの脆弱性スキャンをしたら、全ノードで SMTP (25/tcp) が外部から到達可能だった。Proxmox はデフォルトで Postfix を入れてる(通知メール用)けど、ローカルのみにリッスンを制限すべき:

sudo postconf -e 'inet_interfaces = loopback-only'
sudo systemctl restart postfix

まとめ

専用機材なしでも、Proxmox の LXC + TEE ミラーリングで実用的な IDS 環境が作れた。月額コストもゼロ。

「何が起きてるかわからない」状態から「異常があれば検知して通知される」状態になっただけで、だいぶ安心感が違う。自宅サーバー勢にはおすすめ。

参考リンク


この記事は2026年2月時点の情報です。