Kỹ thuật chống DDoS cơ bản khi quản trị Web

Lá chắn chặn các luồng truy cập tấn công, minh hoạ chống DDoS

Website đang chạy quảng cáo bỗng phản hồi chậm rồi ngừng hẳn, trong khi bảng thống kê hiển thị lượng truy cập tăng vọt. Đó là lúc bạn phải trả lời một câu hỏi trong vài phút: đây là khách thật đông bất thường, là bot cào dữ liệu, hay là một đợt tấn công từ chối dịch vụ.

Bài này viết ở tầng phòng thủ cho người quản trị website vừa và nhỏ: cách nhận biết, các lớp bảo vệ nên dựng sẵn, và trình tự thao tác khi sự cố đang diễn ra. Không có phần nào nói về cách tấn công, vì đó là việc trái pháp luật và cũng không giúp bạn phòng thủ tốt hơn.

Hiểu đúng vấn đề trước khi mua giải pháp

Tấn công từ chối dịch vụ phân tán nhắm tới việc làm cạn một loại tài nguyên nào đó. Với người quản trị, chỉ cần phân biệt hai nhóm:

  • Nhóm gây ngập băng thông và kết nối: lưu lượng rác đổ vào đường truyền hoặc mở thật nhiều kết nối dở dang. Máy chủ chưa kịp xử lý gì thì đường đã tắc. Loại này gần như không thể chống bằng cấu hình phần mềm trên chính máy chủ đó — phải có một lớp lọc đứng trước.
  • Nhóm nhắm vào ứng dụng: gửi các yêu cầu trông như người thật nhưng chọn đúng những trang tốn tài nguyên nhất — trang tìm kiếm nội bộ, trang lọc sản phẩm nhiều tham số, trang đăng nhập. Số yêu cầu không cần nhiều, chỉ cần đủ để lấp hết tiến trình xử lý. Đây là loại mà website nhỏ hay gặp nhất, và cũng là loại bạn tự làm được nhiều nhất.

Cần phân biệt với hai hiện tượng dễ nhầm: một là bot thu thập dữ liệu chạy quá nhanh (chỉ cần điều tiết, không phải kẻ tấn công); hai là chính website của bạn thiếu bộ nhớ đệm nên chỉ vài trăm người truy cập cùng lúc đã đủ sập. Trường hợp thứ hai không cần chống tấn công, cần tối ưu.

Nhận biết: đọc dấu hiệu thay vì đoán

Dấu hiệu quan sát được Nghiêng về khả năng
Lưu lượng tăng, đơn hàng và thời gian ở lại trang cũng tăng theo Khách thật, cần tăng năng lực phục vụ
Lưu lượng tăng gấp nhiều lần nhưng chuyển đổi bằng không Bot hoặc tấn công
Yêu cầu dồn vào một đường dẫn duy nhất, nhiều tham số lạ Tấn công tầng ứng dụng
Cùng một chuỗi nhận dạng trình duyệt lặp lại hàng loạt Công cụ tự động
Rất nhiều kết nối ở trạng thái nửa mở Tấn công tầng kết nối
Tiến trình xử lý mã nguồn chiếm hết, cơ sở dữ liệu chờ khoá Đang bị bào bằng truy vấn nặng
Băng thông chạm trần trong khi số yêu cầu không tăng tương ứng Có tệp lớn đang bị tải lặp, hoặc ngập băng thông

Vài lệnh đọc tình hình nhanh trên máy chủ Linux:

# Đếm số kết nối theo trạng thái
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn
# Các đường dẫn bị gọi nhiều nhất trong nhật ký truy cập
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# Phân bố theo địa chỉ nguồn
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# Theo dõi tải và tiến trình theo thời gian thực
top -o %CPU

Ghi lại kết quả ngay lúc sự cố. Sau khi mọi thứ ổn định, nhật ký thường bị xoay vòng và bạn mất bằng chứng để rút kinh nghiệm.

Sáu lớp phòng thủ nên dựng sẵn

1. Đặt một lớp lọc đứng trước máy chủ

Đây là biện pháp có hiệu quả cao nhất và cũng dễ triển khai nhất. Một mạng phân phối nội dung hoặc dịch vụ lọc trung gian sẽ nhận lưu lượng thay bạn, hấp thụ phần rác ở tầng mạng và chỉ chuyển về máy chủ gốc phần yêu cầu hợp lệ. Với nhóm tấn công gây ngập băng thông, đây gần như là cách duy nhất khả thi cho website vừa và nhỏ.

Khi chọn, hãy nhìn vào ba năng lực cụ thể thay vì lời quảng cáo: có bật được chế độ kiểm tra trình duyệt cho toàn site không, có đặt được luật giới hạn tần suất theo đường dẫn không, và có cho xem nhật ký để bạn biết cái gì đã bị chặn không.

