Skip to content

Latest commit

 

History

History
55 lines (31 loc) · 3.09 KB

README.md

File metadata and controls

55 lines (31 loc) · 3.09 KB

sshttproxy: a connect-on-demand SSH HTTP Proxy

(You have my permission to pronounce it sh*t proxy, if you wish)

sshttproxy parses the Host header of incoming HTTP requests, works out which remote host and port they are destined for, creates an SSH tunnel to that host and forwards the request. For example, requests for http://example.com.8080.localhost will get forwarded to port 8080 on example.com.

Why?

I wanted a hassle free way of securing access to web-based administration tools (e.g., phpMyAdmin) on remote servers. Having these apps listen only on localhost and then tunnelling a port over SSH provided a good level of security, but it was a pain to have to keep setting up the tunnels and not having consistent local URLs meant I couldn't use my password manager to store login information. Now all I need to do is bookmark a URL.

Usage

Start it up on some local port:

./sshttproxy.py
usage: sshttproxy.py [-h] [--port PORT] [--host HOST]

optional arguments:
  -h, --help            show this help message and exit
  --port PORT, -p PORT  port to listen on (default: 7150)
  --host HOST           host to listen on (default: localhost)

Connect to your favourite server:

http://remote-host.example.com.8080.whatever.localhost:7150/

Host headers are parsed as follows:

  • the rightmost all-numeric subdomain is treated as the remote port;
  • everything to the left of this is treated as the remote hostname;
  • everything to the right is ignored.

Dependencies

I've only tested this on Python 2.6.

It uses two third-party Python modules: paramiko which handles the SSH stuff and eventlet which provides networking concurrency.

Notes

This won't be much use unless you can resolve arbitrary subdomains of localhost.
Obviously you could add entries to /etc/hosts every time but it kind of defeats the purpose of creating tunnels with zero configuration. Fortunately, it's easy to set this up: just use dnsmasq. (See also my brief guide to configuring dnsmasq.) It's a handy feature to have anyway for development purposes.

The app you're connecting to must be Host header agnostic.
sshttproxy passes your entire request through untouched (it's a TCP-level proxy really) so the web app on the other end needs to not mind that the Host header ends in .localhost. This means, among other things, that virtual hosting won't work, so the app needs to be the only thing listening on that particular port. This shouldn't be too difficult to satisfy though, given that you can choose any arbitrary port with no firewalls to worry about.

Make sure the SSH keys you need are loaded into your key agent.
sshttproxy makes no attempt to prompt you for your password or to load keys.

Make sure the host is in your known_hosts list.
For simplicty and safety's sake, sshttproxy refuses to connect to any hosts it doesn't recognise.