service smtps { disable = no socket_type = stream wait = no user = USER server = /usr/bin/ssh server_args = USER@HOST -C /home/USER/bin/localsmtp bind = 127.0.0.1 } service pop2 { disable = no socket_type = stream wait = no user = USER server = /usr/bin/ssh server_args = USER@HOST -C /home/USER/bin/localpop bind = 127.0.0.1 }
I have the above in my xinetd configuration to automatically generate ssh tunnels. I configure my MUA to talk to localhost on the pop2 port for POP connections to my real POP server and I configure Postfix (my local MTA) to relay all mail through localhost on the smtps port with the directive “relayhost = 127.0.0.1:465“.
The localpop script contains the command “nc 127.0.0.1 110” and the localsmtp script contains the command “nc 127.0.0.1 25“. I use the localpop and localsmtp scripts so that if I change anything on the server end then I can easily adjust the scripts without reconfiguring the workstations that relay their mail.
The same configuration can be used whenever you have shell access via ssh to a machine that runs a MTA. It’s not difficult and the ssh connections are terminated whenever the MUA or the MTA that initiated them times out and closes it’s connection. This means that there is no need to have cron jobs monitoring the ssh tunnels or anything else that is difficult.
I fetch mail using fetchmail’s preconnect option:
poll localhost service 23456 with proto POP3 auth password
password “SECRET”
preconnect ‘ssh -f -L localhost:23456:localhost:110 USERNAME@REMOTEHOST sleep 3 < /dev/null > /dev/null’
If the password is not cached by ssh-agent, ssh will ask for it when you run fetchmail.
The xinetd method is really great! It gets the job done, it’s dynamic, and it avoids the TCP-in-TCP issues.
bartman: Tunneling through ssh does not avoid the TCP in TCP issues. However most of the time the link congestion and packet loss is so low that it doesn’t matter. When there is packet loss mail transfer is something that can happen asynchronously (not like a terminal session where every delay matters).
To avoid the TCP in TCP issues you would need a VPN based on UDP. I’ve been thinking of doing that but the current setup never broke badly enough.
But for the original request (access to a server controlled by other people that runs ssh) this is the best option.
Take a look at autossh for keeping tunnels alive nicely:
http://packages.debian.org/unstable/net/autossh
etbe: the reason I say that it gets around TCP-in-TCP issues is that it uses netcat to convert the serial stream into a socket.
Unlike the ssh port forwarding solution that was mentioned in a comment above mine.
I use IPSec.