4 điểm bởi GN⁺ 2025-06-02 | 1 bình luận | Chia sẻ qua WhatsApp
  • Do việc crawl và scraping bừa bãi từ các công ty AI/tìm kiếm lớn, các máy chủ và dịch vụ cá nhân bị ảnh hưởng nghiêm trọng, liên tục xảy ra tiêu tốn tài nguyên và mất ổn định dịch vụ
  • Sau khi phát hiện lưu lượng bất thường bằng giám sát dựa trên Zabbix·Loki, tác giả dùng các công cụ phân tích log (lnav, goaccess) và truy vấn dựa trên SQL để nắm chi tiết mẫu tấn công, IP, User Agent
  • Xây dựng hệ thống phòng thủ nhiều tầng trong cấu hình Nginx như chặn 403 theo User Agent, rate limit và tích hợp Fail2Ban, qua đó chặn hàng trăm IP độc hại và ổn định hóa máy chủ
  • Vấn đề chính là các bot cố tải hàng loạt toàn bộ kho Gitea dưới dạng tarball, và lưu lượng với mục đích "thu thập dữ liệu AI/huấn luyện mô hình" thay vì chỉ tiêu thụ nội dung đơn thuần đã tăng vọt
  • Về lâu dài, tác giả đang cân nhắc chiến lược xử lý ngoại lệ cho các dịch vụ hợp pháp (archive.org, v.v.), vẫn duy trì khả năng hiển thị trên công cụ tìm kiếm nhưng chống lại hiện tượng en-shitification của AI

Mở đầu: Lưu lượng bot đổ dồn vào máy chủ nhỏ của tôi

  • Gần đây, lưu lượng lớn không rõ nguồn gốc tăng vọt trên blog lambdacreate và nhiều dịch vụ do cá nhân vận hành
  • Các dịch vụ hợp pháp như Archive.org thì được hoan nghênh, nhưng việc crawl dữ liệu vô tội vạ từ các tập đoàn lớn như Amazon, Facebook, OpenAI lại gây hại cho trang web
  • Khi nhu cầu thu thập dữ liệu cho việc huấn luyện mô hình AI tăng cao, hiện tượng này càng trở nên nghiêm trọng hơn
  • Trong tình huống này, thay vì độc giả thật (con người), tác giả chủ yếu phải chịu đựng lượng lớn lưu lượng bot

Xác nhận vấn đề: Chẩn đoán bùng nổ lưu lượng bằng công cụ giám sát

  • Dùng các công cụ giám sát như Zabbix, Loki để phân tích tình trạng tiêu thụ tài nguyên máy chủ
  • Phiên bản Gitea xuất hiện hiện tượng tăng dữ liệu lên tới 20~30GB mỗi ngày, kèm nhiều cảnh báo CPU/bộ nhớ
  • Kết quả phân tích lưu lượng nginx cho thấy mức trung bình hàng tháng từ 8req/s tăng vọt tức thời lên hơn 20req/s
  • Dù không phải lưu lượng ở quy mô khổng lồ, nó vẫn tăng gần 10 lần so với bình thường và gây cạn kiệt tài nguyên

Phân tích nguyên nhân tấn công: Mổ xẻ sâu tệp log

  • Sử dụng lnavgoaccess để phân tích log access của nginx bằng SQL
    • Nắm bắt các mẫu về IP truy cập, User Agent, Referrer, v.v.
  • Kết quả cho thấy đây không phải lưu lượng đổ về từ một dịch vụ hay cộng đồng cụ thể, mà là crawl hàng loạt từ các dải IP nhất định
  • Phát hiện nhiều giá trị được khai báo hoặc giả mạo trong User Agent như Amazonbot, OpenAI, Applebot, Facebook
  • Vì điều này bắt đầu cản trở việc sử dụng dịch vụ thực tế, nhu cầu về một chính sách chặn mạnh tay trở nên cấp thiết

Giải pháp: Kết hợp nhiều lớp phòng thủ như Nginx, Fail2Ban

  • Dùng Nginx map để lập tức trả về 403 cho User Agent độc hại, đồng thời áp dụng rate limit (giới hạn tốc độ truy cập)
  • Giảm thiểu gánh nặng cho máy chủ bằng cách hạ tần suất yêu cầu web, kể cả với các bot mới hoặc chưa bị nhận diện
  • Dựa trên log phát sinh 403, dùng goaccess và lnav để phát hiện IP và User Agent độc hại mới
  • Thông qua công cụ bảo mật tự động Fail2Ban, tự động chặn trong 24 giờ các IP phát sinh quá nhiều phản hồi 403
    • Ghi nhận hơn 735 lần auto-ban
  • Mức sử dụng tài nguyên thực tế đã được đưa về trạng thái bình thường đáng kể
  • Trong tương lai, tác giả dự định áp dụng quy tắc ngoại lệ cho các dịch vụ hợp lệ như archive.org, cho phép công cụ tìm kiếm lập chỉ mục nhưng tiếp tục chặn việc crawl bừa bãi phục vụ huấn luyện AI