2. Không để lộ địa chỉ máy chủ gốc

Dựng lớp lọc phía trước mà địa chỉ máy chủ gốc vẫn công khai thì lưu lượng có thể đi vòng qua lớp lọc. Những chỗ hay làm lộ:

  • Bản ghi DNS cũ còn sót lại của tên miền con không dùng nữa.
  • Bản ghi phục vụ thư điện tử trỏ thẳng vào cùng máy chủ đặt website.
  • Thư do ứng dụng gửi đi mang tiêu đề chứa địa chỉ máy chủ.
  • Chứng chỉ bảo mật cấp cho tên miền nội bộ, tra được trong nhật ký minh bạch chứng chỉ công khai.

Việc cần làm kèm theo: cấu hình máy chủ web từ chối mọi yêu cầu không đi qua lớp lọc — hoặc bằng tường lửa chỉ chấp nhận dải địa chỉ của lớp lọc, hoặc bằng cách yêu cầu một tiêu đề bí mật. Không có bước này thì việc giấu địa chỉ chỉ là che mắt.

3. Bật bộ nhớ đệm toàn trang

Mỗi yêu cầu được trả từ bộ nhớ đệm là một yêu cầu không chạm tới mã nguồn và cơ sở dữ liệu. Khoảng cách giữa hai trường hợp thường là vài bậc độ lớn về tài nguyên tiêu tốn. Với website nội dung, bật bộ nhớ đệm toàn trang là biện pháp chống quá tải rẻ nhất mà lại có ích cả ngày thường.

Ba điểm cần chú ý: đặt thời gian sống của bản đệm đủ dài; loại trừ đúng các trang cần cá nhân hoá như giỏ hàng và tài khoản; và cẩn thận với việc đặt cookie trên mọi phản hồi, vì đó là lý do phổ biến khiến lớp đệm phía trước không bao giờ lưu được gì.

4. Tách tài nguyên tĩnh ra khỏi đường xử lý động

Ảnh, video, tệp CSS và JavaScript nên được phục vụ từ lớp phân phối nội dung với thời hạn lưu trữ dài, đặt tên tệp có gắn phiên bản để đổi nội dung thì đổi tên. Như vậy phần lớn số yêu cầu và phần lớn băng thông không bao giờ tới máy chủ gốc, và khi có sự cố thì máy chủ gốc chỉ còn phải lo phần động.

5. Giới hạn tần suất và giới hạn kết nối

Đây là tuyến phòng thủ tại chỗ, nên đặt ngay cả khi đã có lớp lọc phía trước. Nguyên tắc: mỗi nguồn chỉ được gọi một đường dẫn nhất định với tần suất hợp lý; vượt ngưỡng thì bị làm chậm rồi mới bị từ chối.

# Ví dụ cấu hình nginx: hai vùng đo, một cho toàn site, một cho trang đăng nhập
limit_req_zone  $binary_remote_addr zone=chung:10m   rate=10r/s;
limit_req_zone  $binary_remote_addr zone=dangnhap:10m rate=1r/s;
limit_conn_zone $binary_remote_addr zone=ketnoi:10m;
server {
    # Cho phép bùng ngắn hạn, không trả lỗi ngay
    limit_req  zone=chung burst=20 nodelay;
    limit_conn ketnoi 20;
    client_body_timeout   10s;
    client_header_timeout 10s;
    send_timeout          10s;
    location = /wp-login.php {
        limit_req zone=dangnhap burst=5 nodelay;
    }
}

Đặt ngưỡng bằng cách đo lưu lượng ngày thường trước, rồi lấy mức đỉnh nhân lên vài lần. Ngưỡng quá chặt sẽ chặn nhầm khách thật và cả bot của công cụ tìm kiếm. Sau khi bật, hãy theo dõi nhật ký vài ngày để chỉnh lại.

6. Khoá bớt các điểm tốn tài nguyên

  • Trang tìm kiếm nội bộ: yêu cầu độ dài từ khoá tối thiểu, đặt giới hạn tần suất riêng, và đệm kết quả cho các từ khoá phổ biến.
  • Giao diện lập trình cũ không dùng tới: tắt hẳn thay vì để mở.
  • Trang đăng nhập và trang quản trị: giới hạn theo địa chỉ nguồn nếu được, bật xác thực nhiều bước, đặt độ trễ tăng dần sau mỗi lần sai.
  • Các đường dẫn sinh tệp nặng theo yêu cầu như xuất báo cáo hay tạo ảnh động: đưa vào hàng đợi xử lý nền và yêu cầu đăng nhập.
  • Chức năng gửi thư từ biểu mẫu công khai: thêm bước xác thực người dùng và giới hạn số lần gửi.

