Some daemon processes which handle user connections don’t have an internal mechanism to limit the bandwidth. One popular example is OpenSSH.
In theory SFTP could eat up all the bandwidth available, which is especially bad for home connections, since a fully utilized uplink is sometimes worse than a fully utilized downlink.
In order to apply a speed limit to daemon processes which use fork, tools like trinkle are not an option, but tc can do the job.
The following example configures a 10MBit/s upload speed limit (10,5Mbit/s burst limit) to the SSH server (sport 22) running on eth0.
tc qdisc add dev eth0 root handle 1:0 htb tc class add dev eth0 parent 1:0 classid 1:1 htb \ rate 10000kbps ceil 10500kbps prio 0 tc filter add dev eth0 protocol ip parent 1:0 prio 0 \ u32 match ip sport 22 0xffff flowid 1:1
To watch the applied rules and the status:
tc -s -d class show dev eth0
To remove the applied configuration:
tc qdisc del dev eth0 root
This is completely done using the Kernel API. So it can be done with every service by specifying the source port and doesn’t bring any noticeable performance degradation beside having a speed limit applied.
If you want to limit all the upload traffic on a certain interface there doesn’t need to be an filter rule. This is done using a default.
The following example sets the limit from above to all upload traffic on eth0
tc qdisc add dev eth0 root handle 1:0 htb default 1 tc class add dev eth0 parent 1:0 classid 1:1 htb \ rate 3500kbps ceil 4000kbps prio 0