分类:
2008-11-07 17:45:29
The goal of this article is to present a few effective methods to revamp the way you work in a restricted corporation-like network. In order to achieve it we’re going to use to bypass the firewall rules applied by your system administrator. We’ll start with breaking through simple restrictions and gradually pass to more and more elaborate firewalls while we move on.
Author: Lukasz Usowicz
Translation: Lukasz Usowicz, Borys Musielak
Important note: It’s not our goal to encourage you to illegally bypass any restrictions set by the administrators of your network. We present a technology which is often helpful when working on a machine behind a firewall. If you are willing to use some tricks presented here to break through your company’s firewall, you have to understand that it may not be allowed in your corporation and you risk getting sacked. We take no responsibility for your actions. You’ve been warned.
This article is a continuation of a previous text: published in our vortal last month. The spirit of this article is a little bit different, though. It targets more experienced users, especially those who have to work in computer networks with harsh security rules. To make it clear - using SSH to tunnel insecure protocols like FTP or CVS is not in the scope. Perhaps another SSH article will cover this.
Here are a few things that you need to know or prepare in order to benefit from this article.
For simplicity reasons, throughout this text we’re going to use some
default names. The workstation which is located in a restricted network
eg. on our desk at work (the one we are going to revamp) will be called
LOCAL_HOST
. The second one should be outside the restricted network eg. at our house and will be called REMOTE_HOST
. Let’s assume that on the home workstation there is a user named user
and on the work machine there is a user worker
. On the REMOTE_HOST
with a public, static IP an SSH
server is installed. Although all the solutions presented in this
article can be applied in any GNU/Linux distribution or even in MS
Windows to make it simpler, we will consider a Debian-like system only.
If you don’t have the SSH server installed and running, open up a terminal and type (as root or using sudo
) the following command:
REMOTE_HOST:~# aptitude install openssh-server
The server should start automatically after being installed (as well
as on system start-up). We should also check whether we’re not blocking
the port 22 on our firewall (and open it if we do). We should also note
down our IP address (we’ll call it IP_NUMBER
in text; try /sbin/ifconfig
command to figure it out).
All right, let’s leave our home computer (REMOTE_HOST
)
now on and go visit our office. First, we need to analyze our network
restrictions. Sounds serious but don’t worry - I’m not going to mess
with network sniffers and other types of hacker tools. We are going to
simply try to connect to some outside networks and depending on the
level of restrictions we’ll see whether we fail or not. Looks good?
Let’s start then.
At the beginning let’s assume that SSH connections are not
blocked, but we can receive e-mails only from our local office account.
This means that ports 25 and 110 (SMTP and POP) are open only for our
local network. But what if we want to be able to receive mail from
external servers (EXT_POP_SVR
) and send it using external accounts as well (EXT_SMTP_SVR
)? Here is where the tunnels enter the stage. We just need to add a parameter while connecting to the REMOTE_HOST
via SSH. So, we’re digging the tunnel from our work machine to home with the following command:
worker@LOCAL_HOST:~$ ssh user@IP_NUMBER \\
-L 10025:EXT_SMTP_SVR:25 -L 10110:EXT_POP_SVR:110
Let’s try to decode this. The option -L
can be read as “listen on local host”. After a space bar we put the port on which SSH has to listen (in our case respectively 10025
and 10110
,
but it’s just an example; we can choose different ones but in order to
tunnel ports with numbers lower than 1024 we need root privileges).
After first colon we point where our REMOTE_HOST
should
forward the connection. After second colon we state on which port the
final server/computer awaits our connection. I emphasize that just
after the first colon we give an address relative to REMOTE_HOST. If we want to connect via tunnel with REMOTE_HOST
on port 25 (and not further than there) we should use something like:
worker@LOCAL_HOST:~$ ssh user@IP_NUMBER -L 10025:localhost:25
The relation between REMOTE_HOST
and… REMOTE_HOST
is the following: this is the very same host ;), so it’s localhost
for itself.
Let’s get back to our tunnels. We can now configure an e-mail client
to connect to an external server. As we’ve mentioned earlier, our LOCAL_HOST
listening on port 10025
is now “EXT_SMTP_SVR
server listening on port 25”. By analogy, we can say that localhost:10110
is an EXT_POP_SVR:110
. In our e-mail client we shall set an incoming server to localhost
and port to 10110
- SSH will carry on further communication. Naturally, localhost
set on LOCAL_HOST
will point to itself. And again by analogy outgoing server should be set to localhost
and port to 10025
.
In this quite simple (I hope!) way we can bypass not very complex restrictions only. But our network administrator is not sleeping so…
Note that you don’t have to use your IP_NUMBER
all the time. If you want to use REMOTE_HOST
by its name you need to put a line like this
IP_NUMBER REMOTE_HOST
to your /etc/hosts
file (on the machine at work), so that your work machine translates the REMOTE_HOST
to IP_NUMBER
on the fly. You don’t need to do this only if the REMOTE_HOST
is a domain name (or if you’re fine with using your IP_NUMBER
all the time). In this text we use IP_NUMBER
nevertheless.
Our present situation has changed. It seems that somebody in our work abuses usage of WWW. Access via HTTP has been cut to the minimum allowed by the boss. Right now we are not interested in how it has been done. Port 22 is still open, but we can’t say the same about port 80 (responsible for HTTP communication). Now when we know how the tunnels work, this is not a big problem for us.
It seems impossible but even the Google search has been blocked. So, to solve this unfortunate situation, we sit down and log onto our REMOTE_HOST
like that:
worker@LOCAL_HOST:~$ ssh user@IP_NUMBER \\
-L 10080:
Just a few clicks in Firefox: Edit -> Preferences -> Connection Settings -> Manual proxy configuration
. Here we can put in the HTTP proxy server
field: localhost
and 10080
for port
.
If there has been some other values in those fields, we shall write
them down. We may need to use them later on. I’ll call those extra
settings PROXY_SVR
and PROXY_PORT
.
Now, we can type in the address bar and… hip hip hooray – the WWW is wide open again. Don’t be so happy though. Try
. And what you’ve got – Google search again. Well, what else can we expect if we’re forwarding all traffic to
via SSH! To visit AltaVista we should reconnect again with:
worker@LOCAL_HOST:~$ ssh user@IP_NUMBER \\
-L 10080:
This is rather a pretty non-effective way to work with the Internet, don’t you think?
In this situation let’s look into the SSH manual and find a parameter -D
. As we can read there, SSH can act as a (specific) proxy server. This is a SOCKS-type (pseudo)server. We won’t be concerned how it works, just remember the name. Type the following in your text terminal:
worker@LOCAL_HOST:~$ ssh user@IP_NUMBER -D 8080
From now on, SSH listens on port 8080
. Looking back into Firefox’s proxy settings we can find a SOCKS Host
field. There we put localhost
and port 8080
(server type should be set to 5). Don’t forget to remove the previous entries in HTTP Proxy
that we’ve set earlier. And what we’ve got? Well, now SSH will intercept everything on this port and dynamically open a tunnel (via REMOTE_HOST
) to the final target typed in the Firefox address bar. From now on we can surf over the whole Internet! Vualla!
There is one little issue. And you know what? I think that Opera users will rise it first. That’s because currently . I’m an Opera user too and I can’t understand that, just like you ;). This is the right time and place to introduce one of the SSH friends: (abbr. transparent SOCKS). Yet again we won’t look deeper in how SOCKS server works but with tsocks we’re going to use some of its features instead. We’ll need root account privilege on LOCAL_HOST
to do this. This is not always available but here it’s required. Let’s install tsocks (again on Debian):
LOCAL_HOST:~# aptitude install tsocks
Assuming that SSH still listens on port 8080 as a proxy, we should perform the following steps:
/etc/tsocks.conf
,local
and put there our local network(s) address(es) eg.
local = 192.168.0.*
local = 10.0.0.0/255.255.255.0
path
, I’ll omit this part for now,server
and server_port
. We’ve got to set them to our proxy server. In our example it will look like this:
server = localhost
server_port = 8080
server_type = 5
and don’t ask me why It’s time to put those socks on. We can do this as a normal user. Again in a terminal:
worker@LOCAL_HOST:~$ tsocks opera
Here tsocks are used to run Opera. But it will also
intercept all network queries generated by the browser and forward them
directly to the SOCKS server (except for the local network queries). Our proxy server (ie. SSH) will then forward those queries further on to REMOTE_HOST
. All in all, Opera will act as if it has been run in the REMOTE_HOST
environment. This way, the browser won’t be vulnerable on any network restrictions. If REMOTE_HOST
is connected directly to the Internet, Opera should also be configured as Directly connected
. The whole “dirty job” is done by the tsocks+SSH tandem. In fact we can run practically any net application with tsocks program_name
.
That’s how we’ve met first good SSH friend, but…
… just because our admin closed port 22. Loser! Well, we need to
adjust to the new environment now. First, we should find a port which
is usually open. Let’s try the one responsible for secure web pages
(SSL connections) which is usually left open in all networks. Its
number is 443. As there is no possibility to change anything remotely
for now, we need to go back home. Sitting in front of our REMOTE_HOST
as root we need to edit /etc/ssh/sshd_config
file. Find the place with entry Port 22
and put Port 443
just below. All we have to do now is to restart SSH server with:
REMOTE_HOST:~# /etc/init.d/ssh restart
Sample command to connect to REMOTE_HOST
from LOCAL_HOST
in the present situation may look like that:
worker@LOCAL_HOST:~$ ssh -p 443 user@REMOTE_HOST -D 8080 \\
-L 10025:smtp.gmail.com:25 -L 10110:pop.gmail.com:110
As you can see, option -p 443
is a proper switch to force SSH to use a non-default port for a connection. And again we are “free as a bird”.
Oh, no! Our network administrator got really furious now. “It’s time
to finish these abuses” – he said. But he was not allowed to block all
HTTPS traffic (fortunately!). So he figured out that the best thing in
this situation is to control all traffic with an HTTP proxy server. He
has set it up to listen on port 3128 and opened this port to connect
only to a proxy server (naturally port 443 has been blocked). Outside
connections on port 3128 are blocked too. Is there any way to bypass
this? Well, try to remind some settings you’ve written down earlier: PROXY_SVR, PROXY_PORT
. We’ll assume now that these values point to admins’ proxy server (here PROXY_PORT
= 3128). We need to find a proper tool to use these values. Let’s look into our repositories:
worker@REMOTE_HOST:~$ apt-cache search proxy ssh tunnel
Among the results we should probably see a app. Quick installation:
REMOTE_HOST:~# aptitude install corkscrew
Corkscrew manual reveals an easy way to “teleport” SSH
to the other side of the HTTP proxy. To generate such a “hoop” we need
to know which types of connections are passed directly through the
proxy. All encrypted connections usually fulfill this condition. That’s
why we again concentrate on HTTPS (port 443). To force SSH skip the proxy we should edit ~/.ssh/config
and add the entry shown below:
Host IP_NUMBER
ProtocolKeepAlives 30
ProxyCommand /usr/bin/corkscrew PROXY_SRV \
PROXY_PORT IP_NUMBER 443
Having such settings we should be able to connect to REMOTE_HOST
again with:
worker@LOCAL_HOST:~# ssh -p 443 user@IP_NUMBER
All those switches like -L and -D still work, so we can use them in a suitable way for us. So please welcome another good friend of SSH – corkscrew.
Once again we can feel the breath of freedom, but …
We could continue our speculations further and further. A well-prepared administrator will find a way to block all methods shown above. But one truth is uncontested: if there is any hole in a restricted network, it automatically becomes a wide open window to the whole world. Here we talked only about the HTTPS protocol abuse and a HTTP proxy. But there are other environments and protocols we could possibly use.
-C
which compresses all traffic on-the-fly. It’s especially useful while using corkscrew.-R
), but they are very useful as well.LOCAL_HOST
is (our) proxy server installed on REMOTE_HOST
The above text is an almost-direct translation from the . But I’ve got something special for those who are not bored (or confused) with all those tunnels, yet. So, let’s met the…
Here I need to be more precise. Imagine that the traffic in our
network is allowed only via port 3128 and only to one specific IP
number which points to a proxy server. What’s more, the proxy doesn’t
allow for http_connect (i.e. forwarding encrypted protocols). This excludes the usage of corkscrew.
And to make it even harder, the firewall blocks all packages that don’t
have an HTTP header. Conditions described above mean no more than that
we are only allowed to view “classical” web pages and only with a
proxy. What shall we do to bypass such restrictions? To effectively
overcome this “not so fortunate” situation, we’ll still need SSH. But this time SSH
is going to have a special carrier to bypass the proxy. This carrier
needs to have an HTTP header to do its job. You can probably figure out
the name of this third SSH friend – yes, it’s an . Installation is needed on both hosts (LOCAL_HOST
and REMOTE_HOST
) and as you’ve noticed earlier, in Debian this is as simple as:
REMOTE/LOCAL_HOST:~# aptitude install httptunnel
The application contains both an httptunnel server (hts
) and an httptunnel client (htc
). I encourage you to take a look at the manual to see how it works in detail, but the usage is very similar to SSH tunneling. On the REMOTE_HOST
we need to run the server side of the application. The server is
responsible for deciding where the connections should be forwarded. If
we want to tunnel the connection to REMOTE_HOST
we simply point it by using localhost
.
In our example we only want to forward all connections to an SSH server running on REMOTE_HOST
. To accomplish this task, the httptunnel server should be started as follows:
REMOTE_HOST:~# hts -F localhost:22 80
A word of explanation: -F localhost:22
means that each connection is going to be forwarded to REMOTE_HOST
’s port 22 (i.e to an SSH server on REMOTE_HOST
). And 80
is the port on which hts should await our connections from the outside
(just remember to open it on the firewall and/or stop any other
services that may be running and listening on this port).
The appropriate command to connect to hts
on REMOTE_HOST
from LOCAL_HOST
using the proxy is:
worker@LOCAL_HOST:~$ htc -P PROXY_SVR:PROXY_PORT \\
-F 10022 IP_NUMBER:80
From now on, LOCAL_HOST
listening on port 10022
should forward all connections to port 22 on REMOTE_HOST
. To establish a desired SSH connection we can type:
worker@LOCAL_HOST:~$ ssh -p 10022 user@localhost -C -D 8080 \\
-L 13389:somewhere.else.com:3389 -L \\
13306:here.or.there.net:3306
Although this is a double-tunneled connection and may be a little bit slower than a direct one, it allows us to navigate all over the net, not only to the addresses set by the administrator. And you know what? We are free again!
I just hope that each of you won’t need to apply all of those tricks in real conditions. But… some day, somewhere… it may even save your life