Kết luận: Sức mạnh của việc kết hợp công cụ và nhu cầu bảo mật cho dịch vụ cá nhân

  • Bằng cách áp dụng chuỗi biện pháp phòng thủ nhiều tầng này, tác giả đã khôi phục khả năng vận hành trơn tru của blog cá nhân và khả năng truy cập dịch vụ
  • Việc tận dụng nhiều công cụ quản trị hệ thống nhỏ và công cụ tự động hóa đã chứng minh hiệu quả đối với bảo mật máy chủ cá nhân
  • Trong môi trường mà ngay cả máy chủ cá nhân cũng bị crawl bừa bãi do nhu cầu huấn luyện AI ngày càng tăng, chặn chủ động và tự động hóa quản lý là điều thiết yếu

1 bình luận

 
GN⁺ 2025-06-02
Ý kiến trên Hacker News
  • Tôi thường xuyên thấy nhiều crawler thiếu ý thức chỉ đơn giản giả danh các công cụ tìm kiếm lớn; có người nói không nên để bị đánh lừa bởi thông tin user agent, nhưng cách tôi thích nhất là đưa thông tin bẫy đáng ngờ vào robots.txt (ví dụ: gzip bomb), rồi cấu hình để crawler nào chạm vào đó sẽ bị chặn từ các request tiếp theo. Có thể triển khai khá đơn giản bằng Caddy, và cách này chủ yếu tóm được những kẻ vi phạm nghiêm trọng. Tôi không định bào chữa cho hành vi của bot, nhưng nếu chỉ vài bot như vậy đã làm sập site của bạn thì đó cũng là bằng chứng cho thấy site đó cực kỳ dễ tổn thương trước kẻ tấn công ác ý.

    • Tôi thấy bình luận cuối mới thực sự chạm đúng trọng tâm. Có thể tôi khác thế hệ với nhiều người ở đây, nhưng tôi thật sự không hiểu vì sao dạo này người viết cứ ám ảnh với việc tiết kiệm chút tài nguyên ít ỏi như thế. Nó giống kiểu ông bà làm ầm lên vì tắt bóng đèn LED, hay lái 24 km chỉ để tiết kiệm 5 xu tiền xăng. 20 request mỗi giây thực sự chẳng là gì cả, kể cả khi trang được tạo động đi nữa (mà tại sao phải thế? Dành thời gian đó để thiết lập cache còn đáng hơn nhiều). Mấy bài kiểu 'fuck the bots' đúng là đang thịnh hành, nhưng đây đâu phải chủ đề mới mẻ gì. Có rất nhiều cách xử lý hiệu quả hơn mà không phải tốn thời gian như vậy.

    • Tôi muốn nghe chi tiết hơn về cách giăng gzip bomb qua robots.txt. Tôi cứ nghĩ đa số AI đều phớt lờ robots.txt, nên tự hỏi liệu cách này rốt cuộc chỉ bắt được một số crawler ngây thơ thôi không. Không phải tôi phản đối ai cả, chỉ là muốn biết thêm cách triển khai sao cho không gây hại tới bên vô tội.

    • Tôi vận hành một trong những wiki lớn nhất trong lĩnh vực của mình, nhưng gần như không thể thuyết phục những người khác trong đội phát triển dùng gzip bomb. Họ khăng khăng rằng cách này có rủi ro quá lớn (theo kiểu tư duy “vì quy định của EU”) nên không đáng để triển khai. Tôi rất tò mò không biết ngoài kia có ai thực sự dùng cách này trên site công khai hay không.

  • Dạo này bot hoàn toàn không tôn trọng file robots.txt, và điều đó làm tôi thật sự phát điên. Tôi nghĩ những người tạo ra kiểu bot đó đúng là cực kỳ ích kỷ. Nếu ai làm bot như vậy thì mặc xác họ.

    • Nếu gài bẫy kiểu honeypot trong file robots thì dù không bắt được bọn bỏ qua hoàn toàn, nó vẫn hữu ích để lọc ra những bot cố tình đi gây rối.

    • Cũng có thể nói điều tương tự với những người dùng chatbot, công cụ tìm kiếm hay công cụ so sánh giá. Thực ra chính những người dùng đó mới là tác nhân kinh tế chủ chốt tạo động lực cho đám scraper.

  • Tôi hiểu việc tác giả nói rằng “giờ tôi không còn bận tâm nữa”, nhưng tôi thấy trong danh sách IP bị cấm có Google, ripe.net và semrush. Không nói đến các công ty khác, riêng Google thì tôi thực sự sẽ không chặn. Nếu bạn muốn quảng bá site, tôi cũng nghĩ không cần chặn Semrush hay ripe.net. Dù nội dung của tôi có bị AI hay đám kỳ quặc nào đó scrape đi nữa, nếu ngay từ đầu site đã công khai thì cũng phải chấp nhận là nó sẽ bị sử dụng ở mức nào đó. Kiểu như tắt đèn biển hiệu nhà nghỉ rồi lại mời khách vào vậy.

    • Semrush đã gây phiền toái cực nặng ở nhiều tầng trong thời gian dài, đến mức suốt 8 năm qua tôi còn để lại cả thông điệp đặc biệt trong robots.txt. Cuối cùng tôi thậm chí phải lôi cả bộ phận pháp lý vào mới khiến họ dịu xuống được. Với tôi, chẳng có giá trị gì trong việc cho một công ty 'SEO' xua đuổi khách truy cập thật rồi scrape site một cách thô bạo như vậy. Các đối thủ của Semrush cũng tệ tương tự. Còn scraper AI hiện nay thì chất lượng quá thấp, đến mức có lúc tôi phải liên tục gửi thư khiếu nại chính thức tới cả nhà đầu tư lớn lẫn bộ phận PR của họ. Cuối cùng tôi cũng kéo tình hình trở lại bình thường bằng nhiều cách, cả kỹ thuật lẫn pháp lý.

    • Vấn đề thực tế là bot chiếm dụng một lượng lớn traffic và tài nguyên như băng thông, bộ nhớ, CPU, đĩa. Ngay trong phần giới thiệu cũng có nói đó là hành vi thiếu lịch sự khó chấp nhận. Tôi không thấy có lý do gì phải cung cấp lượng traffic đó cho scraper. Google cũng đang vận hành scraper AI, nên có lẽ đó là lý do nó xuất hiện trong danh sách chặn.

    • Cũng có những bot độc hại thật sự giả danh Google. Trước đây Google scrape theo cách tương đối lịch sự hơn, nhưng nếu tác giả dù có chặn hay không thì họ cũng đã lấy được lượng traffic cần thiết rồi, nên có lẽ cũng chẳng cần bận tâm làm gì.

    • Tôi tự hỏi sao sau 10 năm rồi mà mọi người vẫn chưa nhận ra là không nên dùng Google, nhất là khi giờ đây có cả tình huống Google dùng AI để kiểm duyệt các site độc lập, tôi còn liên kết thẳng tới bình luận liên quan. Giờ tôi thấy Google gần với một rủi ro hơn là một tài sản.

  • Do bot mà file log server phình lên quá lớn, đến mức các server của tôi phải tắt hẳn việc ghi log. Bot đang lì lợm scrape cả API, form, thậm chí cả những phần trên website chỉ có thể truy cập bằng thao tác nhấp. Anthropic, openAI, Facebook và nhiều bên khác vẫn đang scrape site của tôi.

    • Nếu là API chỉ có thể truy cập bằng thao tác nhấp thì tôi tò mò không biết bot đã tiếp cận bằng cách nào.

    • Tôi muốn biết thêm chi tiết về các API đó, để làm rõ liệu ý bạn là phần thuộc UI hoặc phần chỉ con người mới dùng được, hay là thực sự không có đường nào khác để vào. Gần đây AI agent đã bắt đầu mô phỏng cả hành vi người dùng thật, nên chúng ta đang sống trong thời kỳ gần như không thể phân biệt người với bot.

  • Tôi từng nghĩ cũng tốt khi các bot crawler AI điền trung thực header User-Agent, nhưng tôi khá bất ngờ khi thấy đây lại là nguyên nhân của lượng traffic lớn đến mức này. Đa số website đâu cần dữ liệu được lấy thường xuyên như vậy, nên lưu lượng này là quá nhiều. Với blog của lập trình viên thì lại càng khó hiểu hơn.

    • Phần lớn crawler AI vẫn tuân thủ robots.txt, nhưng đã có trường hợp sau khi bị chặn hoặc ngăn lại thì chúng lập tức đổi sang user agent của trình duyệt rồi thử crawl lại từ IP dân cư. Tuy nhiên, vì có quá nhiều trường hợp giả mạo OpenAI/Amazon/Facebook nên cần rất thận trọng khi phân biệt các trường hợp cụ thể.
  • Tôi là tác giả của tirreno. Nền tảng của chúng tôi được tối ưu cho người dùng đang đăng nhập trực tiếp, nhưng cũng có thể dùng rất hiệu quả để phát hiện và chặn bot. Chúng tôi ẩn danh IP bằng cách thay octet cuối cùng bằng dấu sao (*) để gộp các IP cùng subnet thành một tài khoản. Có thể cấu hình để tự động tạo blacklist dựa trên bất thường lưu lượng (lỗi 500/404, thử đăng nhập brute-force, IP từ datacenter, v.v.). Với blacklist API của tirreno, bạn có thể chuyển hướng traffic không mong muốn sang trang lỗi. Hệ thống cũng cung cấp dashboard giám sát để hỗ trợ quản lý và giảm false positive.
    tirreno Github, demo quản trị

    • Dạo này nhiều ISP chuyển sang cấu trúc CGNAT, nên tôi tò mò không biết các bạn xử lý thế nào với việc một IP có thể đại diện cho hàng trăm người dùng thật.

    • Tôi cũng đang phát triển tính năng chặn bot tương tự dựa trên dải IP công khai. Nếu có ý tưởng cải thiện nào thì tôi luôn rất hoan nghênh.

    • Với cách thay octet cuối của IP, tôi sẽ bị gộp thành một người dùng duy nhất với những “hàng xóm” ở địa chỉ hoàn toàn chẳng liên quan gì tới mình. False positive do IP trung tâm cũng không thể xem nhẹ. Trong thực tế, nếu không có gì bị chặn thì tôi còn phải nhấp qua 87 cái đèn giao thông mới lết qua được. Cuối cùng cảm giác như đây chỉ là để giữ danh nghĩa rằng bạn không thu thập dữ liệu riêng tư của tôi nếu không có sự đồng ý, ngay cả trong bước né false positive. Tôi hy vọng các bạn nhất định phải có một cơ chế phản hồi để khách hàng lập tức nhận ra rằng họ đang đánh mất người dùng trả phí thật.

  • Có một điều tôi đã thắc mắc từ lâu: liệu có thể làm kiểu “page knocking”, tức là phải mở các trang theo một thứ tự cụ thể để có quyền truy cập hay không. Ví dụ, phải vào trước một URL riêng tư được chỉ định thì các trang còn lại mới hiện bình thường thay vì trả về 404.

    • Kiến trúc như vậy không phù hợp với những trường hợp cần để người dùng bình thường có thể tìm thấy dự án qua công cụ tìm kiếm và truy cập ngay mà không phải tạo tài khoản hay xác thực gì thêm.

    • Về mặt trải nghiệm sử dụng thì dù thiết kế tốt đến đâu cũng khó tránh khỏi bất tiện. Khi dùng bookmark hay gửi link cho bạn bè, rất có thể họ vẫn chỉ gặp 404 liên tục.

  • Server nhỏ của tôi vẫn chạy ổn nên dạo gần đây tôi không xem trạng thái fail2ban.
    Kết quả chạy lệnh so sánh:

    sshd-ddos:      0
    postfix:       583
    dovecot:     9690
    postfix-sasl: 4227
    nginx-botsearch: 1421
    nginx-http-auth: 0
    postfix-botnet:  5425
    sshd:         202157
    

