Giới hạn kết nối tối đa trên mỗi địa chỉ IP và kết nối mới mỗi giây với iptables


37

Chúng tôi có máy chủ Ubuntu 12.04 với httpd trên cổng 80 và chúng tôi muốn giới hạn:

  • các kết nối tối đa trên mỗi địa chỉ IP tới httpd đến 10
  • các kết nối mới tối đa mỗi giây đến httpd đến 150

Làm thế nào chúng ta có thể làm điều này với iptables?

Câu trả lời:


48
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset  

Điều này sẽ từ chối các kết nối trên 15 từ một IP nguồn.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT  

Trong 160 kết nối mới này (các gói thực sự) được cho phép trước khi giới hạn 150 kết nối MỚI (gói) mỗi giây được áp dụng.


1
Ở trên có thể được thiết lập để làm việc trên tất cả các cổng, không chỉ cổng 80?
EminezArtus 7/03/2015

1
Bạn có chắc chắn đây là trên mỗi IP?
LatinSuD

2
Để đặt quy tắc này cho tất cả các cổng, chỉ cần xóa --dport 80.
Dan Pritts

5
Quy tắc thứ hai KHÔNG hoạt động trên "các kết nối mới". Nó rõ ràng ảnh hưởng đến các kết nối hiện có ("THÀNH LẬP"). Để thực hiện các kết nối mới, bạn sẽ muốn --state MỚI. Bạn cũng có thể xem xét sử dụng -m conntrack --ctstatethay thế -m state --state. conntrack là mới và được cải thiện so với nhà nước.
Dan Pritts

2
nhận xét ở trên để thêm quy tắc thứ 2 vào các NEWkết nối - đừng làm vậy - nó thực sự biến INPUTchuỗi của bạn thành mặc định accept!!!
Stuart Cardall

8

Bạn muốn các quy tắc sau trong iptables của mình để trả lời cả hai yêu cầu trong câu hỏi của bạn:

iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT

iptables -t filter -I INPUT -p tcp --dport 80 -m state \
  --state RELATED,ESTABLISHED -j ACCEPT

# Adjust "--connlimit-above NN" to limit the maximum connections per IP
#   that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 10 --connlimit-mask 32 -j DROP

# Adjust "--connlimit-above NNN" to the maximum total connections you
#   want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 150 -j DROP

Bởi vì chúng tôi đang sử dụng -I (theo yêu cầu của OP), chúng tôi phải thực hiện chúng theo thứ tự ngược lại để 'đọc' chúng từ dưới lên.

Tôi cũng đề nghị xem xét thay đổi --connlimit-mask NN thay đổi từ 32 thành 24. Điều này sẽ giới hạn toàn bộ mạng Class-C (tối đa 256 địa chỉ IP trong cùng phạm vi) ở 10 kết nối. Bạn cũng có thể sử dụng bất kỳ số không có lớp nào khác như 22 hoặc 30 tùy thuộc vào cách bạn nghĩ rằng dịch vụ của bạn có thể được sử dụng.

Ngoài ra, tùy thuộc vào cách bạn muốn ứng dụng khách hoạt động, bạn có thể muốn sử dụng "-j RE DỰ ÁN - từ chối-với tcp-reset" thay vì "-j DROP" trong hai quy tắc trên hoặc thậm chí chỉ trong tối đa 150 kết nối qui định.

Nếu bạn THAM KHẢO kết nối trình duyệt hoặc phần mềm sử dụng cổng 80 sẽ hiển thị trạng thái "không khả dụng" ngay lập tức, nhưng tùy chọn DROP sẽ khiến máy khách phải chờ và thử lại một vài lần trước khi báo cáo trang web là không khả dụng. Tôi có xu hướng nghiêng về DROP vì nó hoạt động giống như một kết nối xấu hơn là một máy chủ ngoại tuyến.

Ngoài ra, nếu giới hạn kết nối giảm xuống dưới 150 (hoặc 10) trong khi nó vẫn đang thử lại, thì cuối cùng nó sẽ thông qua máy chủ của bạn.

Tuy nhiên, tùy chọn RE DỰ ÁN sẽ khiến lưu lượng truy cập ít hơn đến trang web của bạn, vì DROP sẽ khiến nó gửi các gói bổ sung trong khi thử lại. Có lẽ không phải tất cả những gì có liên quan.

Mặt khác, nếu lưu lượng truy cập cổng 80 của bạn là một phần của cụm thì RE DỰA sẽ thông báo cho bộ điều khiển cụm rằng nó ngừng hoạt động và dừng gửi lưu lượng đến nó trong thời gian chờ thử lại.

Quy tắc LIÊN QUAN, THÀNH LẬP có ở đó với giả định quy tắc mặc định của bạn là chặn tất cả lưu lượng truy cập (bộ lọc iptables -t -P INPUT DROP). Điều này chỉ chấp nhận các gói xa hơn thuộc về các kết nối được chấp nhận.

Ngoài ra --syn bảo nó chú ý đến (hoặc đếm) các gói thiết lập kết nối TCP.


Cảm ơn bạn đã đi qua các chi tiết nhỏ của các lệnh này.
txyoji

Tôi có thể lấy --connlimit-mask để chỉ chặn địa chỉ IP cụ thể đó chứ không phải toàn bộ phạm vi không?
Tương tự

--Connlimit-mask 32 một giới hạn địa chỉ. Tức là, nó giống như một / 32 netmask. Bất cứ điều gì ít hơn, như 24 giống như một / 24 netmask, bỏ qua 8 bit thấp hơn.
Ian Macintosh

5

Bạn cần sử dụng các connlimitmô-đun cho phép bạn hạn chế số lượng kết nối TCP song song với máy chủ trên mỗi địa chỉ IP của máy khách (hoặc khối địa chỉ).

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP

Tôi đã cập nhật câu trả lời của bạn, tôi hy vọng nó vẫn ổn (tại sao "--syn" lại cần thiết?). + Và làm thế nào về "Kết nối tối đa mỗi giây (cổng 80, tcp) đến 150"? Cảm ơn bạn!
evachristine

--syn có nghĩa là quy tắc chỉ nhìn vào các gói TCP với cờ syn - có nghĩa là các kết nối mới. Bạn có thể thực hiện tương tự với trạng thái -m --state MỚI, nhưng điều này có thể nhanh hơn.
Dan Pritts
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.