IP ile Linux'ta trafik şekillendirmeyi nasıl yapabilirim?


16

Şeffaf bir proxy kurulumumuz var. Linux'ta trafik şekillendirme aramaya çalıştım ve çevrimiçi bulabildiğim tek şey trafiği arayüze (eth0 / eth1 ...) sınırlamaktı.

IP adresini veya IP aralıklarını (asla belirli bir sınırı aşan) bant genişliği sınırlamak gerekir ve bunu yapmak için bir yol bulamıyorum.

Bunu yapmanın bir yolu var mı?

Yanıtlar:


18

Çekirdeğin trafik şekillendirme katmanı, temel olarak, ağ kartınıza bağlı bir paket zamanlayıcıdır. Dolayısıyla, bir trafik şekillendirme politikası bir ağ kartı için geçerlidir.

Sizin durumunuzda yapabileceğiniz şey, ekli bir IP ve bant genişliği listesi oluşturmaktır ve ardından her bir IP için şunları yaratırsınız:

  • Sınıf kimliği tarafından tanımlanan bir trafik şekillendirme kuralı
  • Paketleri belirli bir işaret değerine işaretleyecek bir netfilter kuralı
  • Bu paketleri bağlayacak bir Filtre, sınıf kimliğini işaretler ve böylece trafik kontrol kuralını belirtilen paketlere uygular.

@Zoredache tarafından verilen örnek çalışıyor, ama ben şahsen paketleri filtrelemek için TC yerine Netfilter özelliğini ve shapping algoritması için CBQ yerine HTB kullanmayı tercih ediyorum. Böylece böyle bir şey deneyebilirsiniz (ilişkilendirilebilir diziler için Bash 4 gerektirir):

#! /bin/bash
NETCARD=eth0
MAXBANDWIDTH=100000

# reinit
tc qdisc del dev $NETCARD root handle 1
tc qdisc add dev $NETCARD root handle 1: htb default 9999

# create the default class
tc class add dev $NETCARD parent 1:0 classid 1:9999 htb rate $(( $MAXBANDWIDTH ))kbit ceil $(( $MAXBANDWIDTH ))kbit burst 5k prio 9999

# control bandwidth per IP
declare -A ipctrl
# define list of IP and bandwidth (in kilo bits per seconds) below
ipctrl[192.168.1.1]="256"
ipctrl[192.168.1.2]="128"
ipctrl[192.168.1.3]="512"
ipctrl[192.168.1.4]="32"

mark=0
for ip in "${!ipctrl[@]}"
do
    mark=$(( mark + 1 ))
    bandwidth=${ipctrl[$ip]}

    # traffic shaping rule
    tc class add dev $NETCARD parent 1:0 classid 1:$mark htb rate $(( $bandwidth ))kbit ceil $(( $bandwidth ))kbit burst 5k prio $mark

    # netfilter packet marking rule
    iptables -t mangle -A INPUT -i $NETCARD -s $ip -j CONNMARK --set-mark $mark

    # filter that bind the two
    tc filter add dev $NETCARD parent 1:0 protocol ip prio $mark handle $mark fw flowid 1:$mark

    echo "IP $ip is attached to mark $mark and limited to $bandwidth kbps"
done

#propagate netfilter marks on connections
iptables -t mangle -A POSTROUTING -j CONNMARK --restore-mark

- edit: varsayılan sınıfı unuttum ve kodun sonunda işaretler yaymak için.


umm .. listede olmayanlar için varsayılan bant genişliği sınırı nasıl eklenir?
Kokizzu

Prio tanımı olarak $ mark kullandınız. Herkes için aynı önceliği kullanmak daha iyi olmaz mıydı?
motobói

"iptables -t mangle -A INPUT" i "iptables -t mangle -A OUTPUT" olarak değiştirirsem sunucumdan belirli bir IP'ye hızı kontrol edebilir miyim?
Frank Barcenas

bundan sonra ayarları nasıl geri yüklerim?
Stefan Rogin

Cant 'bu işi yapıyor gibi görünüyor, tek bir ip için döngü olmadan komutları elle yazma.
Adones Pitogo

5

Bunun gibi bir şey, bir yüklenicinin web kamerasını sınırlı miktarda bant genişliğiyle sınırlamam için işe yaradı. Ayrıntılar için tc kılavuz sayfasına göz atın .

#!/bin/bash
set -x

DEV=eth0
export DEV

tc qdisc del dev $DEV root
tc qdisc del dev $DEV root
tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 100mbit

# setup a class to limit to 1500 kilobits/s
tc class add dev $DEV parent 1: classid 1:1 cbq rate 1500kbit \
   allot 1500 prio 5 bounded isolated

# add traffic from 10.2.1.37 to that class
tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \
   match ip src 10.2.1.37 flowid 1:1

3
CBQ biraz terk edildi ... HTB'yi kullanmak ve aynı sonucu elde etmek çok daha kolay olurdu
Julien Vehent

1
DEV'yi yalnızca bu komut dosyasında kullanılıyorsa dışa aktarmaya gerek yoktur ....
Gert van den Berg

1

Sorunuzu doğru anladığımdan emin değilim.

Saydam proxy (HTTP için Squid'de olduğu gibi) çoğunlukla gelen verileri kontrol etmek için kullanılır. Trafik şekillendirme, giden verileri kontrol etmek için kullanılır.

Daha fazla ayrıntı sağlamanız gerekiyor. Bir HTTP proxy'sinin arkasında çok fazla iş istasyonunuz varsa ve indirme hızlarını sınırlandırmaya çalışıyorsanız, Squid + gecikme havuzları gibi bir şeye gitmeniz daha iyi olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.