C'est faisable sous Linux avec iptables
et tc
. Vous configurez iptables en MARK
paquets sur une connexion où un certain nombre d'octets ont été transférés. Vous utilisez ensuite tc
pour placer ces paquets marqués dans une classe dans une discipline de mise en file d'attente afin de limiter la bande passante.
Une partie quelque peu délicate consiste à limiter la connexion pour les chargements et les téléchargements. tc
ne prend pas en charge la mise en forme du trafic de l'entrée. Vous pouvez contourner cela en façonnant la sortie sur votre interface orientée serveur Web (qui façonnera les téléchargements vers votre serveur Web) et en façonnant la sortie sur votre interface orientée fournisseur en amont (qui façonnera les téléchargements depuis votre serveur Web). Vous ne modifiez pas vraiment le trafic d'entrée (téléchargement), car vous ne pouvez pas contrôler la vitesse à laquelle votre fournisseur en amont envoie des données. Mais, la mise en forme de votre interface face au serveur Web entraînera la suppression des paquets et le téléchargement de la fenêtre TCP pour s'adapter à la limite de bande passante.
Exemple: (suppose que c'est sur un routeur basé sur Linux, où se trouve l'interface en face du serveur Web eth0
et en amont 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
Si vous souhaitez le faire sur le serveur Web lui-même plutôt que sur un routeur Linux, vous pouvez toujours utiliser les parties de téléchargement des éléments ci-dessus. Un changement notable est que vous remplaceriez FOWARD
par OUTPUT
. Pour le téléchargement, vous devez configurer une discipline de mise en file d'attente à l'aide d'un périphérique "Bloc fonctionnel intermédiaire", ou ifb
. En bref, il utilise une interface virtuelle pour que vous puissiez traiter le trafic entrant comme une sortie et le façonner à partir de là à l'aide de tc
. Pour plus d'informations sur la configuration d'un, ifb
cliquez ici: /server/350023/tc-ingress-policing-and-ifb-mirroring
Notez que ce type de trucs nécessite généralement beaucoup de réglages à l'échelle. Une préoccupation immédiate est qu'il connbytes
repose sur le conntrack
module, qui a tendance à frapper les murs de mise à l'échelle avec un grand nombre de connexions. Je recommanderais des tests de charge lourde.
Une autre mise en garde est que cela ne fonctionne pas du tout pour UDP, car il est apatride. Il existe d'autres techniques pour résoudre ce problème, mais il semble que vos exigences concernent uniquement TCP.
En outre, pour annuler tout ce qui précède, procédez comme suit:
# 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