Module connlimit cho phép quản lí số lượng kết nối đồng thời (concurrent connections) đến server hoặc rời đi từ server.

Để xem các options có thể sử dụng:

# iptables -m connlimit --help
...
connlimit match options:
  --connlimit-upto n     match if the number of existing connections is 0..n
  --connlimit-above n    match if the number of existing connections is >n
  --connlimit-mask n     group hosts using prefix length (default: max len)
  --connlimit-saddr      select source address for grouping
  --connlimit-daddr      select destination addresses for grouping

I. Mô hình demo:

, trong đó:

  • Server: có IP 10.10.10.100
  • client1: có IP 10.10.10.200
  • client2: có IP 10.10.10.250

Để demo, tại Server tôi sử dụng socat để tạo listening socket đóng vai trò như một ứng dụng chấp nhận kết nối trên port 2001:

socat TCP-LISTEN:2001,bind=10.10.10.100,fork,reuseaddr SYSTEM:'while true; do echo port 2001 - connected...; sleep 1 ; done'

Từ client sử dụng nc (netcat) hoặc telnet kết nối đến port 2001:

telnet 10.10.10.100 2001

Kết quả khi client có thể mở kết nối đến server:

Sau đó, có thể Ctrl + c để ngắt kết nối, hoàn tất việc chuẩn bị.

II. Giới hạn số lượng kết nối đồng thời:

Trên Server, mở 3 ports 2001-2003:

socat TCP-LISTEN:2001,bind=10.10.10.100,fork,reuseaddr SYSTEM:'while true; do echo port 2001 - connected...; sleep 1 ; done' &
socat TCP-LISTEN:2002,bind=10.10.10.100,fork,reuseaddr SYSTEM:'while true; do echo port 2002 - connected...; sleep 1 ; done' &
socat TCP-LISTEN:2003,bind=10.10.10.100,fork,reuseaddr SYSTEM:'while true; do echo port 2003 - connected...; sleep 1 ; done' &

Server đã sẵn sàng kết nối trên 3 ports:

Giả sử tôi phải thực hiện các yêu cầu sau:

  • Yêu cầu 1: Port 2001, mỗi client được phép mở tối đa 1 kết nối cùng lúc
  • Yêu cầu 2: Port 2002, mỗi client được phép mở tối đa 2 kết nối cùng lúc
  • Yêu cầu 3: Port 2003, tại một thời điểm server chấp nhận 3 kết nối từ clients

Tôi bắt đầu phần tích và viết iptabes rule cho từng yêu cầu một.

* Yêu cầu 1: Port 2001, mỗi client được phép mở tối đa 1 kết nối cùng lúc, ta cần phân tích:
  • Xét những gói tin mở kết nối tcp đến server: -t raw PREROUTING -d 10.10.10.100/32 -p tcp --syn
  • Xét trên port 2001: --dport 2001
  • Xét những gói tin đến Server, mỗi source IP có tối đa 1 kết nối: -m connlimit --connlimit-above 1 --connlimit-mask 32 --connlimit-saddr -j DROP

Chạy lệnh trên Server:

iptables -t raw -A PREROUTING -d 10.10.10.100/32 -p tcp --syn --dport 2001 -m connlimit --connlimit-above 1 --connlimit-mask 32 --connlimit-saddr -j DROP

Kiểm chứng:

  • Client1 chỉ có thể mở một kết nối, kết nối thứ hai không thành công:
  • Client2, tương tự chỉ có thể mở một kết nối:
  • Giới hạn 1 kết nối chỉ áp dụng với port 2001 và không ảnh hưởng các port khác. Ví dụ client2 có thể mở thêm kết nối đến port 2002:

* Yêu cầu 2: Port 2002, mỗi client được phép mở tối đa 2 kết nối cùng lúc
  • Xét những gói tin mở kết nối tcp đến server: -t raw PREROUTING -d 10.10.10.100/32 -p tcp --syn
  • Chỉ áp dụng đối với port 2002: --dport 2001
  • Xét những gói tin đến Server, mỗi source IP có tối đa 1 kết nối: -m connlimit --connlimit-above 2 --connlimit-mask 32 --connlimit-saddr -j DROP

Chạy lệnh trên Server:

