Isso é possível no linux com iptables
e tc
. Você configura iptables para MARK
pacotes em uma conexão onde um certo número de bytes foi transferido. Em seguida, você usa tc
para colocar esses pacotes marcados em uma classe em uma disciplina de enfileiramento para ratelimitar a largura de banda.
Uma parte um tanto complicada é limitar a conexão para uploads e downloads. tc
não suporta a modelagem de tráfego da entrada. Você pode contornar isso modelando a saída na interface voltada para o servidor da Web (que moldará os downloads para o servidor da Web) e modelando a saída na interface voltada para provedor de upstream (que moldará os uploads de seu servidor da Web). Você não está realmente moldando o tráfego de ingresso (download), pois você não pode controlar a rapidez com que o seu provedor envia dados. Mas, modelar a interface voltada para o servidor da Web resultará na eliminação de pacotes e no envio da janela TCP para acomodar o limite de largura de banda.
Exemplo: (presume que isso esteja em um roteador baseado no Linux, onde a interface voltada para o servidor da web é eth0
e o 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 você quiser fazer isso no próprio servidor da Web em vez de em um roteador Linux, ainda poderá usar as partes de upload dos itens acima. Uma mudança notável é a substituição de FOWARD
por OUTPUT
. Para o download, você precisa configurar uma disciplina de enfileiramento usando um dispositivo "Intermediate Functional Block" ou ifb
. Em suma, ele usa uma interface virtual para que você possa tratar o tráfego de entrada como saída e modelá-lo usando tc
. Mais informações sobre como configurar um ifb
podem ser encontradas aqui: link
Note que esse tipo de coisa tende a exigir muito ajuste para escalar. Uma preocupação imediata é que connbytes
depende do módulo conntrack
, que tende a atingir paredes de escala com um grande número de conexões. Eu recomendaria testes de carga pesada.
Outra ressalva é que isso não funciona para o UDP, já que ele é sem estado. Existem outras técnicas para lidar com isso, mas parece que suas necessidades são apenas para TCP.
Além disso, para desfazer todos os itens acima, faça o seguinte:
# 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