IPTABLES - Tốc độ giới hạn của một IP đến cụ thể


103

Tôi không muốn giới hạn tỷ lệ của một dịch vụ cụ thể. Mục tiêu của tôi là giới hạn tốc độ chỉ dựa trên địa chỉ IP đến. Ví dụ: sử dụng quy tắc giả:

john.domain.local (192.168.1.100) can only download from our httpd/ftp servers at "10KB/s" (instead of 1MB/s)

Làm cách nào tôi có thể xếp hạng giới hạn bằng IPTables dựa trên địa chỉ IP đến?

Câu trả lời:


165

IPTables không được thực hiện cho loại công việc này, trong đó rất nhiều gói cần phải được phân tích để đưa ra các quyết định này. IPTables là một phần câu trả lời mặc dù!

Câu trả lời thực sự cho điều này là các phương tiện kiểm soát lưu lượng tuyệt vời và chưa được sử dụng trong Linux. Lưu ý rằng việc lén lút với điều này mà không biết chuyện gì đang xảy ra có thể dẫn đến việc bạn mất kết nối mạng với máy! Bạn đã được cảnh báo!

Giả sử eth0 là thiết bị gửi đi, bạn sẽ cần tạo một hàng đợi kiểm soát lưu lượng dựa trên lớp, theo mặc định sẽ xuất ra hầu hết lưu lượng truy cập thông qua hàng đợi 'nhanh' và đưa một danh sách người cụ thể vào hàng đợi 'chậm'.

Cái hay của việc này là bạn có thể tạo một tình huống trong đó bạn cho phép nhiều lưu lượng truy cập đi ra cho người dùng chậm trừ khi lớp ghi đè muốn băng thông, nhưng ví dụ này không làm được điều này (sẽ luôn cung cấp 10kbps cho người dùng chậm). Hệ thống xếp hàng sẽ trông giống như thế này:

                         Inbound traffic
                              +
                              |
                              |
                              v
                     +------------------+
                     |   Class 1:1      |
                     |------------------|
                     |  Root (all flows)|
                     |       100mbit    |
                     +-----+-----+------+
                           |     |
                           |     |
                           |     |
                           |     |
                           |     |
          +----------+     |     |     +----------+
          |    1:11  +-----+     +-----+    1:12  |
          |----------|                 |----------|
          | Default  |                 | Slow     |
          |100mb-80kb|                 |   80kb   |
          +----------+                 +----------+

Để làm điều này, trước tiên bạn sẽ cần thiết lập kỷ luật xếp hàng trong kernel. Sau đây sẽ làm điều này cho bạn .. bạn phải chạy nó dưới dạng toàn bộ một tập lệnh

#!/bin/bash
tc qdisc add dev eth0 parent root handle 1: hfsc default 11
tc class add dev eth0 parent 1: classid 1:1 hfsc sc rate 100mbit ul rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:11 hfsc sc rate 99920kbit ul rate 100000kbit
tc class add dev eth0 parent 1:1 classid 1:12 hfsc sc rate 80kbit ul rate 80kbit

tc qdisc add dev eth0 parent 1:11 handle 11:1 pfifo
tc qdisc add dev eth0 parent 1:12 handle 12:1 pfifo

"11 mặc định" rất quan trọng vì nó cho kernel biết phải làm gì với lưu lượng không được phân loại.

Khi điều này được thực hiện, bạn có thể thiết lập quy tắc iptables để phân loại các gói phù hợp với một tiêu chí nhất định. Nếu bạn có kế hoạch đưa nhiều và nhiều người vào quy tắc chậm này, quy tắc ipset sẽ phù hợp hơn (nên có sẵn trên rrc6 tôi tin).

Vì vậy, hãy tạo cơ sở dữ liệu ipset để thực hiện so khớp với ...

ipset create slowips hash:ip,port

Sau đó tạo quy tắc iptables để thực hiện khớp ..

iptables -t mangle -I OUTPUT -m set --match-set slowips dst,src -j CLASSIFY --set-class 1:12