iptables -t raw -A PREROUTING -d 10.10.10.100/32 -p tcp --syn --dport 2002 -m connlimit --connlimit-above 2 --connlimit-mask 32 --connlimit-saddr -j DROP

Kiểm chứng:

  • Một client chỉ được mở tối đa 2 kết nối cùng lúc:
  • Giới hạn 2 kết nối chỉ áp dụng với port 2002.

* Yêu cầu 3: Port 2003, tại một thời điểm server chấp nhận 3 kết nối từ clients
  • Chỉ áp dụng đối với port 2003: --dport 2001
  • Xét những gói tin đến Server, server chỉ chấp nhận 2 kết nối từ client bất kì, vì thế tôi cần giới hạn trên destination IP sử dụng --connlimit-daddr mode : -m connlimit --connlimit-above 3 --connlimit-mask 32 --connlimit-daddr -j DROP

Chạy lệnh trên Server:

iptables -t raw -A PREROUTING -d 10.10.10.100/32 -p tcp --syn --dport 2003 -m connlimit --connlimit-above 3 --connlimit-mask 32 --connlimit-daddr -j DROP

Kiểm chứng:

  • Client1 mở 2 kết nối thành công, Client2 mở thêm kết nối thứ thứ 3 thành công. Sau đó, Server bắt đầu từ chối kết nối thứ tư:

III Ứng dụng khác:

Vì lí do độ dài, một số lưu ý và kinh nghiệm khác không được đề cập. Đọc giả có thể tham khảo thêm và vận dụng:

  • Tôi chỉ demo giới hạn các gói tin đến Server, trường hợp khác đọc giả vẫn có thể sử dụng module connlimit để giới hạn kết nối chiều OUT từ Server ra ngoài.
  • Tôi dùng --connlimit-above và target -j DROP, đọc giả có thể sử dụng --connlimit-upto tùy vào bối cảnh. Ví dụ, yêu cầu số 2 tôi viết lại với policy DROP:
iptables -t raw -A PREROUTING -d 10.10.10.100/32 -p tcp --syn --dport 2002 -m connlimit --connlimit-upto 2 --connlimit-mask 32 --connlimit-saddr -j ACCEPT
iptables -t raw -A PREROUTING -d 10.10.10.100/32 -p tcp --dport 2002 -j DROP
  • Mặc định, option --connlimit-mask 32 sẽ áp dụng giới hạn cho một IP, bạn có thể áp dụng giới hạn cho cả một network. Ví dụ, yêu cầu số 1 được viết lại:
iptables -t raw -A PREROUTING -d 10.10.10.100/32 -p tcp --syn --dport 2001 -m connlimit --connlimit-above 1 --connlimit-mask 24 --connlimit-daddr -j DROP

Khi IP bất kì 192.168.1.5 kết nối đến Server, giới hạn sẽ apply cho cả network 192.168.1.0/24, các IP trong range này sẽ không thể mở kết nối thứ hai.

Thông qua các ví dụ, hi vọng đọc giả cảm thấy thoải mái hơn khi ứng dụng của module connlimit để đáp ứng các nhu cầu riêng trong quản trị.

Comments

  1. phucvm

    Ở đây em thấy a dùng table raw và chain PREROUTING. Tại sao mình không dùng filter và INPUT để chạy ạ? Vì đây là connect vào server. Vậy có thể dùng INPUT được không anh?

    1. thuc.doan@vietnix.com.vn Article Author

      chào bạn phucvm,

      Packets traveling qua chain PREROUTING trước. Sau đó, routing decision dựa trên destination IP để quyết định packet sẽ tiếp tục qua chain INPUT hay FORWARD.
      Mình đặt rule tại table raw chain PREROUTING với lí do:
      – Mình cầu toàn một ít hiệu suất, mình muốn packets được filter càng sớm càng tốt.
      – Trường hợp destination IP của gói tin đến chính server thì rule phải đặt ở chain INPUT. Nếu server đóng vai trò forward gói tin sang host khác (NAT) thì rule phải đặt tại chain FORWARD. Do đó, nếu mình đặt rule(s) tại PREROUTING thì sẽ match được cả hai.

      Tất nhiên, bạn có thể đặt rule tại nơi phù hợp không nhất thiết phải raw – PREROUTING.

Leave a Reply

Your email address will not be published. Required fields are marked *