Hướng dẫn miễn phí SSem SecuMon

Bắt đầu từ một máy chủ cá nhân · cập nhật tháng 10/2026

Sắp ra mắtBộ cài đặt đang được chuẩn bị để phát hành.

Hướng dẫn này công bố trước các yêu cầu, trình tự cài đặt và những điều cần biết khi vận hành. Khi bắt đầu phát hành, địa chỉ tải về sẽ được ghi tại đây.

1. Chuẩn bị

Hạng mụcYêu cầu
Máy chủ cần bảo vệLinux (systemd) + fail2ban · nftables · sqlite3. amd64 hoặc arm64. Đã kiểm chứng trên Ubuntu 22.04 · CentOS 8.
Máy chủ console1 máy. JDK 21 · Tomcat 11 · PostgreSQL 17. Chạy bằng Docker là đơn giản nhất.
MạngCác máy chủ phải kết nối HTTPS được tới địa chỉ console. Không cần mở cổng nào vào máy chủ. Nên đặt console sau VPN hoặc mạng nội bộ.
Đồng hồĐồng bộ đồng hồ của mọi máy chủ và console bằng NTP. Nếu thời điểm ký lệch quá 60 giây, yêu cầu sẽ bị từ chối.
Chứng chỉChứng chỉ HTTPS cho console (ví dụ: Let's Encrypt). Cookie đăng nhập chỉ được gửi qua HTTPS nên không thể đăng nhập bằng HTTP không mã hóa.

Trước tiên, cài các gói cần thiết trên từng máy chủ cần bảo vệ.

# 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. Bật ban theo cấp số nhân trong fail2ban

Cấu hình để cùng một IP càng quay lại thì càng bị chặn lâu hơn. SecuMon dùng các hệ số nhân này để tính “IP đang ở mức mấy” và “lần tới sẽ bị chặn bao lâu”.

# /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 <dải VPN của bạn>

# /etc/fail2ban/fail2ban.local — giữ lịch sử tái phạm 60 ngày (mặc định 1 ngày thì sau một ngày IP lại thành vi phạm lần đầu)
[DEFINITION]
dbpurgeage = 60d

Với cấu hình trên, thời lượng ban như sau. fail2ban cộng thêm một khoảng thời gian ngẫu nhiên nhỏ nên giá trị thực tế sẽ chênh lệch đôi chút.

Ban tích lũy1 lần2 lần3 lần4 lần5 lần6 lần7 lầnTừ 8 lần
Thời lượng ban1 giờ2 giờ4 giờ8 giờ16 giờ32 giờ64 giờ7 ngày

Hãy nhớ thêm đường truy cập của bạn (dải VPN, v.v.) vào ignoreip. Như vậy bạn sẽ không bị chính máy chủ của mình ban chỉ vì gõ sai mật khẩu vài lần.

3. Cài đặt console

3-1. Tệp bí mật

Giá trị bí mật không ghi trong mã nguồn hay biến môi trường mà lưu thành tệp trong một thư mục. Container console gắn thư mục này vào /App/secrets ở chế độ chỉ đọc.

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      # mật khẩu đăng nhập lần đầu (tên tài khoản admin)
openssl genpkey -algorithm ed25519 -out console_ed25519.key
openssl pkey -in console_ed25519.key -pubout -out console_ed25519.key.pub
# tệp để quyền 644 cho tài khoản container đọc được — việc bảo vệ do thư mục cha 700 đảm nhận
chmod 644 db_password admin_password console_ed25519.key console_ed25519.key.pub
TệpMục đíchNếu thiếu
db_passwordKết nối cơ sở dữ liệuConsole không khởi động
admin_passwordMật khẩu của tài khoản quản trị đầu tiên adminTài khoản không được tạo nên không thể đăng nhập
console_ed25519.key · .pubKý lệnhChỉ xem được, không thể thực thi
abuseipdb.keyKhóa API AbuseIPDB (tùy chọn)Không dùng được báo cáo · tra cứu uy tín
telegram.envThông báo Telegram (tùy chọn)Không gửi thông báo
tls/cert.pem · chain.pem · privkey.pemChứng chỉ HTTPS của consoleKhông mở được qua HTTPS

Chỉ với console_ed25519.key là có thể ký lệnh hợp lệ cho mọi máy chủ. Đừng để tệp này trong kho mã · ổ đĩa dùng chung, hãy cất giữ riêng.

3-2. Cơ sở dữ liệu

Không mở cổng DB ra bên ngoài. Console kết nối bằng tên container trong cùng mạng 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

Bảng và dữ liệu mặc định do console tự tạo khi khởi động lần đầu. Không cần nạp schema riêng bằng psql.

3-3. Cấu hình console

Console là ứng dụng web chạy trên Tomcat 11. Cách chạy sẽ được công bố cùng gói phát hành; ở đây trước tiên liệt kê các biến môi trường cần thiết lập.

Biến môi trườngMặc địnhÝ nghĩa
F2B_DB_URLjdbc:postgresql://…:5432/secumonĐịa chỉ DB. Ghi bằng tên container.
F2B_CANONICAL_HOSTBắt buộc đặt giá trị của bạnTên miền console của bạn. Truy cập bằng HTTP không mã hóa hoặc địa chỉ khác sẽ được chuyển sang HTTPS của địa chỉ này.
F2B_PROTECTED_CIDRSBắt buộc đặt giá trị của bạnCác dải tuyệt đối không chặn — VPN của bạn · mạng nội bộ · IP công khai của máy chủ. Mạng riêng · loopback luôn được bảo vệ bất kể giá trị này.
F2B_BLOCK_TTL_DAYS30Thời hạn mặc định (ngày) của lệnh chặn dải IP. 0 là vĩnh viễn.
F2B_AUTO_BLOCK_ENABLEDtrueBật / tắt tự động chặn IP tái phạm.
F2B_AUTO_BLOCK_THRESHOLD3Tự động chặn kể từ lần ban thứ mấy.
F2B_AUTO_BLOCK_TTL_DAYS30Thời hạn chặn tự động (ngày).
F2B_FEED_REFRESH_HOURS24Chu kỳ (giờ) tải lại danh sách chặn công khai · danh sách quốc gia.
F2B_BAN_MULTIPLIERS1 2 4 8 16 32 64 168Đặt giống hệt các hệ số nhân trong cấu hình jail.
F2B_ABUSE_DAILY_LIMIT1000Hạn mức sử dụng AbuseIPDB mỗi ngày.

Sau khi khởi động, hãy kiểm tra trạng thái. Thấy "db":"ok" là bình thường.

curl -s https://<địa chỉ console>/api/health

4. Đăng ký máy chủ — agent

  1. Đăng nhập console bằng admin, nhập tên máy chủ ở thẻ Máy đích rồi nhấn Đăng ký + Cấp token.
  2. Màn hình hiện ID máy đích và token dùng một lần. Token chỉ hiện một lần duy nhất lúc này và hết hạn sau 15 phút.
  3. Trên máy chủ cần bảo vệ, chạy script cài đặt bằng root.
# trên máy chủ cần bảo vệ (root)
tar xzf agent-amd64.tgz && cd agent
./install-agent.sh --console https://<địa chỉ console> \
    --target-id <ID máy đích> --token <token dùng một lần>
journalctl -u secumon-agent -f      # trong 30 giây thấy dòng như bên dưới là bình thường

Nếu bình thường, bạn sẽ thấy dòng như sau secumon-agent: 2026/10/06 16:40:12 전송 완료 — jail 2개, 밴 5건

Script cài đặt chỉ làm đúng những việc sau. Không mở cổng tường lửa nào.

  • Tạo tài khoản riêng không thể đăng nhập f2bagent — agent không chạy bằng root.
  • Chỉ cho phép qua sudo đúng một wrapper quyền root là /usr/local/sbin/f2b-agent-exec.
  • Tạo khóa ký của agent ngay trên máy chủ đó. Khóa riêng không bao giờ đi ra mạng.
  • Sau khi đăng ký với console, cho chạy thường trực dưới dạng dịch vụ secumon-agent.

Đừng dùng tên máy chủ có dấu gạch dưới (_) trong địa chỉ console. Tomcat 11 từ chối vì vi phạm chuẩn. Hãy kiểm tra trước xem máy chủ có phân giải được tên miền console không bằng getent hosts <tên miền console>.

Nếu đăng ký đã xong nhưng thất bại ở bước sau, chỉ cần sửa nguyên nhân rồi chạy lại đúng lệnh đó y nguyên. Agent đã đăng ký sẽ không dùng lại token.

Để gỡ một máy chủ, hãy Vô hiệu hóa nó trên console (yêu cầu của agent đó bị từ chối ngay lập tức), rồi chạy systemctl disable --now secumon-agent trên máy chủ.

5. Cách đọc giao diện

  • Bảng tổng quan — số IP đang ban · ban tích lũy · IP tái phạm · xu hướng của mọi máy chủ. Nếu “Lần nhận cuối” trên thẻ máy chủ vượt xa 30 giây, hãy kiểm tra agent của máy chủ đó.
  • Danh sách ban — các IP đang bị chặn, kèm mức tái phạm · thời gian còn lại · quốc gia. Quốc gia được tra từ bảng tích hợp sẵn trong console.
  • Chi tiết IP — các máy chủ đã ban IP đó, lịch sử ban, thời lượng dự kiến của lần ban tới, điểm uy tín AbuseIPDB.

“Đang ban” được đọc từ danh sách mà fail2ban thực sự đang chặn, còn “số lần tái phạm” được đọc riêng từ bản ghi ban của fail2ban. Nhờ vậy, các lệnh ban đã hết hạn không bị hiển thị nhầm là đang ban.

6. Ban · gỡ ban · chặn dải IP

  • Ban · gỡ ban có thể thực hiện từ vai trò người vận hành trở lên. Có thể ban bất kỳ IP nào, và nếu không chọn jail thì mặc định là sshd.
  • Chặn dải IP chỉ quản trị viên mới làm được. Phải nhập lại dải cần chặn thì lệnh mới chạy, và dải rộng hơn IPv4 /16 · IPv6 /48 sẽ bị từ chối. Mặc định tự gỡ sau 30 ngày.
  • Có thể chặn nhiều dải × nhiều máy chủ cùng lúc. Phải tất cả đều qua kiểm tra thì mới có lệnh nào được phát hành — vì trạng thái chỉ chặn được một nửa là nguy hiểm nhất.
  • Lệnh chỉ được thực thi khi agent trên máy chủ lấy về trong vòng 60 giây. Kết quả được xem trong lịch sử lệnh ở thẻ Thực thi với trạng thái hoàn tất · thất bại · hết hạn.

Nếu chặn nhầm, hãy gỡ bằng Thực thi → Bỏ chặn trên console. Nếu gấp đến mức không vào được console, hãy xóa trực tiếp trên máy chủ đó.

# chỉ một dải
nft delete element inet f2b_console blocklist4 '{ 203.0.113.0/24 }'
# toàn bộ lệnh chặn do SecuMon thêm vào (quy tắc fail2ban nằm ở bảng khác nên vẫn giữ nguyên)
nft delete table inet f2b_console

7. Chặn tự động

Tự động chặn IP tái phạm

Cứ 5 phút một lần, chọn các IP đã bị ban tích lũy từ 3 lần trở lên và chặn 30 ngày trên mọi máy chủ. Đây là tính năng duy nhất thay đổi tường lửa mà không cần con người phê duyệt, nên được ràng buộc bằng nhiều lớp.

  • Chỉ chặn IP đơn lẻ (/32 · /128), không chặn dải.
  • Bỏ qua các dải được bảo vệ. Mỗi lần chỉ phát hành tối đa 20 mục.
  • Không nâng mức cùng một IP hai lần, và mọi thao tác đều được ghi vào nhật ký kiểm toán và Telegram.

Để tắt, đặt F2B_AUTO_BLOCK_ENABLED=false cho console rồi khởi động lại. Với IP bị chặn nhầm, trước tiên hãy gỡ bằng Bỏ chặn, sau đó xóa bản ghi nâng mức thì lần sau IP đó mới được đánh giá lại.

docker exec secumon-db psql -U secumon -d secumon -c "DELETE FROM auto_block WHERE ip = '<IP>'"

Danh sách chặn công khai

Bật ở thẻ Nguồn chặn. Ban đầu cả hai đều tắt.

  • Spamhaus DROP — các dải bị chiếm quyền (hijack) hoặc chỉ dùng cho hoạt động tội phạm. Không thể có lưu lượng hợp lệ từ đó nên hầu như không lo chặn nhầm.
  • FireHOL level1 — địa chỉ chưa được sử dụng và các dải độc hại đã được xác nhận. Danh sách này có cả mạng riêng, nên console lọc bỏ các mục trùng với dải được bảo vệ rồi mới gửi đi.

Tải lại mỗi ngày một lần; nếu nội dung không đổi thì không gửi lại cho máy chủ. Dải nào bị loại khỏi danh sách sẽ tự được gỡ ở lần cập nhật tiếp theo.

8. Chặn theo quốc gia — trước khi bật

Dịch vụ cần được truy cập từ khắp thế giới thì không thể chặn theo quốc gia.

  • Máy chủ DNS có thẩm quyền — resolver trên toàn thế giới phải truy cập được thì tên miền của bạn mới được phân giải. SecuMon luôn cho phép cổng 53.
  • Nhận thư (25) · VPN — nếu chặn, thư sẽ bị gián đoạn và bạn không thể vào máy chủ của mình khi ở nước ngoài. Đừng bật chặn theo quốc gia trên những máy chủ như vậy.
  • Bot công cụ tìm kiếm — chặn một quốc gia lớn thì bot tìm kiếm cũng bị chặn theo, và website có thể biến mất khỏi kết quả tìm kiếm.

Chọn quốc gia ở thẻ Chặn theo quốc gia, console sẽ hiển thị trước số dải IP của quốc gia đó. Khi áp dụng, danh sách được tải về ngay và đưa vào mọi máy chủ trong vòng 30 giây; khi tắt, danh sách của quốc gia đó bị xóa. Quốc gia lớn có thể có tới hàng chục nghìn dải.

Ngay cả với quốc gia gửi tới nhiều tấn công, trên thực tế thường chỉ là vài dải nhỏ · máy chủ thuê ở nước đó. Bị chặn thì kẻ tấn công sẽ chuyển sang máy chủ ở nước khác. Hãy coi chặn theo quốc gia là biện pháp bổ trợ dùng kèm danh sách chặn công khai · tự động chặn IP tái phạm.

SecuMon cho phép phản hồi của kết nối đã thiết lập ngay ở đầu quy tắc tường lửa. Nếu không có quy tắc này, ngay cả phản hồi cho các kết nối mà máy chủ của bạn tạo ra tới dịch vụ ở nước đó (mirror gói · API thông báo · cấp chứng chỉ) cũng bị chặn.

9. AbuseIPDB · Telegram

AbuseIPDB

Đặt abuseipdb.key vào thư mục bí mật là tính năng được bật. Khóa chỉ nằm trên máy chủ console, không bao giờ lộ ra giao diện · DB · máy chủ nào.

  • Chỉ có thể báo cáo IP đang bị ban hoặc đã bị ban trong 30 ngày gần đây — không thể báo cáo IP tùy ý.
  • Không báo cáo lại cùng một IP trong vòng 15 phút. Hạn mức mỗi ngày do console tự đếm.
  • Danh mục được xác định theo tên jail — ssh → 18 · 22, web (apache · nginx) → 18 · 21, thư → 18 · 11, còn lại → 18.

Telegram

# /srv/secumon/secrets/telegram.env
TELEGRAM_TOKEN=<token bot>
TELEGRAM_CHAT_ID=<ID cuộc trò chuyện>

Thông báo khi tự động chặn IP tái phạm và khi danh sách công khai thay đổi. Toàn bộ danh sách được gửi kèm dưới dạng tệp. Không có gì thay đổi thì không thông báo — nếu ngày nào cũng nhận “không thay đổi”, bạn sẽ bỏ lỡ chính những thông báo quan trọng.

10. Tài khoản · xác thực hai bước

Vai tròViệc có thể làm
VIEWER chỉ xemXem bảng tổng quan · danh sách ban · chi tiết IP · lịch sử lệnh
OPERATOR người vận hành+ ban · gỡ ban · báo cáo AbuseIPDB và tra cứu uy tín
ADMIN quản trị viên+ chặn dải IP · đăng ký máy chủ · nguồn chặn · chặn theo quốc gia · người dùng · nhật ký kiểm toán
  • Lần đăng nhập đầu tiên dùng admin và mật khẩu trong tệp admin_password. Sau khi đăng nhập, hãy đổi mật khẩu trong Tài khoản của tôi.
  • Trong Tài khoản của tôi → Xác thực hai bước, quét mã QR bằng ứng dụng xác thực hoặc nhập mã thủ công. Một mã không thể dùng hai lần.
  • Sai mật khẩu 5 lần sẽ bị khóa 15 phút, và mỗi IP chỉ được thử tối đa 10 lần mỗi phút. Không thao tác gì trong 30 phút sẽ bị đăng xuất.

Nếu mất ứng dụng xác thực thì không thể gỡ trên giao diện. Người có quyền truy cập máy chủ console phải gỡ trực tiếp trong 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. Sao lưu · quản lý khóa

# cơ sở dữ liệu — mật khẩu đã được băm, token đăng ký cũng chỉ lưu dạng băm
docker exec secumon-db pg_dump -U secumon secumon | gzip > secumon-$(date +%F).sql.gz
# thư mục bí mật — đây mới là bí mật thật sự. Cất ở nơi khác với bản sao lưu DB
tar czf secumon-secrets-$(date +%F).tgz -C /srv/secumon secrets
  • Đổi khóa ký của console thì mọi agent sẽ từ chối lệnh. Nếu đã đổi, hãy đăng ký lại từng máy chủ theo trình tự: vô hiệu hóa → cấp lại token → xóa /etc/secumon/agent.json · agent_ed25519.key trên máy chủ → cài đặt lại.
  • Cần kiểm tra định kỳ: hằng ngày xem trạng thái máy chủ và lệnh thất bại; hằng tuần xem các bản ghi bị từ chối trong nhật ký kiểm toán và các tài khoản chưa bật xác thực hai bước.

12. Khắc phục sự cố

Thông báo của agent và console được ghi bằng tiếng Hàn. Hãy tìm trong log đúng đoạn chữ hiển thị dạng mã trong bảng dưới đây.

Hiện tượngNguyên nhânCách xử lý
Log agent 등록되지 않았거나 비활성 상태인 타겟Máy chủ đã bị vô hiệu hóa trên consoleNhận lại token và đăng ký lại
Log agent 요청 시각 편차가 허용치를 넘습니다Đồng hồ máy chủ lệch quá 60 giâyĐồng bộ đồng hồ bằng NTP
Log agent 이미 사용된 nonceCùng một yêu cầu được gửi lạiĐây là cơ chế phòng vệ bình thường. Nếu lặp lại liên tục, hãy nghi ngờ mạng gửi trùng lặp
Kết quả lệnh 거부: 만료된 명령Agent không lấy lệnh về trong vòng 60 giâyKiểm tra trạng thái secumon-agent trên máy chủ rồi chạy lại
Kết quả lệnh 거부: 서명이 유효하지 않음Đã đổi khóa ký của console nhưng chưa đăng ký lạiĐăng ký lại theo trình tự ở mục 11
“Lần nhận cuối” trên thẻ máy chủ dừng lại · log bị ngắtAgent bị treosystemctl restart secumon-agent
Đã bật chặn theo quốc gia nhưng máy chủ không thay đổiLog agent không có dòng này: 국가 차단 적용Kiểm tra agent có phải bản mới nhất không và xem lỗi trong log
Liên tục bị đăng xuấtTruy cập bằng địa chỉ không phải HTTPSTruy cập bằng địa chỉ HTTPS của console

Mọi thắc mắc khác, vui lòng gửi về halo@levelupsoft.com.