Chuẩn bị trước để không phải xoay xở lúc đang cháy

  1. Hạ TTL của các bản ghi DNS quan trọng xuống mức thấp và giữ như vậy. Khi cần chuyển hướng lưu lượng khẩn cấp, TTL cao sẽ trói bạn hàng giờ.
  2. Giám sát từ bên ngoài với cảnh báo qua kênh bạn thật sự đọc. Biết sớm 10 phút là khác biệt lớn.
  3. Viết sẵn sổ tay xử lý: ai làm gì, đăng nhập ở đâu, bật chế độ phòng thủ ở đâu, số liên hệ của nhà cung cấp hạ tầng.
  4. Chuẩn bị sẵn trang tĩnh dự phòng chỉ gồm HTML và thông tin liên hệ, có thể bật lên khi cần chịu tải mà không cần cơ sở dữ liệu.
  5. Kiểm tra bản sao lưu bằng cách khôi phục thử. Bản sao lưu chưa từng khôi phục không tính là bản sao lưu.
  6. Biết trần chịu tải của mình: chạy một phép đo tải trên môi trường thử nghiệm của chính bạn để biết ngưỡng gãy nằm ở đâu.

Khi đang bị tấn công: thứ tự thao tác

  1. Xác nhận đúng hiện tượng. Xem nhật ký và số kết nối, phân biệt quá tải do khách thật hay do lưu lượng rác. Xử lý sai hướng còn tệ hơn không xử lý.
  2. Bật mức phòng thủ cao nhất ở lớp lọc phía trước, ví dụ chế độ kiểm tra trình duyệt cho toàn bộ website. Chấp nhận phiền phức cho khách trong vài giờ để giữ dịch vụ sống.
  3. Thu hẹp mục tiêu. Nếu áp lực dồn vào một vài đường dẫn, tạm khoá hoặc trả về bản tĩnh cho đúng những đường dẫn đó thay vì chặn cả site.
  4. Tăng tỷ lệ phục vụ từ bộ nhớ đệm, kể cả bằng cách kéo dài thời gian sống của bản đệm tạm thời.
  5. Liên hệ nhà cung cấp hạ tầng. Họ nhìn được tầng mạng mà bạn không nhìn được và có thể chặn giúp ở phía trên.
  6. Ghi lại toàn bộ. Thời điểm bắt đầu, đặc điểm lưu lượng, thao tác đã làm và tác dụng của từng thao tác.
  7. Sau khi yên, gỡ dần các biện pháp khẩn cấp và giữ lại những gì đáng giữ. Đừng để chế độ kiểm tra gắt chạy mãi rồi quên.

Hai điều tuyệt đối không làm: không trả đũa dưới bất kỳ hình thức nào — đó là hành vi vi phạm pháp luật và không làm lưu lượng vào bạn giảm đi; và không đổi tên miền hay đổi máy chủ trong lúc hoảng loạn, vì bạn sẽ tự tạo thêm một sự cố mới chồng lên sự cố đang có.

Vệ sinh nền tảng: phần ít hào nhoáng nhưng cứu bạn nhiều nhất

  • Cập nhật hệ quản trị nội dung và các trình cắm. Phần lớn website nhỏ “sập” không phải vì bị nhắm mục tiêu, mà vì bị quét lỗ hổng hàng loạt.
  • Gỡ trình cắm và giao diện không dùng, thay vì chỉ tắt.
  • Bật HTTPS trên toàn bộ website và bảo đảm gia hạn chứng chỉ tự động chạy đều — xem Hướng dẫn lấy chứng chỉ SSL Let’s Encrypt.
  • Tách môi trường thử nghiệm khỏi môi trường chạy thật, và chặn truy cập công khai vào môi trường thử nghiệm.
  • Giữ cấu hình DNS gọn: xoá bản ghi cũ, biết chính xác mỗi bản ghi đang trỏ về đâu. Nếu bạn vừa chuyển hosting, đối chiếu lại theo Hướng dẫn trỏ tên miền về Hosting cPanel.

Kết

Chống tấn công từ chối dịch vụ ở quy mô website vừa và nhỏ không nằm ở một sản phẩm đắt tiền, mà ở việc dựng sẵn nhiều lớp: một lớp lọc đứng trước, máy chủ gốc không lộ và chỉ nhận lưu lượng từ lớp đó, bộ nhớ đệm toàn trang, tài nguyên tĩnh tách riêng, giới hạn tần suất và kết nối, cùng vài điểm nóng được khoá bớt. Phần lớn công việc phải làm trước khi có sự cố; lúc sự cố chỉ còn là bật thứ đã chuẩn bị và ghi chép lại.

Nếu bạn đang dựng lại hạ tầng cho một dự án và muốn bắt đầu bằng phần gốc — tên miền của chính bạn, DNS sửa được ngay khi cần chuyển hướng khẩn cấp — hãy tra và đăng ký tại ivi.vn/search.