Como posso modelar o tráfego no Linux por IP?

15

Temos uma configuração de proxy transparente. Tentei procurar modelagem de tráfego no Linux, e tudo que consegui encontrar on-line foi limitar o tráfego por interface (eth0 / eth1 ...).

Preciso limitar a largura de banda (nunca excedendo um limite específico) pelo endereço IP ou intervalos de IPs e não consigo encontrar uma maneira de fazer isso.

Existe alguma maneira de fazer isso?

Osama ALASSIRY
fonte

Respostas:

17

A camada de modelagem de tráfego do kernel é basicamente um agendador de pacotes conectado à sua placa de rede. Portanto, uma política de modelagem de tráfego se aplica a uma placa de rede.

O que você pode fazer, no seu caso, é criar uma lista de IP e largura de banda anexados e, para cada IP, você cria:

  • Uma regra de modelagem de tráfego identificada por um classid
  • Uma regra de filtro de rede que marcará pacotes com um valor de marca específico
  • Um filtro que vinculará essas marcas de pacotes ao classid, aplicando a regra de controle de tráfego aos pacotes especificados.

O exemplo dado por @Zoredache funciona, mas eu pessoalmente prefiro usar o recurso Netfilter em vez de TC para filtrar pacotes, e HTB em vez de CBQ para o algoritmo de modelagem. Portanto, você pode tentar algo assim (requer o Bash 4 para matrizes associativas):

#! /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

- editar: esqueceu a classe padrão e propaga marcas no final do script.

Julien Vehent
fonte
umm .. como adicionar limite de largura de banda padrão para aqueles que não estão na lista?
Kokizzu
Você usou a marca $ como definição prio. Não seria melhor usar a mesma prioridade para todos?
Motobói 15/05
se eu mudar "iptables -t mangle -A INPUT" para "iptables -t mangle -A OUTPUT" eu poderia controlar a taxa do meu servidor para um IP em particular?
31575 Frank Barcenas
como faço para restaurar as configurações depois disso?
Stefan Rogin
Não consigo fazer isso funcionar, escrevendo comandos manualmente sem loop para um único ip.
Adones Pitogo
5

Algo assim funcionou para mim para limitar a webcam de um contratado a uma quantidade limitada de largura de banda. Confira a página de manual para tc para obter detalhes.

#!/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
Zoredache
fonte
3
CBQ é um pouco abandonado ... você iria encontrar HTB muito mais fácil de usar e obter o mesmo resultado
Julien Vehent
1
Não há necessidade de DEV exportação, se for utilizado apenas neste roteiro ....
van den Berg Gert
1

Não sei se entendi sua pergunta corretamente.

A proxy transparente (como no Squid for HTTP) é usada para controlar principalmente os dados recebidos. Enquanto a modelagem de tráfego é usada para controlar os dados enviados.

Você precisa fornecer mais detalhes. Se você tem muitas estações de trabalho por trás de um proxy HTTP e está tentando limitar as velocidades de download, é melhor optar por algo como pools de atraso do Squid +.

halp
fonte