Honeypot Live Stats — 17 connections today from 11 unique IPs (17 total, 11 unique IPs all-time)
Kris Pham

Nhật ký triển khai

Toàn bộ chặng đường từ một máy chủ EC2 trống, đến một website Bludit hoàn chỉnh, có tên miền, HTTPS, và một honeypot SSH tự viết blog về chính những kẻ đang cố tấn công nó. Phạm vi: 14–19/8/2026.

Trạng thái hiện tại

Domain           khaipham.duckdns.org
Elastic IP       54.66.147.65
SSH quản trị     port 2222, chỉ cho IP của chủ
Honeypot Cowrie  port 22 công khai → 2223 nội bộ
CMS              Bludit, theme Flavor
Tự động hoá      cron mỗi 15 phút, systemd khi reboot

I. Dựng nền tảng — server và website

1. Khởi tạo EC2 và cài Bludit CMS

Từ dashboard EC2 trống, launch instance t3.micro chạy Amazon Linux 2023 (region Sydney), tạo key pair, mở security group cho SSH và HTTP. Cài nginx + php-fpm, tải mã nguồn Bludit trực tiếp từ GitHub, dựng cấu hình nginx route qua PHP.

Vướng mắc chính: bản Bludit từ nhánh master đi kèm sẵn tài khoản demo admin/admin — đổi mật khẩu ngay sau khi đăng nhập lần đầu. Lỗi "Session initialization failed" hoá ra do PHP-FPM chạy dưới user nginx nhưng thư mục session PHP mặc định chỉ cho apache ghi — sửa quyền thư mục là xong.

2. Elastic IP, tên miền và HTTPS thật

Gắn Elastic IP trước để IP không đổi mỗi lần restart — nhưng việc gắn IP mới lập tức làm vỡ giao diện, vì Bludit lưu cứng IP cũ làm base URL trong site.php, khiến CSS/JS bị trình duyệt chặn. Sửa bằng một dòng sed thay IP cũ bằng IP mới.

Đăng ký subdomain miễn phí trên DuckDNS, trỏ về Elastic IP. Cài Certbot qua Python venv (Amazon Linux không có sẵn gói này), lấy chứng chỉ Let's Encrypt. Lần chạy đầu thất bại vì nginx.conf vẫn còn server_name _; — một giá trị thật, không phải chỗ để trống, nên Certbot không khớp được block nào. Sau khi bật HTTPS, giao diện vỡ lần nữa vì cùng lý do — base URL vẫn lưu http:// thay vì https://.

Bài học lặp lại: bất cứ thứ gì lưu cứng base URL của site sẽ "cắn" bạn hai lần — một lần khi đổi IP, một lần khi đổi giao thức.

II. Honeypot — dựng cái bẫy

3. Nhường port 22 lại — chuyển SSH thật sang 2222

Trước khi đặt bẫy, SSH thật được chuyển sang port 2222, kiểm tra kết nối ổn định từ một cửa sổ terminal riêng trước khi đóng port 22 cũ, tránh tự khoá mình ra khỏi server.

sudo sed -i '/^#Port 22$/a Port 22\nPort 2222' /etc/ssh/sshd_config
sudo systemctl restart sshd
sudo sed -i '/^Port 22$/d' /etc/ssh/sshd_config
sudo systemctl restart sshd

4. Cài Cowrie — SSH giả để bẫy kẻ quét mạng

Tạo user riêng cowrie (khoá mật khẩu đăng nhập), cài Python 3.11 vì Cowrie mới nhất yêu cầu ≥3.10 trong khi Amazon Linux chỉ có 3.9 mặc định. Port SSH mặc định của Cowrie (2222) trùng với SSH thật vừa chuyển sang — đổi Cowrie sang port nội bộ 2223. Dùng iptables chuyển hướng port 22 công khai sang 2223 nội bộ.

sudo iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2223

Kiểm chứng ngay: honeypot chấp nhận đăng nhập với mật khẩu bất kỳ, giả lập hệ thống Debian cũ (kernel 2.6.26) để dụ kẻ tấn công ở lại lâu hơn.

5. Script tự động biến log thành bài blog

Một script Python đọc log JSON của Cowrie, đếm kết nối và IP nguồn trong ngày, ghi trực tiếp vào file nội dung bài viết và database metadata của Bludit — không qua trang quản trị. Cài cronie (Amazon Linux không có cron sẵn), đặt lịch chạy mỗi 15 phút.

III. Bảo mật & vận hành lâu dài

6. Thêm một lớp khoá trước cửa quản trị

Gắn HTTP Basic Auth ở tầng nginx cho riêng /admin — trước khi chạm được form đăng nhập Bludit, trình duyệt phải qua thêm một lớp xác thực khác. Xác minh bằng curl -I để thấy đúng 401 Unauthorized.

7. Sống lại sau khi reboot

Cả Cowrie lẫn rule iptables ban đầu chỉ chạy tạm — restart server là mất. Biến cả hai thành systemd service, bật enable để tự khởi động cùng hệ thống.

8. Để mỗi báo cáo tự nói rõ nó đã cũ hay còn sống

Bài "Honeypot report" của hôm nay cập nhật liên tục, còn bài của ngày đã qua đứng yên vĩnh viễn — dễ gây nhầm là dữ liệu trùng lặp. Script được bổ sung: mỗi lần chạy, tự kiểm tra báo cáo của các ngày đã qua chưa có dấu "đã chốt", rồi tự thêm ghi chú cố định vào cuối bài đó.

IV. Nội dung, giao diện & để Google tìm thấy

9. Viết lại hành trình thành bài blog thật

Hai bài viết thủ công kể lại quá trình build: "Building my first honeypot on AWS" và "Getting a real domain and real HTTPS", cùng bài "Every command" gom toàn bộ lệnh đã dùng để tra cứu nhanh.

10. Đổi giao diện và cá nhân hoá

Chuyển từ theme mặc định Alternative sang Flavor — tối giản hơn, dùng Tailwind. Đổi tên site từ "BLUDIT" thành tên riêng, viết lại banner "Honeypot Live Stats" cho khớp hệ màu theme mới.

11. Khai báo với Google

Bật plugin Sitemap có sẵn của Bludit để tự sinh sitemap.xml. Đăng ký Google Search Console, xác minh quyền sở hữu bằng file HTML tải lên thư mục gốc, nộp sitemap — miễn phí hoàn toàn.

Nhìn lại

Điểm chung xuyên suốt: hầu hết sự cố không đến từ một lệnh sai, mà từ việc một nơi nào đó lưu cứng một giá trị — IP, giao thức, tên miền — rồi thứ đó thay đổi mà không ai báo cho nơi lưu biết. Cách xử lý mỗi lần cũng giống nhau: tìm đúng nơi lưu, sửa, rồi xác minh lại bằng công cụ độc lập thay vì chỉ tin cảm giác "chắc là được rồi".

Server hiện tự vận hành: honeypot ghi log, script mỗi 15 phút biến log thành bài viết, systemd giữ mọi thứ sống qua reboot.