8

How do I limit the speed of an SSH connection? For example, when I am doing port forwarding (ssh -L ...), reverse tunneling (ssh -R ...), or SOCKS5 dynamic port forwarding (ssh -D ...), I may want to limit the bandwidth of the tunnel.

2 Answers 2

16

This can be done using ProxyCommand which acts as an alternative for the raw TCP connection. You can specify ProxyCommand in the global config for ssh (/etc/ssh/ssh_config), your private config (~/.ssh/config) or in the command line as ssh -o ProxyCommand=….

A trivial ProxyCommand is nc %h %p or equivalent (use nc, ncat, socat with the right syntax, anything that can give you raw TCP connection to the SSH server). To talk to the server your ssh will write to the stdin of this command and it will read from stdout of it. Sole nc %h %p is almost like connecting without ProxyCommand (when ssh does the job of nc internally).

The trick is you can insert filters between nc %h %p and ssh, on both sides. This way you can throttle the connection. Imagine your ssh talks through this:

pv -qL 20K | nc %h %p | pv -qL 10K

What ssh sends to the server gets limited by the first pv; what ssh receives from the server gets limited by the second pv.

To run ssh that talks through the above command, invoke:

ssh -o ProxyCommand='pv -qL 20K | nc %h %p | pv -qL 10K' …

Notes:

  • With this method you limit the entire SSH connection, everything that goes through it, all tunnels, X11 forwarding, other sessions (in case of connection sharing), everything. You throttle the raw TCP connection.

  • If you use ssh -N then you may want pvs not to be quiet and actually report the throughput of the tunnel(s):

    ssh -o ProxyCommand='pv -cN out -L 20K | nc %h %p | pv -cN in -L 10K' -ND 8080 user@server
    
  • With pv -R (invoked aside) you can change the settings of a running pv, this way you can adjust the throttle anytime. If you want to do this then pv -P inside the ProxyCommand will be useful to tell what PID belongs to what pv. See man 1 pv for details.

  • If your configuration already uses ProxyCommand then you need to embrace the existing value (rather than nc %h %p) with pvs. If your configuration already uses ProxyJump then you need to translate it to ProxyCommand and then embrace it with pvs.

0
1

One option would be applying QoS on port 22 on your router.

Trickle is a lightweight userspace bandwidth shaper. It can also be run as daemon, in which role it can manage multiple sessions at a time.

Another possibility is using something like htb.init-script, or ip_relay.

According to this discussion, you could also use iptables to limit the traffic by packets, but that wouldn't be my choice. I'd rather limit the bandwidth directly.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .