This site runs on a small, internet-facing Linux server. A few weeks after it went live, I opened the authentication logs out of curiosity and was not ready for the scale.
Filtering for failed SSH logins, the username "root" alone had been tried 291,215 times. Counting the rest pushes the total past 400,000 failed attempts. They were not evenly spread. A handful of hosts dominated: 62,798 tries from one IP, 62,231 from another, then a long tail each in the tens of thousands.
The usernames they guessed read like a cheat-sheet of automated playbooks: root, ubuntu, admin, user, test, oracle, postgres, git, mysql, debian. None of it is targeted at me. It is internet-wide background noise: botnets sweeping every reachable address, spraying default usernames at the SSH port. Almost none of those accounts even exist on the box.
I also looked up where the busiest sources came from, and the answer was telling. The two heaviest attackers, about 62,000 attempts each, were both cloud VMs inside AS63949, which is Akamai Connected Cloud, the network that used to be called Linode. I had them written down as two separate operators until I looked the ASN up. The rest traced to Microsoft Azure, Hetzner, and ISPs across Myanmar, Slovenia, Bangladesh, Vietnam, Ireland and Finland. That is the modern shape of brute-force: cheap rented or compromised cloud machines doing the work. My first draft of this post said that blocking one IP barely moves the needle, and my own table says otherwise. The two busiest hosts account for 125,029 attempts between them, close to a third of everything I logged, and blocking them would have been worth doing. What blocking does not buy is a lower arrival rate for long, because the next rented VM costs the operator a few cents and the address was never the asset.
Seeing it laid out was clarifying: every internet-facing host lives inside this constant hum of opportunistic attacks. The question is not whether you are probed. It is whether the easy attacks have been made pointless. So I looked at my own part of the setup through that lens:
• The database and app never touch the public internet. They are bound to localhost behind a reverse proxy; only the static site and a locked-down API are exposed.
• The web layer sends proper security headers, and the admin surface is gated.
And the clearest hardening lessons the data argues for:
• Key-only SSH. With no password to guess the attempts keep arriving and stop being able to land, which turns the whole category from risk into wasted traffic.
• Rate-limiting and lockout, so no single host can hammer the server thousands of times an hour.
• Turning logs into signal, so an alert fires when the pattern changes, because a new attacker doing something unusual matters far more than a bot trying "root" for the 291,216th time.
This is a first pass on a small server, not a SOC. But it taught me the most useful thing about defense so far: most of it is not clever, it is structural: reduce what is reachable, remove the weak door, then actually watch. That’s the part of blue-team work I want to get good at.
Methodology & sources / Phương pháp & Nguồn:
- The numbers in this post come straight from my own server's authentication logs (auth.log / journalctl, filtered for failed SSH logins); the busiest source IPs were attributed with public WHOIS/RDAP. This is primary data and you can check it. The parser and the two Sigma rules are at github.com/daihongphucecq/soc-ssh-analysis; the script runs against any auth.log and prints the same tables.
- Technique classification, MITRE ATT&CK: Brute Force T1110 — with the observed behaviour matching Password Guessing T1110.001 and Password Spraying T1110.003.
- Companion post on this site: "AutoJack and the wall that was never there."
Trang web này chạy trên một máy chủ Linux nhỏ có mặt trên Internet. Vài tuần sau khi lên sóng, tò mò mở log đăng nhập ra xem, và tôi không ngờ con số lại lớn đến vậy.
Lọc riêng các lần đăng nhập SSH thất bại, chỉ riêng tài khoản "root" đã bị thử 291.215 lần. Cộng phần còn lại, tổng vượt 400.000 lần thất bại. Chúng không rải đều. Một nhóm nhỏ máy chủ chiếm phần lớn: 62.798 lần từ một IP, 62.231 lần từ một IP khác, rồi một "đuôi dài" mỗi cái hàng chục nghìn lần.
Danh sách username chúng dò giống hệt một "bài tủ" của các công cụ tự động: root, ubuntu, admin, user, test, oracle, postgres, git, mysql, debian. Không có gì nhắm riêng vào tôi, đây là "tiếng ồn nền" của cả Internet: các botnet quét mọi địa chỉ với tới được, bắn username mặc định vào cổng SSH. Gần như không tài khoản nào trong số đó tồn tại trên máy.
Tôi cũng tra cứu nguồn gốc của những IP "hăng" nhất, và kết quả rất đáng nói. Hai kẻ tấn công nặng nhất, mỗi bên khoảng 62.000 lần, hoá ra đều là máy ảo nằm trong cùng một mạng AS63949, tức Akamai Connected Cloud, chính là nhà cung cấp trước đây tên Linode. Tôi đã ghi chúng thành hai bên khác nhau cho tới lúc tra số hiệu mạng. Phần còn lại đến từ Microsoft Azure, Hetzner, và các nhà mạng ở Myanmar, Slovenia, Bangladesh, Việt Nam, Ireland, Phần Lan. Đó là hình hài hiện đại của brute-force: máy chủ đám mây thuê rẻ hoặc bị chiếm làm việc thay người. Bản nháp đầu của bài này tôi viết rằng chặn một IP thì gần như không ăn thua, và chính cái bảng của tôi nói ngược lại: hai máy bận nhất cộng lại là 125.029 lần, gần một phần ba tất cả những gì tôi ghi được, chặn chúng là việc đáng làm. Thứ mà chặn IP không mua được là một tốc độ tấn công thấp lâu dài, vì cái máy ảo thuê tiếp theo chỉ tốn của họ vài xu, và địa chỉ chưa bao giờ là tài sản.
Nhìn tất cả bày ra trước mắt khiến tôi sáng ra một điều: mọi máy chủ có mặt trên Internet đều sống trong tiếng ồn tấn công cơ hội không ngừng này. Câu hỏi không phải "có bị dò hay không", mà là "những đòn dễ đã bị làm cho vô dụng hay chưa". Nên tôi soi lại phần cấu hình của mình:
• Cơ sở dữ liệu và ứng dụng không hề lộ ra Internet, chúng chỉ chạy nội bộ (localhost) sau một reverse proxy; thứ duy nhất công khai là trang tĩnh và một API đã khóa chặt.
• Tầng web gửi đầy đủ các security header, và khu quản trị được đặt sau lớp bảo vệ.
Và đây là những bài học siết bảo mật rõ nhất mà dữ liệu chỉ ra:
• Chỉ cho SSH bằng khóa (key-only). Không còn mật khẩu để đoán thì các lần dò vẫn cứ tới, nhưng hết đường thành công, cả nhóm tấn công này chuyển từ rủi ro thành lưu lượng vô ích.
• Giới hạn tần suất (rate-limit) và khóa tạm, để không một máy nào nện server hàng nghìn lần mỗi giờ.
• Biến log thành tín hiệu, để cảnh báo bật lên khi quy luật thay đổi, bởi một kẻ tấn công mới làm điều bất thường đáng chú ý hơn nhiều so với một con bot thử "root" lần thứ 291.216.
Đây mới chỉ là bước đầu trên một máy chủ nhỏ, chưa phải một SOC. Nhưng nó dạy tôi điều hữu ích nhất về phòng thủ cho tới giờ: phần lớn công việc không hề "cao siêu", mà mang tính nền tảng, thu hẹp những gì có thể với tới, gỡ bỏ cánh cửa yếu, rồi thật sự theo dõi. Đó chính là phần của nghề blue-team mà tôi muốn giỏi.
Methodology & sources / Phương pháp & Nguồn:
- Các con số trong bài lấy trực tiếp từ log xác thực của chính máy chủ của tôi (auth.log / journalctl, lọc các lần đăng nhập SSH thất bại); nguồn gốc các IP "hăng" nhất được tra bằng WHOIS/RDAP công khai. Đây là dữ liệu sơ cấp và bạn kiểm chứng được: script phân tích cùng hai rule Sigma nằm ở github.com/daihongphucecq/soc-ssh-analysis, chạy được trên bất kỳ file auth.log nào và in ra đúng những bảng trong bài.
- Phân loại kỹ thuật theo MITRE ATT&CK: Brute Force T1110, hành vi quan sát được khớp với Password Guessing T1110.001 và Password Spraying T1110.003.
- Bài đồng hành trên trang này: "AutoJack và bức tường chưa từng tồn tại".