Huy động mọi công cụ nhỏ để chặn bot
(lambdacreate.com)- Gitea và blog trên máy chủ cá nhân bị lưu lượng scraping đè nặng, liên tục phát cảnh báo đĩa, CPU và bộ nhớ; người vận hành đã kết hợp phân tích log, Nginx và Fail2Ban để phòng thủ
- Theo Zabbix, lưu lượng tăng mạnh so với bình thường; trung bình một tháng của Nginx là 8 request/giây, còn giai đoạn tệ nhất lên tới hơn 20 request/giây
- Nguyên nhân không phải một đợt truy cập đột biến từ một nguồn duy nhất như Reddit hay Hacker News, mà giống scraping phân tán hơn, khi nhiều dải IP quét các URL của
www.lambdacreate.comvàkrei.lambdacreate.com - Nginx trả về 403 cho các user agent độc hại đã biết và áp dụng giới hạn request theo IP; các client tạo quá nhiều 403 bị Fail2Ban chặn trong 24 giờ
- Tại thời điểm viết, danh sách chặn đã tăng lên tổng cộng 735 lượt ban; đặc biệt, các request cố tạo tarball cho mọi commit trong các kho công khai của Gitea làm tăng tải cho máy chủ
Lưu lượng scraping gây áp lực lên máy chủ cá nhân
- Lưu lượng bot không mong muốn bất ngờ đổ vào không gian Internet cá nhân, ảnh hưởng cả các dịch vụ mà độc giả thật sự cần truy cập
- Các dịch vụ lập chỉ mục nhằm bảo tồn website như Archive.org được xem là đối tượng được phép, nhưng Amazon, Facebook, OpenAI và nhiều bot ngẫu nhiên khác được phân loại là những bên tiêu thụ nội dung cho mục đích riêng của họ
- Cho rằng việc các tập đoàn lớn thu thập dữ liệu Internet trên diện rộng và nhu cầu dữ liệu để huấn luyện mô hình AI đã làm áp lực scraping gia tăng hơn nữa
- Lưu lượng này không phải người tiêu dùng thực sự của Lambdacreate, mà được xem là yếu tố gây cản trở khả năng truy cập của độc giả con người
Zabbix phát hiện dấu hiệu bất thường đầu tiên
- Công cụ đầu tiên báo vấn đề là Zabbix, với cảnh báo rằng ổ đĩa dành cho container đã đầy
- Trong môi trường dựa trên LXD, người vận hành đã mở rộng ZFS sparse file, tạm đưa site xuống rồi bật lại, nhưng nguyên nhân gốc vẫn còn
- Sau đó, instance Gitea tiêu thụ hết dung lượng đĩa mỗi ngày, tạo ra 20–30GB dữ liệu mỗi ngày
- Ban đầu, vấn đề được cho là do Gitea không bật mặc định việc dọn dẹp archive của repository, nên tác giả đã cấu hình tác vụ dọn dẹp mạnh tay
- Không lâu sau, cảnh báo CPU và bộ nhớ cũng xuất hiện; việc
git pullvàgit pushtrên Gitea trở nên khó khăn, còn client weechat cũng không giữ được kết nối
Số request tăng lên mức gấp 10 lần bình thường
- Nhờ có giám sát out-of-band để so sánh chỉ số quá khứ với trạng thái hiện tại, mẫu bất thường đã được xác nhận
- Trên dashboard Zabbix, các chỉ số cốt lõi là số request Nginx và biểu đồ thông lượng mạng
- Tính theo một tháng, lượng request Nginx trung bình ở mức 8 request/giây
- Vào thời điểm tệ nhất, máy chủ nhận hơn 20 request/giây; tuy nhỏ theo chuẩn các dịch vụ lớn, nhưng với máy chủ cá nhân thì đó là mức gấp 10 lần bình thường nên tác động rất lớn
- Không chỉ số request đơn thuần, mức sử dụng đĩa và CPU liên quan đến Gitea cũng tăng cùng lúc, khiến gánh nặng vận hành máy chủ lớn hơn
Truy vết log bằng lnav và goaccess
- Để giữ máy chủ sống đủ lâu cho việc xem log, người vận hành tạm tắt container và Nginx rồi bắt đầu phân tích
- Các công cụ được dùng là lnav và goaccess
lnavhiển thị file log trong TUI có tô màu, đồng thời cung cấp một lớp trừu tượng trên các định dạng log phổ biến để có thể truy vấn log bằng SQL- Trong
access.log, việc kiểm tra tập trung vào các câu hỏi sau- Có bao nhiêu IP truy cập tổng cộng
- Có mẫu hình nào trong địa chỉ IP hay không
- Lưu lượng có đến từ một referrer cụ thể không
- Những user agent nào được sử dụng
- IP nào gắn với user agent nào
- Kết quả phân tích cho thấy đây không phải “hug of death” đến từ một referrer duy nhất, mà là nhiều dải IP đang quét URL trên toàn bộ site
Trả 403 dựa trên user agent và giới hạn request
- Biện pháp đầu tiên là liệt kê các user agent gây vấn đề trong Nginx và trả về 403
- Cấu hình ví dụ dùng
map $http_user_agent $badagentđể đánh dấu các agent nhưAdsBot-Google,Amazonbot,Amazonbot/0.1 - Trong cấu hình Nginx mặc định, các quy tắc user agent được include, đồng thời thiết lập cả rate limit theo IP
- Cấu hình virtual host bao gồm các hành vi sau
- Áp dụng giới hạn request bằng
limit_req zone=krei burst=20 nodelay; - Nếu
$badagentlà đúng thì chặn truy cập nội dung bằngreturn 403;
- Áp dụng giới hạn request bằng
- Cách này giúp giảm xử lý ở backend, nhưng vì máy chủ vẫn phải nhận request HTTP và xử lý 403, nên khi có lượng lớn request đồng thời thì vẫn còn gánh nặng
Tự động hóa chặn bằng tường lửa với Fail2Ban
- Sau khi log 403 tích lũy, có thể dùng
lnavđể kiểm tra các IP duy nhất đã nhận 403 goaccessđược dùng để phân tích log cũ và hiện tại cùng nhau, nhằm xác định số request vào máy chủ và các endpoint bị nhắm tới nhiều nhất- Để bảo vệ máy chủ thực tế, Fail2Ban được bổ sung
- Quy tắc Fail2Ban là một dạng đơn giản, bắt các IP tạo quá nhiều phản hồi 403 trong access log của Nginx
- Thời gian chặn được đặt là 86400 giây, tức 24 giờ
- Kết quả
fail2ban-client status nginx-forbiddentại thời điểm viết như sau- Lỗi hiện tại: 13
- Tổng số lỗi: 57135
- Đang bị chặn: 38
- Tổng số lần chặn: 735
Mục tiêu thực sự không phải blog mà là tạo tarball trên Gitea
- Cuối cùng, độc giả đã có thể truy cập lại blog và các dịch vụ khác của Lambdacreate
- Trong tình huống phải chặn lưu lượng robot, ngay cả việc viết bài blog cũng trở nên khó khăn
- Lưu lượng gây vấn đề không phải scraping blog, mà nhắm vào việc tạo tarball cho mọi commit trong từng kho công khai của instance Gitea
- Về dài hạn, tác giả dự định cân nhắc mở rộng danh sách chặn hoặc đặt ngoại lệ cho các dịch vụ hợp pháp như Archive.org
- Lập trường là không muốn nội dung biến mất khỏi công cụ tìm kiếm, nhưng cũng không muốn để nó trở thành nhiên liệu cho sự xuống cấp của Internet do AI
Chưa có bình luận nào.