Thursday, November 22, 2007

Tunneling TCP Services over HTTP(S)

HTTP Tunnel Definition
HTTP Tunneling is a technique by which communications performed using various network
protocols are encapsulated using the HTTP protocol, the network protocols in question usually belonging to the TCP/IP family of protocols. The HTTP protocol therefore acts as a wrapper for a covert channel that the network protocol being tunneled uses to communicate.The HTTP stream with its covert channel is termed a HTTP Tunnel.

HTTP Tunnel software consists of client-server HTTP Tunneling applications that integrate
with existing application software, permitting them to be used in conditions of restricted network connectivity including firewalled networks, networks behind proxy servers, and NATs.

An HTTP Tunnel is used most often as a means for communication from network locations with
restricted connectivity – most often behind NATs, firewalls, or proxy servers, and most often with applications that lack native support for communication in such conditions of restricted connectivity. Restricted connectivity in the form of blocked TCP/IP ports, blocking traffic initiated from outside the network, or blocking of all network protocols except a few is a commonly used method to lock down a network to secure it against internal and external threats.

This document explains how to set up an Apache server and SSH client to allow tunneling SSH over HTTP(S) as an example. This can be useful on restricted networks that either firewall everything except HTTP traffic (tcp/80,tcp/443) or require users to use a local (HTTP) proxy.

In this example our LAN is 192.168.0.0/24
The client 192.168.0.CC is behind the firewall.)
Gateway(Firewall) is 192.168.0.GW
HTTP Tunnel Server is 192.168.0.TT

Here SSH Service is tunneled as an example.You can tunnel telnet or any other TCP/IP
Service/PORT supported by Apache Proxy Module.

Apache Compilation in the HTTP Tunnel Server
So as to use Apache Server as a Tunnel for TCP/IP or other protocols,it should be
configured to run in Proxy Mode.
Run httpd -l to check whether the proxy modules are loaded or not.
If not load it if available under the Apache MODULES directory using the LoadModule
Directive.
eg : LoadModule mod_proxy modules/mod_proxy.so

Or you should recompile Apache to include the mod_proxy support
[root@tunnelserver] # ./configure --enable-proxy --enable-proxy-connect --enable-proxy-http --enable-proxy-ajp --enable-proxy-balancer --enable-proxy-ftp
[root@tunnelserver] # make
[root@tunnelserver] # make install

Then include the following in httpd.conf (Simple config .No security measures followed)
Listen 80
Listen 443

Order deny,allow
Deny from all
Allow from all

ProxyRequests On
AllowCONNECT 22
# You can specify a number of ports here
ProxyVia on


Now Apache is ready to act as a Tunnel listening on ports 80 and 443
Do a service restart.

Verification with SSH Tunnel Client software- ProxyTunnel
Download Proxytunnel from
SOURCEFORGE
Install it in the Client machine(s) behind the firewall,from which you want SSH through the HTTP Tunnel Server. Here I have a client 192.168.0.CC
[root@client]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 192.168.0.GW 0.0.0.0 UG 0 0 0 eth0

SSH to PUB.LIC.IP.ADD over port 22 is blocked by firewall in the Gateway Server

See the output of iptables -L of Gateway
[root@GATEWAY ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DROP tcp -- 192.168.0.CC PUB.LIC.IP.ADD.some-domain.com tcp dpt:22
Chain OUTPUT (policy ACCEPT)
target prot opt source destination


And lets try a Bare SSH from the client to a Remote Server outside the LAN
[root@client]# ssh PUB.LIC.IP.ADD -l root -p 22
ssh: connect to host PUB.LIC.IP.ADD port 22: Connection timed out


So it is clear that SSH to PUB.LIC.IP.ADD is filtered

Installed ProxyTunnel Software
[root@client src]# tar xzf proxytunnel-1.6.3.tgz
[root@client src]# cd proxytunnel-1.6.3
[root@client proxytunnel-1.6.3]#
# make
# make install


Then configure SSH to use proxytunnel for connections
Edit ~/.ssh/config and include the following
Host *
ProxyCommand proxytunnel -v -p 192.168.0.TT:80 -d %h:%p
ServerAliveInterval 30

Here Host Specifies the Destination * for all
-d %h:%d will be expanded on the Run to -d Destination_IP:Port

Now try SSH
[root@client]# ssh PUB.LIC.IP.ADD -l root -p 22
192.168.0.TT is 192.168.0.TT
Connected to 192.168.0.TT:80
Tunneling to PUB.LIC.IP.ADD:22 (destination)
Connect string sent to Proxy: 'CONNECT PUB.LIC.IP.ADD:22 HTTP/1.0
Proxy-Connection: Keep-Alive
'
DEBUG: recv: 'HTTP/1.0 200 Connection Established
'DEBUG: recv: 'Proxy-agent: Apache/2.2.6 (Unix)
'DEBUG: recv: '
'Starting tunnel
root@PUB.LIC.IP.ADD's password:
Last login: Fri Nov 23 14:22:48 2007 from some-domain.com
[root@RemoteServer root]#


Now replace
ProxyCommand proxytunnel -v -p 192.168.0.TT:80 -d %h:%p
with
ProxyCommand proxytunnel -v -p 192.168.0.TT:443 -d %h:%p
in ~/.ssh/config if you want to tunnel through Port 443 of HTTP Tunnel Server.

Then try SSH
[root@client]# ssh PUB.LIC.IP.ADD -l root -p 22
192.168.0.TT is 192.168.0.TT
Connected to 192.168.0.TT:443
Tunneling to PUB.LIC.IP.ADD:22 (destination)
Connect string sent to Proxy: 'CONNECT PUB.LIC.IP.ADD:22 HTTP/1.0
Proxy-Connection: Keep-Alive
'
DEBUG: recv: 'HTTP/1.0 200 Connection Established
'DEBUG: recv: 'Proxy-agent: Apache/2.2.6 (Unix)
'DEBUG: recv: '
'Starting tunnel
root@PUB.LIC.IP.ADD's password:
Last login: Fri Nov 23 14:26:44 2007 from some-domain.com
[root@RemoteServer root]#


References
APACHE Project Page
APACHE Project Page
Wikipedia
Dag Wieers

No comments: