SSem SecuMon 無料ガイド
個人サーバー1台から · 2026年10月時点
準備中インストールファイルの配布は準備中です。
このガイドでは、必要なものとインストール手順、そして運用で知っておくべきことを先に公開します。配布が始まったら、ダウンロード先をここに記載します。
1. 必要なもの
| 項目 | 条件 |
|---|---|
| 保護するサーバー | Linux(systemd)+ fail2ban · nftables · sqlite3。amd64 または arm64。Ubuntu 22.04 · CentOS 8 で動作を確認しています。 |
| コンソールサーバー | 1台。JDK 21 · Tomcat 11 · PostgreSQL 17。Docker で起動すると簡単です。 |
| ネットワーク | 各サーバーからコンソールのアドレスへ HTTPS で接続できる必要があります。サーバーへの受信ポートは不要です。コンソールは VPN または内部ネットワークの内側に置くことをおすすめします。 |
| 時刻 | すべてのサーバーとコンソールの時刻を NTP で合わせます。署名の時刻が60秒以上ずれると、リクエストは拒否されます。 |
| 証明書 | コンソール用の HTTPS 証明書(例:Let's Encrypt)。ログイン Cookie は HTTPS でのみ送信されるため、平文の HTTP ではログインできません。 |
保護する各サーバーに、まずパッケージをインストールします。
# Debian · Ubuntu apt-get update && apt-get install -y fail2ban nftables sqlite3 # RHEL · Rocky · CentOS dnf install -y epel-release && dnf install -y fail2ban nftables sqlite systemctl enable --now fail2ban
2. fail2ban の指数バンを有効にする
同じ IP が繰り返し来るほど、長くブロックするように設定します。SecuMon はこの倍率から「いま何段階目か」と「次はどれだけブロックされるか」を計算します。
# /etc/fail2ban/jail.local [DEFAULT] bantime = 1h findtime = 10m maxretry = 5 bantime.increment = true bantime.multipliers = 1 2 4 8 16 32 64 168 bantime.maxtime = 168h ignoreip = 127.0.0.1/8 ::1 <自分の VPN アドレス帯> # /etc/fail2ban/fail2ban.local — 再犯の記録を60日間保持する(デフォルトの1日だと、翌日には初犯扱いになる) [DEFINITION] dbpurgeage = 60d
上の設定では、バンの長さは次のとおりです。fail2ban がわずかにランダムな時間を加えるため、実際の値は多少異なります。
| 累積バン | 1回 | 2回 | 3回 | 4回 | 5回 | 6回 | 7回 | 8回以上 |
|---|---|---|---|---|---|---|---|---|
| バンの長さ | 1時間 | 2時間 | 4時間 | 8時間 | 16時間 | 32時間 | 64時間 | 7日 |
ignoreip には、自分の接続経路(VPN のアドレス帯など)を必ず入れてください。パスワードを数回間違えただけで、自分のサーバーから自分がバンされるのを防ぎます。
3. コンソールのインストール
3-1. シークレットファイル
シークレットはコードや環境変数に書かず、ひとつのフォルダーにファイルとして置きます。コンソールのコンテナはこのフォルダーを /App/secrets に読み取り専用でマウントします。
mkdir -p /srv/secumon/secrets/tls && chmod 700 /srv/secumon cd /srv/secumon/secrets openssl rand -hex 24 > db_password openssl rand -base64 18 > admin_password # 初回ログイン用のパスワード(アカウント名 admin) openssl genpkey -algorithm ed25519 -out console_ed25519.key openssl pkey -in console_ed25519.key -pubout -out console_ed25519.key.pub # コンテナのアカウントが読めるようファイルは 644 に — 保護は上位フォルダーの 700 が担う chmod 644 db_password admin_password console_ed25519.key console_ed25519.key.pub
| ファイル | 用途 | ない場合 |
|---|---|---|
db_password | データベース接続 | コンソールが起動しません |
admin_password | 最初の管理者アカウント admin のパスワード | アカウントが作成されず、ログインできません |
console_ed25519.key · .pub | コマンドの署名 | 閲覧のみ可能で、執行はできません |
abuseipdb.key | AbuseIPDB API キー(任意) | 報告 · レピュテーション照会が使えません |
telegram.env | Telegram 通知(任意) | 通知が送信されません |
tls/cert.pem · chain.pem · privkey.pem | コンソールの HTTPS 証明書 | HTTPS で開けません |
console_ed25519.key ひとつで、すべてのサーバーに有効なコマンドを署名できます。このファイルはリポジトリ · 共有ドライブに置かず、別に保管してください。
3-2. データベース
DB のポートは外部に公開しません。コンソールは同じ Docker ネットワーク内で、コンテナ名で接続します。
docker network create secumon-net docker run -d --name secumon-db --network secumon-net --restart unless-stopped \ -e POSTGRES_DB=secumon -e POSTGRES_USER=secumon \ -e POSTGRES_PASSWORD_FILE=/run/secrets/db_password \ -v /srv/secumon/secrets/db_password:/run/secrets/db_password:ro \ -v secumon_pgdata:/var/lib/postgresql/data \ postgres:17
テーブルと初期データは、コンソールの初回起動時に自動で作成されます。psql で別途スキーマを投入する必要はありません。
3-3. コンソールの設定
コンソールは Tomcat 11 上で動く Web アプリです。実行方法は配布パッケージとあわせて公開します。ここでは、あらかじめ決めておく環境変数をまとめます。
| 環境変数 | デフォルト値 | 意味 |
|---|---|---|
F2B_DB_URL | jdbc:postgresql://…:5432/secumon | DB のアドレス。コンテナ名で指定します。 |
F2B_CANONICAL_HOST | 必ず自分の値に | 自分のコンソールのドメイン。平文の HTTP や別のアドレスでアクセスされた場合は、このアドレスの HTTPS へリダイレクトします。 |
F2B_PROTECTED_CIDRS | 必ず自分の値に | 絶対にブロックしないアドレス帯 — 自分の VPN · 内部ネットワーク · サーバーのグローバル IP。プライベートアドレス · ループバックはこの値に関係なく常に保護されます。 |
F2B_BLOCK_TTL_DAYS | 30 | アドレス帯ブロックのデフォルト期間(日)。0 は無期限。 |
F2B_AUTO_BLOCK_ENABLED | true | 再犯 IP の自動ブロックをオン/オフします。 |
F2B_AUTO_BLOCK_THRESHOLD | 3 | 何回目のバンから自動ブロックするか。 |
F2B_AUTO_BLOCK_TTL_DAYS | 30 | 自動ブロックの期間(日)。 |
F2B_FEED_REFRESH_HOURS | 24 | 公開ブロックリスト · 国別リストを再取得する間隔(時間)。 |
F2B_BAN_MULTIPLIERS | 1 2 4 8 16 32 64 168 | jail 設定の倍率とまったく同じにします。 |
F2B_ABUSE_DAILY_LIMIT | 1000 | AbuseIPDB の1日あたりの利用上限。 |
起動したら状態を確認します。"db":"ok" が表示されれば正常です。
curl -s https://<コンソールのアドレス>/api/health
4. サーバー登録 — エージェント
- コンソールに
adminでログインし、ターゲットタブでサーバー名を入力してから登録 + トークン発行を押します。 - 画面にターゲット ID とワンタイムトークンが表示されます。トークンはこのとき一度だけ表示され、15分後に失効します。
- 保護するサーバーで、root としてインストールスクリプトを実行します。
# 保護するサーバーで(root) tar xzf agent-amd64.tgz && cd agent ./install-agent.sh --console https://<コンソールのアドレス> \ --target-id <ターゲット ID> --token <ワンタイムトークン> journalctl -u secumon-agent -f # 30秒以内に下のような行が出れば正常
正常なら次のような行が出力されます secumon-agent: 2026/10/06 16:40:12 전송 완료 — jail 2개, 밴 5건
インストールスクリプトが行うのは、次のことだけです。ファイアウォールのポートは開けません。
- ログインできない専用アカウント
f2bagentを作成します — エージェントは root では動作しません。 - root 権限のラッパー
/usr/local/sbin/f2b-agent-execひとつだけを sudo で許可します。 - エージェントの署名鍵をそのサーバー上で生成します。秘密鍵がネットワークに出ることはありません。
- コンソールに登録したあと、
secumon-agentサービスとして常駐させます。
コンソールのアドレスに、アンダースコア(_)を含むホスト名を使わないでください。Tomcat 11 が規格違反として拒否します。サーバーがコンソールのドメインを名前解決できるか、getent hosts <コンソールのドメイン> で先に確認してください。
登録は済んだのにその後の手順で失敗した場合は、原因を直してから同じコマンドをそのまま再実行すれば大丈夫です。登録済みのエージェントがトークンを再び使うことはありません。
サーバーを外すには、コンソールで無効化し(そのエージェントのリクエストはすぐに拒否されます)、サーバーで systemctl disable --now secumon-agent を実行します。
5. 画面の見方
- ダッシュボード — すべてのサーバーの現在のバン · 累積バン · 再犯 IP · 推移。サーバーカードの「最終受信」が30秒を大きく超えている場合は、そのサーバーのエージェントを確認してください。
- バン一覧 — 現在バン中の IP。再犯段階 · 残り時間 · 国もあわせて表示します。国はコンソールに内蔵された参照表から調べます。
- IP 詳細 — その IP をバンしたサーバー、バン履歴、次回バンの予測時間、AbuseIPDB のレピュテーション。
「現在のバン」は fail2ban がいま実際にブロックしているリストから、「再犯回数」は fail2ban のバン記録から、それぞれ別に読み取ります。そのため、すでに解除されたバンを現在のバンとして誤表示することはありません。
6. バン · アンバン · アドレス帯ブロック
- バン · アンバンはオペレーター以上が実行できます。バンは任意の IP に対して可能で、jail を選ばない場合は
sshdになります。 - アドレス帯ブロックは管理者のみ実行できます。ブロックするアドレス帯をもう一度入力しないと実行されず、IPv4 /16 · IPv6 /48 より広い場合は拒否されます。デフォルトでは30日後に自動で解除されます。
- 複数のアドレス帯 × 複数のサーバーを一度にブロックできます。すべてが検査を通過しない限り、1件も発行されません — 半分だけブロックされた状態がいちばん危険だからです。
- コマンドは、サーバーのエージェントが60秒以内に取得した場合にのみ実行されます。結果は執行タブのコマンド履歴で、完了 · 失敗 · 期限切れとして確認できます。
誤ってブロックした場合は、コンソールの執行 → ブロック解除で解除します。コンソールに入れないほど急ぐ場合は、そのサーバーで直接削除します。
# アドレス帯をひとつだけ nft delete element inet f2b_console blocklist4 '{ 203.0.113.0/24 }' # SecuMon が追加したブロックをすべて(fail2ban のルールは別テーブルなのでそのまま) nft delete table inet f2b_console
7. 自動でブロックする
再犯 IP の自動ブロック
累積3回以上バンされた IP を5分ごとに抽出し、すべてのサーバーで30日間ブロックします。人の承認なしにファイアウォールを変更する唯一の機能なので、何重にも制約をかけています。
- アドレス帯ではなく、単一 IP(
/32·/128)だけをブロックします。 - 保護アドレス帯はスキップします。1回に発行するのは最大20件までです。
- 同じ IP を二度昇格させることはなく、すべて監査ログと Telegram に記録します。
無効にするには、コンソールに F2B_AUTO_BLOCK_ENABLED=false を設定して再起動します。誤ってブロックされた IP は、まずブロック解除で解除し、そのあと昇格記録を削除してください。削除しないと、後で改めて判定されません。
docker exec secumon-db psql -U secumon -d secumon -c "DELETE FROM auto_block WHERE ip = '<IP>'"
公開ブロックリスト
ブロックリストフィードタブでオンにします。初期状態ではどちらもオフです。
- Spamhaus DROP — ハイジャックされた、または犯罪にのみ使われているアドレス帯。正常なトラフィックが出てくることはないため、誤検知の心配はほとんどありません。
- FireHOL level1 — 使われていないアドレスと、確認済みの悪性アドレス帯。プライベートアドレスも含まれているため、コンソールが保護アドレス帯と重なる項目を除外してから送ります。
1日1回再取得し、内容が変わっていなければサーバーへは再送しません。リストから外れたアドレス帯は、次回の更新時に自動で解除されます。
8. 国別ブロック — オンにする前に
世界中からのアクセスが必要なサービスは、国単位でブロックできません。
- 権威 DNS サーバー — 世界中のリゾルバーがアクセスできなければ、自分のドメインが名前解決されません。SecuMon は53番ポートを常に許可します。
- メール受信(25)· VPN — ブロックするとメールが届かなくなり、海外から自分のサーバーに入れなくなります。こうしたサーバーでは国別ブロックをオンにしないでください。
- 検索エンジンのボット — 大きな国をブロックすると検索ボットも一緒にブロックされ、Web サイトが検索結果から消えることがあります。
国別ブロックタブで国を選ぶと、その国のアドレス帯の数を先に表示します。適用するとその場でリストを取得して30秒以内にすべてのサーバーへ反映し、オフにするとその国のリストを削除します。大きな国では、アドレス帯が数万件に達します。
攻撃が多い国でも、実際にはその国の一部のアドレス帯 · 借りたサーバーであることが少なくありません。ブロックすれば、別の国のサーバーへ移ってきます。国別ブロックは、公開ブロックリスト · 再犯の自動ブロックと併用する補助手段と考えてください。
SecuMon はファイアウォールルールの先頭で確立済み接続の応答を許可します。このルールがないと、自分のサーバーからその国のサービス(パッケージミラー · 通知 API · 証明書の発行)へ向けた接続の応答までブロックされてしまいます。
9. AbuseIPDB · Telegram
AbuseIPDB
シークレットフォルダーに abuseipdb.key を置くと有効になります。キーはコンソールサーバーにだけ存在し、画面 · DB · サーバーのどこにも出ていきません。
- 報告できるのは、現在バン中か、直近30日以内にバンされた IP だけです — 任意の IP は報告できません。
- 同じ IP を15分以内に再報告することはありません。1日の上限はコンソール自身がカウントします。
- カテゴリーは jail 名で決まります — ssh → 18 · 22、Web(apache · nginx)→ 18 · 21、メール → 18 · 11、その他 → 18。
Telegram
# /srv/secumon/secrets/telegram.env
TELEGRAM_TOKEN=<ボットトークン>
TELEGRAM_CHAT_ID=<チャット ID>
再犯の自動ブロックと公開リストの変更を通知します。リスト全体はファイルとして添付して送ります。変更がなければ通知しません — 毎日「変更なし」が届くと、本当に重要な通知を見逃してしまうからです。
10. アカウント · 2段階認証
| ロール | できること |
|---|---|
VIEWER 閲覧専用 | ダッシュボード · バン一覧 · IP 詳細 · コマンド履歴の閲覧 |
OPERATOR オペレーター | + バン · アンバン · AbuseIPDB への報告とレピュテーション照会 |
ADMIN 管理者 | + アドレス帯ブロック · サーバー登録 · ブロックリストフィード · 国別ブロック · ユーザー · 監査ログ |
- 初回ログインは、
adminとadmin_passwordファイルのパスワードで行います。ログイン後、マイアカウントでパスワードを変更してください。 - マイアカウント → 2段階認証で、認証アプリで QR コードを読み取るか、コードを直接入力します。同じコードは2回使えません。
- パスワードを5回間違えると15分間ロックされ、ひとつの IP からは1分間に10回までしか試行できません。30分間操作がないとログアウトされます。
認証アプリをなくした場合、画面からは解除できません。コンソールサーバーにアクセスできる人が、DB で直接解除します。
docker exec secumon-db psql -U secumon -d secumon -c \ "UPDATE app_user SET totp_enabled=false, totp_secret=NULL, totp_last_counter=0 WHERE username='admin';"
11. バックアップ · 鍵の管理
# データベース — パスワードはハッシュ、登録トークンもハッシュでのみ保存されている docker exec secumon-db pg_dump -U secumon secumon | gzip > secumon-$(date +%F).sql.gz # シークレットフォルダー — これが本当の秘密。DB のバックアップとは別の場所に置く tar czf secumon-secrets-$(date +%F).tgz -C /srv/secumon secrets
- コンソールの署名鍵を変えると、すべてのエージェントがコマンドを拒否します。変えた場合は、サーバーごとに 無効化 → トークン再発行 → サーバーの
/etc/secumon/agent.json·agent_ed25519.keyを削除 → 再インストール の順で再登録します。 - 定期的に確認すること:毎日はサーバーの状態と失敗したコマンド、毎週は監査ログの拒否記録と、2段階認証を有効にしていないアカウント。
12. トラブルシューティング
エージェントとコンソールのメッセージは韓国語で出力されます。下の表のコード表記の文字列を、そのままログで検索してください。
| 症状 | 原因 | 対処 |
|---|---|---|
エージェントのログ 등록되지 않았거나 비활성 상태인 타겟 | コンソールで無効化されたサーバー | トークンを再取得して再登録 |
エージェントのログ 요청 시각 편차가 허용치를 넘습니다 | サーバーの時刻が60秒以上ずれている | NTP で時刻を合わせる |
エージェントのログ 이미 사용된 nonce | 同じリクエストが再度届いた | 正常な防御です。続く場合は、ネットワークでの重複送信を疑う |
コマンド結果 거부: 만료된 명령 | エージェントが60秒以内に取得できなかった | サーバーの secumon-agent の状態を確認して再実行 |
コマンド結果 거부: 서명이 유효하지 않음 | コンソールの署名鍵を変えたあと、再登録していない | 11章の手順で再登録 |
| サーバーカードの最終受信が止まった · ログが途切れた | エージェントが停止している | systemctl restart secumon-agent |
| 国別ブロックをオンにしたのに、サーバーに反映されない | エージェントのログにこの行がない: 국가 차단 적용 | エージェントが最新バージョンか確認し、ログのエラーを確認します |
| ログインが何度も切れる | HTTPS ではないアドレスで接続している | コンソールの HTTPS アドレスで接続する |
その他のご質問は、halo@levelupsoft.com までお送りください。
fail2ban · nftables · AbuseIPDB · Spamhaus · FireHOL · Telegram · Let's Encrypt はそれぞれの所有者に帰属します。SSem SecuMon はこれらと提携しておらず、承認も受けていません。