Điều này hướng dẫn kernel rằng nếu bạn khớp IP đích với cổng nguồn từ tập hợp, hãy phân loại nó thành hàng đợi chậm mà bạn thiết lập với điều khiển lưu lượng.

Bây giờ, cuối cùng bất cứ khi nào bạn muốn làm chậm IP, bạn có thể sử dụng lệnh ipset để thêm ip vào tập hợp như sau:

ipset add slowips 192.168.1.1,80
ipset add slowips 192.168.1.1,21
...

Bạn có thể kiểm tra nó hoạt động bằng lệnh "lớp tc -s show dev eth0" và bạn sẽ thấy các số liệu thống kê trong đó cho biết các gói được chuyển hướng đến hàng đợi chậm.

Lưu ý nhược điểm thực sự duy nhất của việc này là làm cho nó sống sót khi khởi động lại. Tôi không nghĩ rằng có bất kỳ tập lệnh init nào có sẵn để tạo ipsets từ các lần đổ khi khởi động lại (và chúng cũng phải được tạo trước quy tắc iptables) và tôi chắc chắn không có tập lệnh init nào để thiết lập lại quy tắc kiểm soát lưu lượng khi khởi động lại. Nếu bạn không bận tâm, bạn chỉ có thể tạo lại toàn bộ từ việc gọi một tập lệnh trong RC.local.


3
Vâng, tôi không thể cảm ơn bạn đủ. Điều này là rất mô tả và rất nhiều thông tin. Sau đó tôi nhận ra rằng kiến ​​thức về TC sẽ được yêu cầu và tôi đã bắt đầu xem xét điều này. Cảm ơn một lần nữa!
James

Oh và như mất kết nối. Tôi chắc chắn rằng tôi đã giảm cấu hình trước khi chuyển từ VPS sang máy chủ. Ngoài ra, tôi có quyền truy cập VPN vào mạng riêng trên ETH0. Tôi sẽ chỉ làm việc trên ETH1 vì vậy về lý thuyết tôi sẽ không gặp vấn đề gì. Nhưng nghe cảnh báo!
James

2
Tôi không thể nói với bạn bao nhiêu lần tôi đã đọc các hướng dẫn tương tự, đây là lần đầu tiên có ý nghĩa
RC1140

5
Là một sidenote, thông thường thích hợp hơn để thực hiện giới hạn tài nguyên như thế này trong các nhóm kiểm soát (một lần nữa, cũng có thể và cũng không được sử dụng và tuyệt vời) khi bạn có thể xác định giới hạn cho mỗi ứng dụng trên cpu, bộ nhớ, IO và mạng trong kho chính sách tập trung '. Nhưng vẫn chưa thấy một câu hỏi như vậy được đặt ra để đưa ra một câu trả lời.
Matthew Ife

2
Nếu bạn không thích những tccú pháp bạn có thể cung cấp cho tcng thử mà thêm ngôn ngữ thân thiện với người sử dụng nhiều hơn một chút mà tạo ra tclệnh. Tôi đã từng thích điều này trong shell script : echo '... multi line tcng configuration ...' | tcng | sh.
Mattias Wadman

5

Nó đơn giản như thực hiện quy tắc giới hạn tỷ lệ và thêm công -stắc. Công -stắc phù hợp với IP đến. Ví dụ iptables -A INPUT -s 1.1.1.1và sau đó kết thúc với phương pháp giới hạn tỷ lệ ưa thích của bạn cho quy tắc đó.


Cảm ơn bạn đã trả lời nhanh chóng của bạn. Thật không may, vấn đề chính của tôi là nửa thứ hai. Tôi đã xem xét --limit và tôi chưa thấy bất cứ điều gì cho phép tôi giới hạn dựa trên KB / s - bất kỳ hướng nào bạn có thể chỉ cho tôi?
James

1
@ James Tôi sẽ quay lại với bạn nhưng tôi phải bước ra nhà của một người bạn. Chỉ cần quay lại và tôi thấy rằng MIfe đã hoàn thành một công việc. =)
Wesley
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.