Questo è fattibile in Linux con iptables
e tc
. Si configura iptables in MARK
pacchetti su una connessione in cui è stato trasferito un certo numero di byte. Quindi si utilizza tc
per mettere quei pacchetti contrassegnati in una classe in una disciplina di accodamento per ratificare la larghezza di banda.
Una parte un po 'complicata è limitare la connessione sia per i caricamenti che per i download. tc
non supporta il traffic shaping dell'ingresso. Puoi aggirare questo problema modellando l'uscita dall'interfaccia rivolta verso il server web (che modellerà i download sul tuo server web) e modellando l'uscita dall'interfaccia rivolta verso il provider upstream (che modellerà i caricamenti dal tuo server web). Non stai davvero modellando il traffico in ingresso (download), in quanto non puoi controllare la velocità con cui il tuo provider upstream invia i dati. Tuttavia, modellare l'interfaccia di fronte al server Web comporta la caduta dei pacchetti e l'uploader che restringe la finestra TCP per adattarsi al limite di larghezza di banda.
Esempio: (presuppone che si trovi su un router basato su Linux, in cui l'interfaccia del server Web è eth0
e l'upstream è eth1
)
# mark the packets for connections over 4MB being forwarded out eth1
# (uploads from webserver)
iptables -t mangle -A FORWARD -p tcp -o eth1 -m connbytes --connbytes 4194304: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 50
# mark the packets for connections over 4MB being forwarded out eth0
# (downloads to webserver)
iptables -t mangle -A FORWARD -p tcp -o eth0 -m connbytes --connbytes 4194304: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 50
# Setup queuing discipline for server-download traffic
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:50 htb rate 50mbit
# Setup queuing discipline for server-upload traffic
tc qdisc add dev eth1 root handle 1: htb
tc class add dev eth1 parent 1: classid 1:50 htb rate 50mbit
# set the tc filters to catch the marked packets and direct them appropriately
tc filter add dev eth0 parent 1:0 protocol ip handle 50 fw flowid 1:50
tc filter add dev eth1 parent 1:0 protocol ip handle 50 fw flowid 1:50
Se vuoi farlo sul server web stesso invece che su un router Linux, puoi comunque usare le porzioni di upload delle cose sopra. Un cambiamento notevole è che si dovrebbe sostituire FOWARD
con OUTPUT
. Per il download è necessario impostare una disciplina di accodamento utilizzando un dispositivo "Blocco funzionale intermedio" o ifb
. In breve, utilizza un'interfaccia virtuale in modo da poter trattare il traffico in ingresso come in uscita e modellarlo da lì utilizzando tc
. Maggiori informazioni su come impostare un ifb
possono essere trovate qui: /server/350023/tc-ingress-policing-and-ifb-mirroring
Si noti che questo tipo di cose tende a richiedere molta ottimizzazione per ridimensionare. Una preoccupazione immediata è che connbytes
si basa sul conntrack
modulo, che tende a colpire i muri di ridimensionamento con un gran numero di connessioni. Consiglierei test di carico pesante.
Un altro avvertimento è che questo non funziona affatto per UDP, poiché è apolide. Esistono altre tecniche per affrontarlo, ma sembra che i tuoi requisiti siano solo per TCP.
Inoltre, per annullare tutto quanto sopra, procedi come segue:
# Flush the mangle FORWARD chain (don't run this if you have other stuff in there)
iptables -t mangle -F FORWARD
# Delete the queuing disciplines
tc qdisc del dev eth0 root
tc qdisc del dev eth1 root