SSH Proxying
For about a year now I run a little atom box with three harddrives hooked up in my flat in Graz, that serves as central media server. It runs samba, mt-daapd (for iTunes music sharing) and an HTTP server. The only thing that is visible to the outside from this server, is port 22 which is obviously an SSH server.
It is however still possible to get access to the services it provides by tunnelling. I don't care too much about samba here because I have access to the file system via SSH as well (OS X is able to mount SSH resources) but I do care about DAAP and the HTTP server. Because I constantly have to remember how to do that, I thought others might be interested in that as well, so here is how:
Simple Port Forwarding
Task is: forward a port so that you can access something remotely. For example the HTTP server:
ssh username@remote-server.example.com -N -L local-port:server-name:remote-port
So say my server that gives me access to my network via SSH is listening at servername.example.com I can forward port 80 to a local port 8080 like this:
ssh username@servername.example.com -N -L 8080:localhost:80
For example I know my rounter responds to the name router.local I can forward access to that as well:
ssh username@servername.example.com -N -L 8080:router.local:80
If you are interested in what the flags do: -N ensures no command is executed on the remote side, -L does the actual port forwarding. The format for the port forwarding is always [bind_address:]port:host:hostport where bind_address can be omitted in which case 0.0.0.0 is assumed.
DAAP Forwarding
Because I have a DAAP server at home, I can forward the music I want to listen to as well. This is a little bit trickier because the service has to be registered locally for iTunes or whatever you want to use, to pick up. On OS X this script does the trick:
#!/usr/bin/env python import os import signal import time from subprocess import Popen from threading import Thread SSH_SERVER_NAME = 'servername.example.com' DAAP_SERVER_NAME = 'localhost' REMOTE_DAAP_PORT = 3689 LOCAL_DAAP_PORT = 3689 SHARE_NAME = 'iTunes Share Name' pids = [] def start_ssh(): c = Popen(['ssh', SSH_SERVER_NAME, '-g', '-N', '-L', '%d:%s:%d' % ( LOCAL_DAAP_PORT, DAAP_SERVER_NAME, REMOTE_DAAP_PORT )]) pids.append(c.pid) c.wait() def start_proxy(): c = Popen(['dns-sd', '-R', SHARE_NAME, '_daap._tcp.', 'local', str(LOCAL_DAAP_PORT)]) pids.append(c.pid) c.wait() def main(): print 'Starting up...' try: try: for task in start_ssh, start_proxy: t = Thread(target=task) t.setDaemon(True) t.start() while 1: time.sleep(30) except KeyboardInterrupt: pass finally: for pid in pids: try: os.kill(pid, signal.SIGTERM) except OSError: pass print 'Shut down' if __name__ == '__main__': main()
Just start it and you will have a secure proxy to your remote music collection until you hit ^C. The share name can be anything, this is what shows up in the iTunes sidebar.
You mean port 22?
— Simon on Sunday, February 14, 2010 18:46 #
Indeed. 22 it is, no idea why I was confusing this :)
— Armin Ronacher on Sunday, February 14, 2010 20:19 #
Maybe you could be interested in a program I wrote and published recently ( github.com/mtorromeo/iosshy ). It manages ssh tunnels and seems to cover your use case. It should also run on osx but I couldn't test it there. It's a python + pyqt app.
— Massimiliano Torromeo on Sunday, February 14, 2010 21:00 #
It's good idea to run the ssh server on port 443 also, so you can connect on networks where most ports are blocked. It even works through most proxy's.
— Brynjar on Monday, February 15, 2010 17:36 #
And those who are in such network that doesn't allow accessing either port 443 or 22 can use corkscrew - SSH over HTTP tunnel ;)
— plaes on Thursday, February 18, 2010 17:03 #
That DAAP Forwarding script is exactly what I was looking for. Thanks!
— Luke on Thursday, March 4, 2010 4:12 #
That is a pretty complicated way to get your music remotely :P Pretty clever way to trick itunes though.
— John on Tuesday, March 9, 2010 16:19 #