Tôi hơi sốc khi phát hiện hơn 220.000 IP đã bị chặn.

  • Một bot mà chúng tôi theo dõi, 'DotBot/1.2', đã để lại hơn 220.000 request trong 2 tuần gần đây. Nó có kiểu hành vi là ngẫu nhiên yêu cầu tên file và tên thư mục trên webserver. Vì tò mò không biết nó sẽ đào bới tới mức nào nên tôi cố tình chưa chặn mà chỉ đứng nhìn.

  • Tôi đang nghĩ liệu cấu trúc lập chỉ mục tập trung cho AI hay công cụ tìm kiếm giờ đây có nên chuyển sang mô hình push hoặc submit hay không. Nếu là kiểu chỉ chia sẻ trực tiếp khi tôi muốn thì tôi nghĩ vấn đề scraping sẽ giảm đi rất nhiều.

  • Hồi những năm 90 khi còn nhỏ, tôi từng nhận được cuộc gọi từ ISP báo rằng máy tính của tôi đã bị kéo vào botnet và họ sẽ ngắt kết nối Internet. Có lẽ nên quay lại thời đó, rồi chặn toàn bộ ASN của những ISP để mặc hành vi đó diễn ra thì mới chấm dứt được vấn đề này.

    • Proxy dân cư không phải do ISP trực tiếp cung cấp, mà phát sinh khi người dùng ở khắp nơi trên thế giới cố ý hoặc vô tình cài phần mềm độc hại rồi biến máy tính của mình thành proxy. Cách đây không lâu trên HN có một bài rất hay nói về chuyện này.

    • Tôi đã thiết lập một quy tắc tường lửa để hiện cảnh báo mỗi khi một thiết bị trong mạng của tôi cố gắng tạo kết nối outbound tới các cổng có liên quan tới malware. Danh sách cổng cần cập nhật định kỳ vì mục tiêu của malware cứ thay đổi liên tục. Chỉ là một biện pháp nhỏ thôi, nhưng nó vẫn là thêm một lớp phòng thủ nữa.