Giới hạn tốc độ theo yêu cầu trong Apache là không dễ dàng, nhưng cuối cùng tôi đã tìm ra một cách thỏa đáng để làm việc đó bằng cách sử dụng mod-an ninh Apache module. Chúng tôi đang sử dụng nó ở Brightbox để ngăn chặn kịch bản lỗi rửa dịch vụ siêu dữ liệu của chúng tôi. Đặc biệt, chúng tôi cần khả năng e thứ để cho phép sự bùng nổ cao của yêu cầu ban đầu, vì đó là mô hình sử dụng bình thường của chúng tôi. Vì vậy, đây là cách để làm điều đó.
Cài đặt mod-an ninh (trên Debian / Ubuntu, chỉ cần cài đặt gói libapache2-ModSecurity) và cấu hình nó trong định nghĩa máy chủ ảo của bạn như thế này:
SecRuleEngine Mở
SecAction initcol: ip =% {REMOTE_ADDR}, vượt qua, nolog
SecAction “giai đoạn: 5, deprecatevar: ip.somepathcounter = 1/1, vượt qua, nolog”
SecRule IP: SOMEPATHCOUNTER “gt 60” “giai đoạn: 2, tạm dừng: 300, phủ nhận, tình trạng: 509, setenv: RATELIMITED, bỏ qua: 1, nolog”
SecAction “giai đoạn: 2, vượt qua, setvar: ip.somepathcounter = + 1, nolog”
Tiêu đề luôn luôn đặt Thử lại-Sau khi “10” env = RATELIMITED
LocationMatch>
ErrorDocument 509 “Tỷ lệ vượt quá giới hạn”
Điều này làm một số việc và đã có một vài nút bấm để bạn có thể tinh chỉnh tùy theo yêu cầu của bạn. Các SecAction đầu tiên khởi nhà nước, trong trường hợp này theo địa chỉ IP. Bạn có thể làm điều này bằng một cookie nếu bạn thích, nhưng tôi cần nó được thực hiện bởi địa chỉ IP (nếu bạn đang sử dụng một proxy đảo ngược của một số loại sau đó nhận được IP từ các tiêu đề X-Forwarded-For ở đây thay vì).
Các SecAction thứ hai được tán thành sự sắc bén của 1 mỗi 1 giây. Đây là thiết lập các lãi suất cơ bản của giới hạn tốc độ của chúng tôi, mỗi thứ hai. Tôi đã đặt tên cho truy cập somepathcounter ở đây, cảm thấy tự do để gọi nó là những gì bạn muốn và sử dụng các tên khác nhau cho các mức giá khác nhau hạn chế phần khác nhau của trang web của bạn.
Kiểm tra SecRule để xem nếu truy cập được greather hơn 60 và nếu như vậy nó ngủ 300ms, thiết lập biến môi trường RATELIMITED và trả về một đáp ứng 509 mã. Đây là thiết lập tốc độ chụp của giới hạn tốc độ của chúng tôi, đến 60 Bất kỳ IP có thể làm bùng nổ của 60 yêu cầu nhanh như nó thích và sau đó nó giới hạn 1 mỗi giây. Nếu nó làm cho không có yêu cầu thêm trong 60 giây sau đó truy cập được giảm về 0, có nghĩa là bùng nổ của họ đã được sạc đầy đủ.
Các SecAction cuối cùng gia số truy cập cho mọi yêu cầu thành công (các SecRule trước bỏ qua dòng này nếu yêu cầu được tốc độ giới hạn).
Sau đó, định nghĩa tiêu đề đảm bảo một tiêu đề được thiết lập bất cứ khi nào một yêu cầu là tỷ lệ hạn chế, đưa ra một gợi ý cho khách hàng rằng họ không nên thử lại trong 10 giây. Điều này rõ ràng chỉ là một hướng dẫn và rất nhiều khách hàng không thực hiện nó (và nó thực sự chỉ có giá trị trên một trạng thái 503 anyway) do đó, nó là một chút mơ tưởng thực sự.
Sau đó, chúng ta định nghĩa một ErrorDocument gọn gàng cho các phản ứng 509 để cung cấp cho một đầu mối tốt hơn cho khách hàng về những gì đang xảy ra.
Đáp ứng 509 HTTP
Tôi đã chọn để sử dụng mã 509 HTTP mà không phải là một tiêu chuẩn (riêng của nó “Giới hạn vượt quá Bandwidth” mã Apache). Về mặt kỹ thuật một 503 (với tiêu đề Retry-Sau) có lẽ là một lựa chọn tốt hơn nhưng tôi đã sử dụng 503 cho các trang bảo trì và tôi muốn phân biệt giữa hai câu trả lời trong các bản ghi. Twitter đã phát minh ra tình trạng của mình 420 “Tăng cường lặng của bạn” mã, nhưng điều đó dường như là một tài liệu tham khảo chủ yếu là cần sa phức tạp. RFC 6586 định nghĩa 429: “Quá nhiều yêu cầu” cho mục đích này nhưng nó rất mới và Apache sẽ không cho phép bạn thiết lập một ErrorDocument cho nó chưa. Và nó gây tranh cãi cho dù đây là một chế độ lỗi 4xx hay một chế độ lỗi 5xx.
dữ liệu nhà nước mod-an ninh
mod-an ninh cần phải lưu trữ các trạng thái giới hạn tỷ lệ giữa khởi động lại, do đó bạn cần phải nói cho nó nơi để ghi dữ liệu đó. Tôi tạo ra một thư mục trong thư mục / var / lib / mod-an ninh, nhưng bạn chỉ có thể dính nó vào / tmp nếu bạn thích:
SecDataDir / tmp
Nếu bạn không xác định này, mod-an ninh chỉ có vẻ âm thầm không áp dụng các giới hạn tốc độ, vì vậy bạn cần nó ngay cả khi bạn không quan tâm về tình trạng giữa khởi động lại.
Nó không xuất hiện có thể lưu trữ nhà nước mod-an ninh trong một cơ sở dữ liệu được chia sẻ nên bạn không thể đánh giá chính xác giới hạn khi bạn có nhiều máy chủ web tải cân bằng.
Sleeping được coi là xấu
Việc thực hiện này ngủ 300ms theo yêu cầu khi tỷ lệ đã bị vượt quá, nhưng ngủ ở đây thường không phải là một ý tưởng tuyệt vời. Nó quan hệ lên người lao động Apache trong suốt thời gian của giấc ngủ, vì vậy trong khi nó sẽ làm giảm tải trên ứng dụng phụ trợ của bạn (mà nếu không có khả năng sẽ sử dụng rất nhiều CPU) nó cho là làm cho nó dễ dàng hơn để buộc tất cả các công nhân của Apache và đưa trang web của bạn offline.
Có nhiều cách dễ dàng hơn để buộc lên một máy chủ web mặc dù, và không có một giấc ngủ nhiều khách hàng sẽ chỉ ngay lập tức thử lại yêu cầu, gửi thư rác các bản ghi bằng các thông báo và sử dụng HTTP phân tích cpu vv Và không có giới hạn tốc độ ở tất cả, ứng dụng của bạn có thể là thậm chí còn chậm hơn và có thể buộc mọi thứ chỉ dễ dàng. Vì vậy, cảm thấy tự do để điều chỉnh này theo ý muốn.
Về cơ bản, hãy nhớ rằng đây không phải là từ chối độc hại của hệ thống dịch vụ bảo vệ – chúng tôi chỉ sử dụng nó thực thi một chính sách cơ bản, thông thường nhất do vi phạm một sai lầm chứ không phải là một cuộc tấn công.
các tùy chọn khác
mod_cband âm thanh khá tốt, nhưng tôi không thể tìm thấy tài liệu hướng dẫn làm thế nào để đánh giá các yêu cầu giới hạn, chỉ cần băng thông, và nó không được đóng gói dành cho Debian / Ubuntu.
mod_evasive âm thanh như một cái gì đó bạn có thể muốn sử dụng để bảo vệ DoS.
Nếu bạn đang sử dụng nginx sau đó các mô-đun HTTP hạn req âm thanh tốt đẹp và đơn giản.
Hashlimit khớp Netfilter là rất mạnh mẽ và có được lợi ích của một lớp trước khi Apache hoàn toàn, vì vậy bạn có thể tiết kiệm chu kỳ CPU nhiều hơn. Netfilter cũng có khả năng để đánh giá giới hạn khai thác gỗ quá, vì vậy bạn sẽ không phải điền vào đĩa cứng của bạn có phần vô dụng. Nếu bạn muốn trả lại một phản ứng 509, thay vì chỉ thả hay từ chối các gói SYN, sau đó bạn có thể chuyển hướng kết nối giới hạn tỷ lệ để một máy chủ ảo Apache mà chỉ cần trả về 509s (đặt nó trên một cổng khác nhau và sử dụng các mục tiêu DNAT Netfilter).