Reducing latency of SSH tunnelled connections



Published: 2018-04-04 08:37:11 +0000
Categories: BASH, Misc,

Language

BASH

Description

The ability to tunnel connections over an SSH connection is incredibly useful, essentially creating a poor man's VPN, whether to a specific port (ssh -L 1443:google.com:443 ssh-server.domain) or by standing up a SOCKS proxy (ssh -D 8080 ssh-server.domain).

The most common complaint when doing this, though, is that the latency sucks. This is because of the TCP over TCP Problem. You're essentially running two layers of TCP congestion control, so any loss hurts - a lot.

This can be addressed by installing and using SShuttle (docs here).

It works (on Linux and Mac OS X) by intercepting and termination TCP connections locally, and transmitting payload and packet metadata over a SSH connection as data. The remote end re-assembles the packets and transmits on your behalf. The remote end only needs to have Python installed (as sshuttle remotely runs a python snippet to handle receipt and re-assembly of packet information).

The result is, there's no TCP connection within the tunnel, so you're still only contending with a single layer of congestion control

Snippet

# Tunnel any packets destinated for 192.168.1.0/24 via ssh-server.domain
sshuttle -r ssh-server.domain 192.168.1.0/24 

# Send everything via the tunnel
sshuttle -r ssh-server.domain 0.0.0.0/0

# Send only port 80 traffic via the tunnel
sshuttle -r ssh-server.domain 0.0.0.0/0:80 

# Send connections to port numbers between 2000 and 3000 via tunnel
sshuttle -r ssh-server.domain 192.168.1.0/24:2000-3000

# Bind to port 1234 and forward connections to 8.8.8.8 via the tunnel
# can be used to provide a proxy to other machines on your LAN
sshuttle -l 0.0.0.0:1234 -r ssh-server.domain 8.8.8.8/32

# Check whether a DNS name is valid at the remote end, and update /etc/hosts
#
# Useful to save mucking around with changing DNS whenever you bring a tunnel up
sshuttle -H -r ssh-server.domain 192.168.1.0/24

# Intercept local DNS queries and send them all over the tunnel (to avoid DNS leaks)
sshuttle --dns -r ssh-server.domain 0.0.0.0/0

# Forward everything but 192.168.2.0/24
sshuttle -X 192.168.2.0/24 -r ssh-server.domain 0.0.0.0/0

Usage Example

# Any of the config options can be dumped into a config file (one per line):

cat /etc/sshuttle.conf
-r ssh-server.domain
--dns
-X 192.168.2.0/24
0.0.0.0/0

# When calling sshuttle, pass it the path to the config file, prefixed with @
sshuttle @/etc/sshuttle.conf

Requires

Client Machine
  • Linux or Mac OS X
  • sudo access
  • SSH client
SSH Server
  • Python >= 2.3 on remote server
  • A running SSH daemon

Keywords

ssh, tunnel, latency, sshuttle, VPN, forwarding, tunnelling,

Latest Posts

Urldecode string (LUA)
FFMPEG Convert YUV444p to YUV420p (BASH)
Forcing FFMPEG to honour segment length in HLS Stream Creator (BASH)
Force CURL to place request to a specific IP (BASH)
Set a variable only if it is undefined (Javascript)
Ignore query string with Nginx caching proxy (NGinx)
Get breakdown of UK and non-UK votes for a Parliamentary Petition (Python)
Decompress Mozilla Firefox jsonlz4 bookmark backup files (Python)
Setting Git author details for a single repo (Git)
Checking Virtual Machine Resource Allocations with Libvirt (BASH)

Copyright © 2019 Ben Tasker | Sitemap | Privacy Policy
Available at snippets.bentasker.co.uk and snippets.6zdgh5a5e6zpchdz.onion