SSem SecuMon 무료 가이드

개인 서버 한 대부터 · 2026년 10월 기준

준비 중설치 파일 배포는 준비 중입니다.

이 가이드는 준비물과 설치 순서, 그리고 운영하며 알아 둘 것을 먼저 공개합니다. 배포가 시작되면 받는 주소를 이 자리에 적습니다.

1. 준비물

무엇조건
보호할 서버리눅스(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). 로그인 쿠키가 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.keyAbuseIPDB API 키 (선택)신고 · 평판 조회를 쓸 수 없습니다
telegram.env텔레그램 알림 (선택)알림이 나가지 않습니다
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 위에서 도는 웹 앱입니다. 실행 방법은 배포 패키지와 함께 공개하고, 여기서는 정해 둘 환경 변수를 먼저 정리합니다.

환경 변수기본값뜻
F2B_DB_URLjdbc:postgresql://…:5432/secumonDB 주소. 컨테이너 이름으로 적습니다.
F2B_CANONICAL_HOST반드시 내 값으로내 콘솔 도메인. 평문 HTTP 나 다른 주소로 들어오면 이 주소의 HTTPS 로 보냅니다.
F2B_PROTECTED_CIDRS반드시 내 값으로절대 막지 않을 대역 — 내 VPN · 내부망 · 서버 공인 IP. 사설망 · 루프백은 이 값과 상관없이 늘 보호됩니다.
F2B_BLOCK_TTL_DAYS30대역 차단의 기본 기간(일). 0 은 영구.
F2B_AUTO_BLOCK_ENABLEDtrue재범 IP 자동 차단을 켜고 끕니다.
F2B_AUTO_BLOCK_THRESHOLD3몇 번째 밴부터 자동 차단할지.
F2B_AUTO_BLOCK_TTL_DAYS30자동 차단 기간(일).
F2B_FEED_REFRESH_HOURS24공개 차단 목록 · 국가 목록을 다시 받는 주기(시간).
F2B_BAN_MULTIPLIERS1 2 4 8 16 32 64 168jail 설정의 배수와 똑같이 맞춥니다.
F2B_ABUSE_DAILY_LIMIT1000AbuseIPDB 하루 사용 한도.

기동한 뒤 상태를 확인합니다. "db":"ok" 가 보이면 정상입니다.

curl -s https://<콘솔 주소>/api/health

4. 서버 등록 — 에이전트

  1. 콘솔에 admin 으로 로그인하고 타겟 탭에서 서버 이름을 넣은 뒤 등록 + 토큰 발급을 누릅니다.
  2. 화면에 타겟 ID 와 1회용 토큰이 나옵니다. 토큰은 이때 한 번만 보이고 15분 뒤 만료됩니다.
  3. 보호할 서버에서 root 로 설치 스크립트를 실행합니다.
# 보호할 서버에서 (root)
tar xzf agent-amd64.tgz && cd agent
./install-agent.sh --console https://<콘솔 주소> \
    --target-id <타겟 ID> --token <1회용 토큰>
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일 뒤 저절로 풀립니다.
  • 여러 대역 × 여러 서버를 한 번에 걸 수 있습니다. 전부 검사를 통과해야 하나라도 발행됩니다 — 절반만 걸린 상태가 가장 위험하기 때문입니다.
  • 명령은 서버의 에이전트가 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)만 막습니다.
  • 보호 대역은 건너뜁니다. 한 번에 최대 20건까지만 발행합니다.
  • 같은 IP 를 두 번 올리지 않고, 전부 감사 로그와 텔레그램에 남깁니다.

끄려면 콘솔에 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 — 쓰이지 않는 주소와 확인된 악성 대역. 사설망도 들어 있어서, 콘솔이 보호 대역과 겹치는 항목을 걸러 낸 뒤 보냅니다.

하루에 한 번 다시 받고, 내용이 그대로면 서버로 다시 보내지 않습니다. 목록에서 빠진 대역은 다음 갱신 때 저절로 풀립니다.

8. 국가 차단 — 켜기 전에

전 세계에서 들어와야 하는 서비스는 나라로 막을 수 없습니다.

  • 권위 DNS 서버 — 전 세계 리졸버가 들어와야 내 도메인이 해석됩니다. SecuMon 은 53번 포트를 언제나 허용합니다.
  • 메일 수신(25) · VPN — 막으면 메일이 끊기고, 해외에서 내가 내 서버에 못 들어옵니다. 이런 서버에는 국가 차단을 켜지 마세요.
  • 검색엔진 봇 — 큰 나라를 막으면 검색 봇도 함께 막혀 웹사이트가 검색에서 사라질 수 있습니다.

국가 차단 탭에서 나라를 고르면 그 나라의 대역 수를 먼저 보여 줍니다. 적용하면 그 자리에서 목록을 받아 30초 안에 모든 서버에 들어가고, 끄면 그 나라의 목록을 지웁니다. 큰 나라는 대역이 수만 개에 이릅니다.

공격이 많이 오는 나라라도 실제로는 그 나라의 소수 대역 · 빌린 서버인 경우가 많습니다. 막으면 다른 나라 서버로 옮겨 옵니다. 국가 차단은 공개 차단 목록 · 재범 자동 차단과 함께 쓰는 보조 수단으로 생각하세요.

SecuMon 은 방화벽 규칙의 맨 앞에서 이미 맺은 연결의 응답을 허용합니다. 이 규칙이 없으면 내 서버가 그 나라의 서비스(패키지 미러 · 알림 API · 인증서 발급)로 나가는 연결의 응답까지 막힙니다.

9. AbuseIPDB · 텔레그램

AbuseIPDB

비밀 폴더에 abuseipdb.key 를 두면 켜집니다. 키는 콘솔 서버에만 있고 화면 · DB · 서버 어디에도 나가지 않습니다.

  • 지금 밴 중이거나 최근 30일 안에 밴된 IP 만 신고할 수 있습니다 — 임의의 IP 는 신고할 수 없습니다.
  • 같은 IP 를 15분 안에 다시 신고하지 않습니다. 하루 한도는 콘솔이 직접 셉니다.
  • 분류는 jail 이름으로 정합니다 — ssh → 18 · 22, 웹(apache · nginx) → 18 · 21, 메일 → 18 · 11, 그 밖 → 18.

텔레그램

# /srv/secumon/secrets/telegram.env
TELEGRAM_TOKEN=<봇 토큰>
TELEGRAM_CHAT_ID=<채팅 ID>

재범 자동 차단과 공개 목록 변경을 알립니다. 목록 전체는 파일로 붙여 보냅니다. 바뀐 것이 없으면 알리지 않습니다 — 매일 「변경 없음」이 오면 정작 중요한 알림을 놓치게 됩니다.

10. 계정 · 2단계 인증

역할할 수 있는 일
VIEWER 보기 전용대시보드 · 밴 목록 · IP 상세 · 명령 이력 보기
OPERATOR 운영자+ 밴 · 언밴 · AbuseIPDB 신고와 평판 조회
ADMIN 관리자+ 대역 차단 · 서버 등록 · 차단 피드 · 국가 차단 · 사용자 · 감사 로그
  • 첫 로그인은 admin 과 admin_password 파일의 비밀번호로 합니다. 로그인한 뒤 내 계정에서 비밀번호를 바꾸세요.
  • 내 계정 → 2단계 인증에서 인증 앱으로 QR 을 찍거나 코드를 직접 넣습니다. 같은 코드는 두 번 쓸 수 없습니다.
  • 비밀번호를 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 으로 보내 주세요.