ssh and https on port 443 in the same time

It’s possible thanks to this Martin Renold wonderful hack


A copy of his site (hope he won’t get angry, but I want to keep this):

It is a bit a hack, but it works like this:

You run a small wrapper program (ssh-https.c, compile with ‘gcc -o ssh-https ssh-https.c’) listening on port 443. Ssh runs on port 22 anyway, and you run apache-ssl on port 8888 instead of 443. The wrapper program detects what kind of traffic is comming and runs netcat, either ‘nc localhost 22’ or ‘nc localhost 8888’.

To make it work, add this line to your /etc/inetd.conf:

443 stream tcp nowait nobody /usr/sbin/tcpd /usr/local/sbin/ssh-https

The Drawback is that sshd as well as apache-ssl will see all traffic comming from localhost, so make sure this is secure.

So how does the ssh-https do its decision? Well, it’s just 23 lines of source code, you’ll find out :)
No, honest. It waits for one second for data from the client. If there was data, it’s https, and if there was no date, it’s the ssh client waiting for the server greeting (I think it is not clearly stated in the RFC whether the client or the server has to greet first, but I found that the clients always waits for the server).
It did work. I’m not running this on my site any more because I don’t run apache-ssl any more nor am I firewalled out anywhere at the moment, lucky me!

ssh-https.c source code:


int main()
  struct timeval tv;
  fd_set set;
  tv.tv_sec = 2;
  tv.tv_usec = 0;
  FD_SET(0, &set);

  if (select(1, &set, NULL, NULL, &tv)) {
    /* Got data from the client side - it must be his https-request. */
    /* FIXME: analyze it, it could be the client ssh greeting */
    execl("/usr/bin/nc", "/usr/bin/nc", "localhost", "8888", NULL);
  } else {
    /* No data sent by the client - it must be waiting for the ssh
       greeting from the server. Connect it to the sshd server. */
    execl("/usr/bin/nc", "/usr/bin/nc", "localhost", "ssh", NULL);

For my use, I changed the execl lines like this:

execl("/bin/nc", "/bin/nc", "-q5", "localhost", "8888", NULL);
execl("/bin/nc", "/bin/nc", "-q5", "localhost", "ssh", NULL);