I have a server called publicserver on the public internet, and a second server (called privateserver) behind a NAT firewall. I also have a client PC (client, running Linux) behind another NAT firewall.
I want to be able to connect from client to privateserver using SSH, to perform Borgbackup backups (among other things). But privateserver is not reachable from the internet and neither is the NAT firewall itself (probably due to ISP settings), so port forwarding the SSH port by the NAT firewall seems to be no option (this was my first idea).
To do this anyway, privateserver establishes a reverse SSH tunnel to "publicserver:44044", so that I can connect from client to privateserver by connecting to publicserver. The command line used by privateserver to establish the tunnel is this:
/usr/bin/ssh -o CheckHostIP=no -o Compression=no -o IdentityFile=/root/.ssh/id_rsa -o LogLevel=INFO -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o BatchMode=yes -nN -R *:44044:localhost:22 user@publicserver
The command to use the tunnel from client is this:
ssh private-user@publicserver -p 44044
private-user exists only on privateserver.
This works. However, transfering data over this connection - e.g. using scp, rsync or other tools - is about 10x slower than it should be. client has a 40 MBit uplink, and privateserver has a 100 MBit downlink. I get a stable 4 MByte/second from client to publicserver using scp, and I get a stable 10MByte/second from publicserver to privateserver, but I only get 400kByte/second from client over the SSH tunnel to privateserver. I think I should get 4MByte/s since this is the lowest common bandwidth of both connections.
There are no bandwidth limits defined and publicserver has much more total bandwidth available than client and privateserver. Both client and privateserver are home machines connected to the internet via DSL. Neither of the three machines has a CPU limit defined or is maxed out regarding memory or CPU power.
I am already using the chacha20-poly1305 cipher in the SSH connection which (-> Wikipedia) performs better than AES if no AES-NI hardware support is available (which is the case on privateserver, it being an ARM machine). Compression is also off.
client and privateserver use OpenSSH 9.6p1, publicserver runs OpenSSH 8.9p1 (Ubuntu 22.04 LTS).
Why is the tunnel so slow? What can I do to speed it up?
Are there any other alternatives to connect from client to privateserver than SSH?
Bfor Bytes andbfor bits. 400,000 Bytes per second is about 4,000,000 bits per second, so you are close. If on the other hand you are comparing 4,000,000 bytrs per second to 400,000 bits per second then you are getting about 1% of the bandwidth. When in doubt, spell the units out!publicserveris roughly in the middle of the two.