Subject: Re: SSH/Firewall
From: Dario Alcocer <dalcocer@home.com>
Date: Wed, 16 Aug 2000 12:50:40 -0700 (PDT)


>>>>> "Nathan" == Nathan Brown <NBrown@Chrystal.com> writes: Nathan> At work, we have this firewall through which all Nathan> connections to the outside world pass Nathan> through. <snip> Nathan> ...I am trying to SSH to my box at home. I have no Nathan> control over the firewall, and am tearing my hair out Nathan> trying to figure out how to beat it. The only port I know Nathan> for sure that works is 80, but even that is proxied. The Nathan> proxy doesn't support SOCKS X proxy either, so that is Nathan> giving me trouble with one of the clients I Nathan> tried. <snip> Nathan> The server works, so that's not an issue, its Nathan> getting around this firewall that is the issue. I found myself in the same unfortunate situation once as well. Thankfully, I did manage to find a solution that worked. Basically it involves running your SSH server at home on a port that the firewall will allow encrypted traffic on, and arranging for your ssh client to proxy its connection. Here are the steps I followed: 1. In my situation, I found out they were using Squid for proxy connections. It turns out that their Squid server allowed outbound proxy connections for HTTPS (port 443) or NNTPS (port 563.) So, your first step is to run the following to launch a second sshd that will listen to one of these ports: # tell ssh to listen on nntps port too /usr/local/sbin/sshd -p 563 2. On your ssh client machine, you'll need to add a proxy command line to your ~/.ssh/config file, so that ssh will know how to proxy the connection to your home ssh server: Host homepc ProxyCommand /usr/local/bin/ssh-tunnel proxy.acme.com 80 w.x.y.z 563 Of course, for this to work, you'll need to use ssh-tunnel (attached) and have Perl installed on your ssh client in order for this to work. Replace 'proxy.acme.com 80' with the correct name and port number that the proxy server uses, and replace w.x.y.z with the IP address or fully qualified domain name of your homepc. 3. When you need to connect to home machine, use 'homepc' (or whatever name you chose to use in Host directive in step 2) as the machine name to connect to: $ ssh homepc 4. (Optional) As a bonus, you can use your ssh connection to provide you encrypted web-surfing access via your home PC, if you or your ISP runs a proxy server. In particular, @Home subscribers can use ssh's port forwarding to point to their proxy server: $ ssh -L 8080:proxy.fed1.sdca.home.com:8080 -C homepc For this to example to work, you'll have to set your web browser running on the ssh client to use localhost:8080 as the "proxy", which will actually send your HTTP traffic encrypted to 'homepc', where 'homepc' will decrypt it and forward it on to proxy.fed1.sdca.home.com:8080.
Content-Description: ssh-tunnel: proxy interface for ssh filename="ssh-tunnel" #!/usr/bin/perl # # Usage: ssh-tunnel.pl [daemon port] ssl-proxy port destination_host port # # This script can be used by ssh to traverse a www-proxy/firewall that # supports the http CONNECT command. (Note: Properly setup proxies that allow # CONNECT will only allow a connection through to SSL ports (443 and 563 # according to squid.)) # # Example-- connect to host named "remote" outside of your firewall: # # $ ssh remote -o'ProxyCommand ssh-tunnel.pl www-proxy 8080 remote 443' # # Better yet, insert the ProxyCommand definition for host "remote" in # your $HOME/.ssh/config file: # # . # . # Host remote # ProxyCommand /usr/local/bin/ssh-tunnel.pl www-proxy 8080 %h %p # . # . # # Originally written by Urban Kaveus <urban@statt.ericsson.se> # # Updated by Theo Van Dinter <tvd@chrysalis.com>,<felicity@kluge.net> 4/28/1999 # I use TTSSH under Windows which doesn't support the proxycommand option. # I made some modifications to this script to help with that: # 1- The script no longer forks to do IO. Now uses IO::Select to deal with # multiple filehandles at once. # 2- The script can optionally "daemonize" itself and sit on a port. When # a connection is established, the tunnelling process will commence. # Add in the optional port # to listen to as the first commandline param. # Ex: "ssh-tunnel 2345 www-proxy 8080 remotehost 443", then start SSH: # "ssh localhost -p 2345". # 3- Tested with ActivePerl (Win32)/TeraTerm/TTSSH and UNIX Perl/SSH client. # use Socket; use IO::Select; $dport = shift if ( $#ARGV > 3 ); ($sslproxy,$proxyport,$destination,$destport) = @ARGV; die "Usage: $0 [daemon port] ssl-proxy port destination port\n" unless ( $sslproxy && $proxyport && $destination && $destport ); # set up log file #open(LOG, ">>/tmp/ssh-tunnel.log") || # die "unable to open logfile: $!"; #print LOG "====== ssh-tunnel started.\n"; # Set up network communication $protocol = getprotobyname("tcp"); if ( $dport ) { # do "daemon" thing. socket(INC, PF_INET, SOCK_STREAM, $protocol) || die "socket:$!"; setsockopt (INC, SOL_SOCKET, SO_REUSEADDR, pack ("l", 1)) || die "setsockopt:$!"; bind(INC,sockaddr_in($dport,INADDR_ANY)) || die "bind: $!"; listen(INC,1) || die "listen:$!"; accept(OUT,INC) || die "accept:$!"; $fhin = $fhout = \*OUT; } else { # STDIN/STDOUT used ... $fhin = \*STDIN; $fhout = \*STDOUT; } # connect to proxy server ... socket (PROXY, PF_INET, SOCK_STREAM, $protocol) or die("Failed to create socket:$!"); connect (PROXY, sockaddr_in($proxyport,inet_aton($sslproxy))) or die("Failed to connect to $sslproxy port $proxyport:$!"); # Force flushing of socket buffers foreach ( \*PROXY, $fhin, $fhout ) { select($_); $|=1; } # Send a "CONNECT" command to proxy: print PROXY "CONNECT $destination:$destport HTTP/1.0\r\n\r\n"; # Wait for HTTP status code, bail out if you don't get back a 2xx code. ($status) = (split(/\s+/,<PROXY>))[1]; die "Received a bad status code \"$status\" from proxy server." if ( int($status/100) != 2 ); # Skip through remaining part of HTTP header (until blank line) 1 until ( <PROXY> =~ /^[\r\n]+$/ ); # Start copying packets in both directions. $s = IO::Select->new($fhin,\*PROXY); while ( 1 ) { foreach $fh ( $s->can_read(10) ) { exit unless ( defined($num = sysread($fh,$_,4096)) ); exit if $num == 0; #$tstamp = localtime; #print LOG $tstamp, ": read ", $num, " bytes.\n"; exit unless ( defined(syswrite( ((fileno($fh)==fileno($fhin))? PROXY:$fhout),$_,$num)) ); #print LOG $tstamp, ": wrote ", $num, " bytes.\n"; } }
Hope this helps. -- Dario Alcocer // dalcocer@home.com
--- http://www.kernel-panic.org list archives http://www.ultraviolet.org To unsubscribe, send a message to the address shown in the list-unsubscribe header of this message.


Note1: Yes, it also works with Putty's pre-connect.
Note2: If you need to run sshd on port 443 (https) but want to keep your apache-ssl there, this is possible.
Back to my (mostly german) homepage