LDP/LDP/howto/docbook/Firewall-Piercing.sgml

1188 lines
46 KiB
Plaintext

<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
<!--
$Id$
Revision 1.25 was the last to use LinuxDoc-SGML
Revision 1.3 corresponds loosely to Firewall-Piercing.fr.sgml 1.3
Compile this file with:
jade -t sgml -d /usr/share/sgml/docbook/stylesheet/dsssl/modular/html/docbook.dsl -V html-index Firewall-Piercing.en.sgml
-->
<article>
<artheader>
<title>Firewall Piercing mini-HOWTO</title>
<author>
<firstname>François-René</firstname>
<surname>Rideau</surname>
<authorblurb><simpara><email>fare+fwprc@tunes.org</email></simpara></authorblurb>
</author>
<pubdate>v0.97, 24 November 2001</pubdate>
<revhistory>
<revision>
<revnumber>v0.97</revnumber>
<date>2001-11-24</date>
<authorinitials>frr</authorinitials>
<revremark>
Conversion to DocBook SGML.
</revremark>
</revision>
</revhistory>
<abstract>
<para>
Directions for using <command>ppp</command> over <command>ssh</command>,
<command>telnet</command> or whatever,
so as to do achieve transparent network connection accross a firewall.
Applies to friendly VPN construction
as well as to piercing unfriendly firewalls.
</para>
</abstract>
</artheader>
<sect1>
<title>Stuff</title>
<sect2>
<title>DISCLAIMER</title>
<para>
<emphasis>READ THIS IMPORTANT SECTION !!!</emphasis>
</para>
<para>
<emphasis>
I hereby disclaim all responsibility
for <emphasis>your</emphasis> use of this hack.
If it backfires on you in any way whatsoever,
that's the breaks. Not my fault.
If you don't understand the risks inherent in doing this, don't do it.
If you use this hack and it allows vicious vandals
to break into your company's computers and costs you your job and
your company millions of dollars, well that's just tough nuggies.
Don't come crying to me.</emphasis>
</para>
</sect2>
<sect2>
<title>Legal Blurp</title>
<para>
Copyright &copy; 1998-2001 by François-René Rideau.
</para>
<para>
This document is free software published under the
<ulink url="http://www.geocities.com/SoHo/Cafe/5947/bugroff.html"
>bugroff license</ulink>.
</para>
<para>
To ease their task, it has also been released
to the LDP maintainers under the
<ulink url="http://www.gnu.org/copyleft/fdl.html"
>GNU Free Documentation License</ulink>.
</para>
</sect2>
<sect2>
<title>Looking for a maintainer</title>
<para>
I have stopped actively developing this mini-HOWTO,
although I'm still maintaining it.
I'm looking for a maintainer to take over this document,
who would extend it into a full-fledged HOWTO
by expanding on the solutions whose existence I only mention,
and who would maybe develop software to make it easier to pierce firewalls.
I have a lot of ideas to expand this HOWTO and write according software,
if anyone is interested.
I also used to write a french version of this HOWTO,
but no one has been maintaining it anymore for a long time.
</para>
</sect2>
<sect2>
<title>Credits</title>
<para>
Even though the only thing left is the disclaimers,
this document owes a lot to the
<ulink url="http://www.linuxdoc.org/HOWTO/mini/Term-Firewall.html"
>Term-Firewall mini-HOWTO</ulink>
by Barak Pearlmutter <email>bap@cs.unm.edu</email>.
Barak's mini-HOWTO relies on
an ancient and no-more-supported program named <productname>Term</productname>
(a great program in its time,
and maybe still useful in some unhappy circumstances),
as well as on peculiarities of a not-so-standard telnet implementation,
that is, many obsolete and non-portable facts.
Nevertheless, there was a necessity for a mini-HOWTO about piercing firewalls,
and despite the limitations of its hacks,
this mini-HOWTO was a model and an encouragement.
</para>
<para>
I'd also like to congratulate
Lars Brinkhoff <email>lars@nocrew.org</email>
<!-- Andreas 'Ajje' Pettersson <email>ajje@wombat.ludvika.se</email> -->
and Magnus Lundström <email>logic@gore.nocrew.org</email>
for their fine http, mail and icmp tunnels.
</para>
</sect2>
<sect2>
<title>Latest versions</title>
<para>
The latest official LDP version of this document is on:
<ulink url="http://www.linuxdoc.org/HOWTO/mini/Firewall-Piercing.html"
>http://www.linuxdoc.org/HOWTO/mini/Firewall-Piercing.html</ulink>
</para>
<para>
The source of my latest official version of this document is on:
<ulink url="http://fare.tunes.org/files/fwprc/"
>http://fare.tunes.org/files/fwprc/</ulink>
</para>
<para>
The source of my latest working draft of this document is on:
<ulink url="http://tunes.org/cgi-bin/cvsweb/fare/fare/www/articles/Firewall-Piercing.en.sgml"
>http://tunes.org/cgi-bin/cvsweb/fare/fare/www/articles/Firewall-Piercing.en.sgml</ulink>
</para>
</sect2>
</sect1>
<sect1>
<title>Introduction</title>
<sect2>
<title>Foreword</title>
<para>
This document has a moral. And the moral is:
<emphasis remap="bf"
>a firewall cannot protect a network against its own internal users,
and should not even try to.</emphasis>
</para>
<para>
When an internal user asks you system administrator
to open an outbound port to an external machine,
or an inbound port to an internal machine,
then you should do it for him.
Of course you should help the user to make sure
that his transactions are secure, and that his software is robust.
But a flat out denial of service is plain incompetence.
For unless he is so firewalled as to be completely cut from the outside world,
with no <command>ssh</command>, no <command>telnet</command>,
no web browsing, no email, no dns, no <command>ping</command>,
no phone line, no radio, no nothing,
then the user can and will use firewall piercing techniques to access
the machines he wants nonetheless,
and the net result for security will be
an unaudited connection with the outside world.
So either you trust your users, after proper training and selection,
or you shouldn't grant them access to the network at all - but then again,
the role of a network administrator is usually to serve its users,
so your goal should be the former rather than the latter.
You can and you shall protect them from the outside world;
you can and you shall protect your critical services from them;
but you can't and you shall not protect them from themselves.
</para>
<para>
Because there exists such things as system administrators
who are either unresponsive, absent, overworked, plain incompetent,
irresponsible, or more generally managed by incompetent people,
it so happens that a user may find himself behind a firewall
that he may cross, but only in awkward ways.
This mini-HOWTO explains a generic and portable way
to pierce tunnels into firewalls,
by turning any thin, tiny trickle of bits
into a full-fledged information superhighway,
so the user can seamlessly use standard tools to access computers
on the other side of the firewall.
The very same technique can be used by competent system administrators
to build virtual private networks (VPN).
</para>
</sect2>
<sect2>
<title>Security issues</title>
<para>
Of course, if your sysadm has setup a firewall
s/he might have a good reason,
and you may have signed an agreement to not circumvent it.
On the other hand, the fact that you can use
telnet, the web, e-mail, or whatever other bidirectional information flux
with the outside of the firewall
(which is a prerequisite for the presented hacks to work)
means that you are allowed to access external systems,
and the fact that you can log into a particular external system
somehow means you're allowed to do it, too.
</para>
<para>
So this is all a matter of <emphasis>conveniently</emphasis>
using legal holes in a firewall,
and allow generic programs to work from there with generic protocols,
as opposed to requiring special or modified (and recompiled) programs
going through lots of special-purpose proxies
that be misconfigured by an uncaring or incompetent sysadm,
or to installing lots of special-purpose converters
to access each of your usual services (like e-mail)
through ways supported by the firewall (like the web).
</para>
<para>
Moreover, the use of a user-level IP emulator such as
<productname>SLiRP</productname>
should still prevent external attackers from piercing the firewall back
in the other way, unless explicitly permitted by you
(or they are clever and wicked,
and root or otherwise able to spy you on the server host).
</para>
<para>
All in all, the presented hack should be <emphasis>relatively</emphasis> safe.
However, it all depends on the particular circumstances
in which you set things up,
and I can give no guarantee about this hack.
Lots of things are intrinsically unsafe
about any Internet connection, be it with this hack or not,
so don't you assume anything is safe unless you have good reasons,
and/or use some kind of encryption all the way.
</para>
<para>
Let's repeat the basics of networking security:
<emphasis>you cannot trust anything about a connection
more than you trust the hosts that can handle the unencrypted data</emphasis>,
including hosts on both ends of the connection,
and all hosts that can intercept the communication,
unless the communication is properly encrypted with secret keys.
If you misplace your trust,
your passwords may be stolen and used against you,
your credit card number may be stolen and used against you,
and you may be fired from your work for endangering the whole company.
Tough nuggies.
</para>
<para>
To sum it up, don't use this hack unless you know what you're doing.
Re-read the disclaimer above.
</para>
</sect2>
<sect2>
<title>Other requirements</title>
<para>
It is assumed that you know what you're doing,
that you know about configuring a network connection,
that in case of doubt, you will have read all relevant documentation
(HOWTOs, manual pages, web pages, mailing-list archives,
RFCs, courses, tutorials).
</para>
<para>
It is assumed that you have shell accounts on both sides of the firewall,
that you can somehow transmit packets of information both ways
across the firewall (with <command>telnet</command>, <command>ssh</command>,
e-mail, and the web being the ways currently known to work),
and that you can let a daemon run as a background task on the server site
(or benefit from and existing daemon,
<command>sshd</command>, <command>telnetd</command>, or
<command>sendmail</command>/<command>procmail</command>).
</para>
<para>
It is assumed that you know or are willing to learn
how to configure an IP emulator
(<command>pppd</command>, <command>slirp</command>)
or an Internet access daemon and its associated library
(<productname>SOCKS</productname>, <productname>Term</productname>)
on each side, according to your needs in terms of connectivity
and to your access rights, with your recompiling some software if needed.
</para>
<para>
Last but not least, so that you can use the hacks described in this document,
it is assumed that you are root on the side of the firewall
that needs full transparent IP access to the other side.
Indeed, you'll want to run the PPP daemon on this side which
allows for use the normal kernel packet routing facilities.
In case you're not root on this side, your case is not desperate though:
indeed, Barak Pearlmutter's
<ulink url="http://www.linuxdoc.org/HOWTO/mini/Term-Firewall.html"
>Term-Firewall mini-HOWTO</ulink>
describes how to use <productname>Term</productname>,
a purely userland program,
to the end of piercing firewalls.
Although there's no HOWTO, I suspect <productname>SOCKS</productname>
could also be used as a way to pierce firewalls without have root privilege;
I will gladly accept patches to this HOWTO that describe
such a method of piercing firewalls.
</para>
</sect2>
<sect2>
<title>Downloading software</title>
<para>
Most software named in this HOWTO should be available
from your standard Linux distribution, possibly among contrib's.
At least, the four first below are available in
as <filename>.rpm</filename> and <filename>.deb</filename> packages.
In case you want to fetch the latest sources
(after all, one of the ends of the connection may not be running under Linux),
use the addresses below:
<itemizedlist>
<listitem>
<para>
<command>SLiRP</command> can be found at
<ulink url="http://blitzen.canberra.edu.au/slirp"
>http://blitzen.canberra.edu.au/slirp</ulink>
and/or
<ulink url="ftp://www.ibc.wustl.edu/pub/slirp_bin/"
>ftp://www.ibc.wustl.edu/pub/slirp_bin/</ulink>.
</para>
</listitem>
<listitem>
<para>
<command>zsh</command> can be found at
<ulink url="http://www.zsh.org/">http://www.zsh.org/</ulink>.
</para>
</listitem>
<listitem>
<para>
<command>ppp</command> can be found at
<ulink url="ftp://cs.anu.edu.au/pub/software/ppp/"
>ftp://cs.anu.edu.au/pub/software/ppp/</ulink>.
</para>
</listitem>
<listitem>
<para>
<command>ssh</command> can be found at
<ulink url="http://www.openssh.com/"
>http://www.openssh.com/</ulink>.
</para>
</listitem>
<listitem>
<para>
<command>fwprc</command>, <command>cotty</command>
and <command>getroute.pl</command> can be found at
<ulink url="http://fare.tunes.org/files/fwprc/"
>http://fare.tunes.org/files/fwprc/</ulink>.
</para>
</listitem>
<listitem>
<para>
<command>httptunnel</command> can be found at
<ulink url="http://www.nocrew.org/software/httptunnel/"
>http://www.nocrew.org/software/httptunnel/</ulink>.
</para>
</listitem>
<listitem>
<para>
<command>mailtunnel</command> can be found at
<ulink url="http://www.detached.net/mailtunnel/"
>http://www.detached.net/mailtunnel/</ulink>.
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
<sect1>
<title>Understanding the problem</title>
<para>
Understanding a problem is the first half of the path to solving it.
</para>
<sect2>
<title>Giving names to things</title>
<para>
If you want this hack to work for you,
you'll have to get an idea of how it works,
so that in case anything breaks,
you know where to look for.
</para>
<para>
The first step toward understanding the problem
is to give a name to relevant concepts.
</para>
<para>
As usual, we'll herein call "client" the machine
that decides to initiate the connection,
as well as programs and files on that machine.
Conversely, we'll call "server" that waits for connections and accepts them,
as well as programs and files on that machine.
Firewall piercing is useful when the two machines are separated by a firewall,
such that it is possible for the server to accept some kind of connections,
whereas the client might or might not be able to accept any.
A tunnel will be created between the two machines
that allows full IP traffic despite the firewall.
</para>
<para>
Usually, when piercing firewalls, the client is the machine behind a firewall:
it has limited access to the internet,
but can somehow open some kind of connection to the server.
The server is a machine with full internet access,
that will serve as a proxy for the client to access all of the internet.
In a VPN, the firewall the roles might be reversed,
with the client being on the internet, and
the server serving as a proxy for the client to access some private network.
</para>
</sect2>
<sect2>
<title>The main problem</title>
<para>
The main problem with firewall piercing is to create a tunnel:
a continuous connection from the client machine
to a server machine on the other side of the firewall,
that allows for bidirectional exchange of information.
Optionally, this connection should be a secure one.
The secondary problem is to transform this connection
into a full IP access for normal programs to use transparently.
</para>
<para>
For the main problem, we'll assume that
either (1) you can establish normal TCP/IP connections
from the client side of the firewall to some port on a server machine
where a sshd runs or can be set to run, or
(2) you can somehow establish a telnet connection through a telnet proxy.
In case you cannot, we will give you pointers
to other software that allows you
to pierce a tunnel accross a firewall.
Although we only give a secure solution in the first case,
you can hack your own secure solution in the other cases,
if you understand the principle
(if you don't, someone, e.g. I, can do it for you in exchange for money).
</para>
</sect2>
<sect2>
<title>The secondary problem</title>
<para>
For the secondary problem,
IP emulators (<command>pppd</command> or <productname>SLiRP</productname>)
are run on each side of the tunnel.
</para>
<para>
On the side that wants full IP access to the other side,
you'll want to run <command>pppd</command>.
On the other side, you want to run <command>pppd</command>
if you also want full IP access to the first side,
or <productname>SLiRP</productname> if you want to prevent any access.
Go to your usual <command>pppd</command> or <productname>SLiRP</productname>
documentation for more information,
if you have specific needs not covered by the examples given below.
</para>
<para>
Although this is conceptually trivial,
it nonetheless requires a few silly tricks, so as to work, since
(a) in case you're using some kind of programmed interactive shell session
to start the server's IP emulator on either side, you need to correctly
synchronize the start of the IP emulator on the other side,
so as not to send garbage into the shell session,
and
(b) IP emulators are designed to be run on a "tty" interface
so you have to convert your tunnel's interface into a tty one.
</para>
<para>
Issue (a) is just your usual synchronization problem,
and doesn't even exist if you use <command>ssh</command>,
that transparently handles server's command launching.
</para>
<para>
Issue (b) requires the use of a simple external utility.
We wrote one, <command>cotty</command> just for that purpose.
</para>
<para>
&lt;FLAME ON&gt;
</para>
<para>
Among the silly problems caused by <command>pppd</command>
maintainers' shortmindedness (no more true in recent Linux versions),
you can only run it through
either a device in <filename>/dev</filename> or the current tty.
You cannot run it through a pair of pipe
(which would be the obvious design).
This is fine for the server's <command>pppd</command> if any,
as it can use the <command>telnet</command> or <command>ssh</command>
session's <filename>tty</filename>;
but for the client's <command>pppd</command>, this conflicts with
the possible use of <command>telnet</command>
as a way to establish a connection.
</para>
<para>
Indeed, <command>telnet</command>, too wants to be on a tty;
it behaves <emphasis>almost</emphasis> correctly with a pair of pipe,
except that it will still insist on doing ioctl's to the current tty,
with which it will interfere;
using <command>telnet</command> without a tty also causes race conditions,
so that the whole connection will fail on "slow" computers
(<command>fwprc</command> 0.1 worked perfectly on a P/MMX 233,
one time out of 6 on a 6x86-P200+, and never on a 486dx2/66).
All in all, when using <command>telnet</command>,
you need <command>cotty</command> to run as a daemon
to copy output from one tty on which runs <command>pppd</command>
into another tty on which runs <command>telnet</command>, and conversely.
</para>
<para>
If I find the sucker (probably a <productname>MULTICS</productname> guy,
though there must have been <productname>UNIX</productname> people
stupid enough to copy the idea)
who invented the principle of "tty" devices
by which you read and write from a "same" pseudo-file,
instead of having clean pairs of pipes,
I strangle him!
</para>
<para>
&lt;/FLAME&gt;
</para>
</sect2>
</sect1>
<sect1>
<title>Secure solution: piercing using ssh</title>
<sect2>
<title>Principle</title>
<para>
Let's assume that your firewall administrator allows
transparent TCP connections to some port on some server machine
on the other side of the firewall
(be it the standard SSH port 22, or an alternate destination port,
like the HTTP port 80 or whatever),
or that you somehow managed to get some port in one side of the firewall
to get redirected to a port on the other side
(using <command>httptunnel</command>, <command>mailtunnel</command>,
some tunnel over <command>telnet</command>, or whatelse).
</para>
<para>
Then, you can run an <command>sshd</command> on the server side port,
and connect to it with an <command>ssh</command> on the client side port.
On both sides of the <command>ssh</command> connection,
you run IP emulators ( <command>pppd</command>),
and there you have your VPN, Virtual Public Network,
that circumvents the stupid firewall limitations,
with the added bonus of being encrypted for privacy
(beware: the firewall administrator still knows the other end of the tunnel,
and whatever authentication information you might have sent before to run
<command>ssh</command>).
</para>
<para>
The exact same technology can be used to build a VPN, Virtual Private Network,
whereby you securely join physical sites into a one logical network
without sacrificing security with respect to the transport network
between the sites.
</para>
</sect2>
<sect2>
<title>A sample session</title>
<para>
Below is a sample script for you to adapt to your needs.
It uses the array feature of <command>zsh</command>,
but you may easily adapt it to your favorite shell.
Use option <command>-p</command> for <command>ssh</command>
to try another port than port 22
(but then, be sure to run <command>sshd</command> on same port).
</para>
<para>
Note that the script supposes that <command>ssh</command>
can login without your having to interactively type your password
(indeed, it's controlling tty will be connected to <command>pppd</command>,
so if it asks for a password, you lose).
This can be done either by ssh keys in your
<filename>&tilde;/.ssh/authorized_keys</filename>
that either do not require a password,
or that you unlock using <command>ssh-agent</command>
or <command>ssh-askpass</command>.
See your SSH documentation.
Actually, you might also use a <command>chat</command> script
to enter your password,
but this is definitely <emphasis>not</emphasis> the Right Thing.
</para>
<para>
If you are not <command>root</command> on the server end,
or simply if want to screen your client's network from outbound connections,
you can use <command>slirp</command> instead of <command>pppd</command>
as the server's PPP emulator.
Just uncomment the relevant line.
</para>
<para>
<programlisting>
<![CDATA[
#!/bin/zsh -f
SERVER_ACCOUNT=root@server.fqdn.tld
SERVER_PPPD="pppd ipcp-accept-local ipcp-accept-remote"
#SERVER_PPPD="pppd" ### This usually suffices if it's in /usr/sbin/
#SERVER_PPPD="/home/joekluser/bin/slirp ppp"
CLIENT_PPPD=( pppd
silent
10.0.2.15:10.0.2.2
### For debugging purposes, you may uncomment the following:
# updetach debug
### Another potentially useful option (see section on Routing):
# defaultroute
)
$CLIENT_PPPD pty "ssh -t $SERVER_ACCOUNT $SERVER_PPPD"
]]>
</programlisting>
</para>
<para>
Note that default options from your <filename>/etc/ppp/options</filename>
or <filename>&tilde;/.slirprc</filename>
may break this script, so remove any unwanted option from there.
</para>
<para>
Also note that <literal>10.0.2.2</literal>
is the default setting for <command>slirp</command>,
which might or not fit your specific setup.
In any case, you should most likely be using some address in one
of the ranges reserved by RFC 1918 for private networks:
<literal>10.0.0.0/8</literal>,
<literal>172.16.0.0/12</literal> or <literal>192.168.0.0/16</literal>.
The firewall-protected LAN might already be using some of them,
and avoiding clashes is your responsibility.
For more customization, please read the appropriate documentation.
</para>
<para>
If your client's <command>pppd</command> is old or non-linux (e.g. BSD)
and hasn't got the <command>pty</command> option, use
<programlisting>
cotty -d -- $CLIENT_PPPD -- ssh -t $SERVER_ACCOUNT $SERVER_PPPD
</programlisting>
Catches: don't put quotes around commands given to cotty,
as they are just <command>exec()</command>'d as is,
and don't forget to specify the full path for
the server's <command>pppd</command>
if it's not in the standard path setup by <command>ssh</command>.
</para>
<para>
Automatic reconnection is left as an exercise to the reader
(hint: the <command>nodetach</command> option from <command>pppd</command>
might help for that).
</para>
</sect2>
</sect1>
<sect1>
<title>Unsecure solution: piercing using telnet</title>
<sect2>
<title>Principle</title>
<para>
If all you can do is <command>telnet</command>
(because of a <command>telnet</command> proxy),
then this solution might be fit for you.
</para>
<para>
The firewall-piercing program, <command>fwprc</command>,
will use a "tty proxy", <command>cotty</command>,
that opens two pseudo-tty devices,
launches some command on each of those devices' slaves,
and stubbornly copies every character that one outputs
to the tty that serves as input of the other command.
One command will be telnet connection to server site,
and the other will be the client's <command>pppd</command>.
<command>pppd</command> can then open and control the telnet session
with a chat script as usual.
</para>
<para>
Actually, if your telnet proxy allows connection to an arbitrary port,
and if you can reliably run a daemon on the server host
(with a cron job to relaunch it in case of breakage),
then you'd better write some program that will just connect
a client side port to the server side port through the proxy,
so you can use the above secure solution,
possibly using some variant of
<programlisting>
ssh -t -o "ProxyCommand ..."
</programlisting>
(if you submit it to me, I'll gladly integrate such a solution
to the <command>fwprc</command> distribution).
</para>
<para>
Note: if you must use the unsecure telnet-based solution,
be sure that nothing lies in your target account
that you want to keep secret or untampered,
since the password will be sent in clear text accross the Internet.
If you can control these things, a one-time-password system,
or an explicit cryptographic challenge system will enhance your security,
although it will make automated connection scripts much more complex.
</para>
</sect2>
<sect2>
<title>fwprc</title>
<para>
I wrote a very well self-documented script
to pierce firewalls, <command>fwprc</command>,
available from
<ulink url="http://fare.tunes.org/files/fwprc/">my site</ulink>,
together with <command>cotty</command>
(which is required by <command>fwprc</command> <literal>0.2</literal>
and later).
At the time of my writing these lines, latest versions are
<command>fwprc</command> <literal>0.3e</literal> and
<command>cotty</command> <literal>0.4c</literal>.
</para>
<para>
The name "fwprc" is voluntarily made unreadable and unpronounceable,
so that it will confuse the incompetent paranoid sysadm
who might be the cause of the firewall that annoys you
(of course, there can be legitimate firewalls, too,
and even indispensable ones;
security is all a matter of <emphasis>correct</emphasis> configuration).
If you must read it aloud, choose the worst way you can imagine.
</para>
<para>
CONTEST! CONTEST! Send me an audio file
with a digital audio recording of how you pronounce "fwprc".
The worst entry will win a free upgrade and his name
on the <command>fwprc</command> <literal>1.0</literal> page!
</para>
<para>
I tested the program in several settings,
by configuring it through resource files.
But of course, by Murphy's law, it will break for you.
Feel free to contribute enhancements that will make life
easier to other people who'll configure it after you.
</para>
</sect2>
<sect2>
<title>.fwprcrc</title>
<para>
<command>fwprc</command> can be customized through a file
<filename>.fwprcrc</filename>
meant to be the same on both sides of the firewall.
Having several alternate configurations to choose from is sure possible
(for instance, <emphasis>I</emphasis> do it),
and is left as an exercise to the reader.
</para>
<para>
To begin with, copy the appropriate section of <command>fwprc</command>
(the previous to last) into a file named <filename>.fwprcrc</filename>
in your home directory.
Then replace variable values with stuff that fits your configuration.
Finally, copy to the other host, and test.
</para>
<para>
Default behavior is to use <command>pppd</command> on the client,
and <command>slirp</command> on the server.
To modify that, you can redefine the appropriate function
in your <filename>.fwprcrc</filename> with such a line as:
<programlisting>
remote_IP_emu () { remote_pppd }
</programlisting>
</para>
<para>
Note that <productname>SLiRP</productname>
is safer than <command>pppd</command>,
and easier to have access to,
since it does not require being root on the server machine,
and needn't additional firewall configuration to prevent
connections from the outside world into the firewalled network.
The basic functionality in <productname>SLiRP</productname> works quite well,
but I haven't managed to get some advertised pluses to work
(like run-time controllability).
Of course, since it is free software,
feel free to hack the source
so as to actually implement or fix whichever feature you need.
</para>
</sect2>
</sect1>
<sect1>
<title>Routing</title>
<para>
Piercing the firewall is not everything.
You must also route the packets
from the client side of the firewall to the server side.
This section tackles the basic settings specific
about routing accross a tunnel.
For more detailed explanations of routing,
see the relevant HOWTOs and man pages
about networking, routing and masquerading.
</para>
<sect2>
<title>The catch</title>
<para>
The catch is that although your network administration would tell you
to setup your some router on your client side's as the default route,
(this may be relevant if you want to have a specific route
to the networks on the client of the firewall),
you should setup PPP link as the route to the networks on the server side.
</para>
<para>
In other words, your default route should point to a router
on whichever side of the tunnel that gives you access to the Internet.
</para>
<para>
Most importantly, packets sent to the server host as part of running the tunnel
should be routed through your usual network
(e.g. your default ethernet router);
otherwise, your kernel will have problems,
as it tries to route through the inside the tunnel
the very packets that ought to constitute the outside of the tunnel.
</para>
<para>
Thus, you'll have to setup correct routes
in your network startup configuration.
The precise location of your routing configuration data
depends on your distribution, but it is typically
under <filename>/etc/init.d/network</filename>
or <filename>/etc/network/</filename>;
similarly, your PPP configuration is typically
in <filename>/etc/ppp/</filename>,
and the proper place to configure its routes is usually
in <filename>ip-up</filename> or <filename>ip-up.d/</filename>.
(Tip: to identify your distribution-specific file locations,
you must read the documentation of your distribution and otherwise
<ulink url="http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?RTFM">RTFM</ulink>;
alternatively use <command>grep</command> recursively
on your <filename>/etc</filename>;
at worst, trace what happens at boot time,
as configured in your <filename>/etc/inittab</filename>.)
</para>
<para>
When piercing a tunnel from a roaming laptop on the Internet
into a protected network, the script <command>getroute.pl</command>
(available from the <command>fwprc</command> distribution)
gives the current route to the server host that is the other end of the tunnel.
</para>
<para>
Once you can route packets to the server side of the tunnel,
you might want to setup your machine as a router for all your pals
on the client side of the firewall, achieving a full-fledged shared VPN.
This is not specific to Firewall-Piercing, so just you read
the relevant HOWTOs about networking, routing and masquerading.
Also, for security reasons, be sure to also setup
a proper firewall on your machine,
especially if you're going to be a router for other people.
</para>
<para>
Finally, be reminded that if you're using <command>pppd</command>
on the server end of the tunnel
(as opposed to user-mode <command>slirp</command>),
you will have to configure proper routes and firewall rules
on the server side of the tunnel, too.
</para>
</sect2>
<sect2>
<title>Example of routing</title>
<para>
In this example, your client machine is connected to a firewalled LAN
through ethernet device <filename>eth0</filename>.
Its IP address is <literal>12.34.56.78</literal>;
its network is <literal>12.34.56.0/24</literal>;
its router is <literal>12.34.56.1</literal>.
</para>
<para>
Your network administrator may have told you
to use <literal>12.34.56.1</literal>
as default router, but you shouldn't.
You should only use it as a route to the client side of the firewall.
</para>
<para>
Let's suppose the client side of your firewall is made of networks
<literal>12.34.0.0/16</literal> and <literal>12.13.0.0/16</literal>,
and of host <literal>11.22.33.44</literal>.
To make them accessible through your client router,
add these routes to your global network startup script:
<programlisting>
route add -net 12.34.0.0 netmask 255.255.0.0 gw 12.34.56.1
route add -net 12.13.0.0 netmask 255.255.0.0 gw 12.34.56.1
route add -host 11.22.33.44 gw 12.34.56.1
</programlisting>
You must also keep the route to the client's local network,
necessary for linux kernel 2.0 and earlier,
but unnecessary for linux kernel 2.2 and later
(that implicitly adds it during the <command>ifconfig</command>):
<programlisting>
route add -net 12.34.56.0 netmask 255.255.255.0 dev eth0
</programlisting>
On the other hand, you <emphasis>must</emphasis> remove
any default route from your scripts.
Delete or comment away a line like:
<programlisting>
route add default gw 12.34.56.1
</programlisting>
Note that it is also possible to remove the route from the running
kernel configuration without rebooting, by the following command:
<programlisting>
route del default gw 12.34.56.1
</programlisting>
Then you can have <command>pppd</command> setup a default route automatically
when it starts by using its <command>defaultroute</command> option.
Alternatively, you can add it afterwards:
<programlisting>
route add default gw 10.0.2.2
</programlisting>
If you don't want <command>pppd</command> as a default route,
because the Internet access is available on your side of the firewall,
and if you instead want network <literal>98.76.48.0/20</literal>
to be routed through the tunnel,
except from host <literal>98.76.54.32</literal>
that serves as the other end of the tunnel,
then add the following lines to your <filename>/etc/ppp/ip-up</filename>:
<programlisting>
route add -host 98.76.54.32 gw 12.34.56.1
route add -net 98.76.48.0 netmask 255.255.240.0 gw 10.0.2.2
</programlisting>
If you're a laptop and your current LAN moves,
and yet you want to keep your current route to <literal>98.76.54.32</literal>,
whatever it be, then use <command>getroute.pl</command> as follows
to automatically find the right gateway
in the <command>route add -host</command> command:
<programlisting>
$(getroute.pl 98.76.54.32)
</programlisting>
Note that if you have them in your <filename>/etc/hosts</filename>,
you might use symbolic names instead of numerical IP addresses
(and you might even use FQDN's, if you trust the DNS never to fail).
</para>
</sect2>
</sect1>
<sect1>
<title>Reverse piercing</title>
<sect2>
<title>Rationale</title>
<para>
Sometimes, only one side of the firewall can launch telnet sessions
into the other side; however, some means of communication is possible
(typically, through e-mail).
Piercing the firewall is still possible, by triggering with
whatever messaging capability is available
a telnet connection from the ``right'' side of the firewall to the other.
</para>
<para>
<command>fwprc</command> includes code to trigger such connections
from an OpenPGP-authentified email message;
all you need is add <command>fwprc</command>
as a <command>procmail</command> filter
to messages using the protocol,
(instructions included in <command>fwprc</command> itself).
Note however, that if you are to launch <command>pppd</command>
with appropriate privileges,
you might need create your own suid wrapper to become root.
Instructions enclosed in <command>fwprc</command>.
</para>
<para>
Also, authentified trigger does not remotely mean secure connection.
You should really use <command>ssh</command> (perhaps over telnet)
for secure connections.
And then, beware of what happens between the triggering of a telnet
connection, and <command>ssh</command> taking over that connection.
Contribution in that direction welcome.
</para>
</sect2>
<sect2>
<title>Getting the trigger message</title>
<para>
If you are firewalled, your mail may as well be in a central mailserver
that doesn't do procmail filtering or allow telnet sessions.
No problem! You can run <command>fetchmail</command>
in daemon mode (or within a cron job)
to poll your mailserver and deliver mail to your linux system
which itself will have been configured to use <command>procmail</command>
at delivery.
Note that if you run <command>fetchmail</command> as a background daemon,
it will lock away any other fetchmail that you'd like to run
only at other times, like when you open a <command>fwprc</command>;
of course, if you can also run a fetchmail daemon as a fake user.
Too frequent a poll won't be nice to either the mailserver or your host.
Too infrequent a poll means you'll have to wait before the message gets read
and the reverse connection gets established.
I use two-minute poll frequency.
</para>
</sect2>
<sect2>
<title>Other automated tools for reverse piercing</title>
<para>
Another way to poll for messages, when you don't have a mailbox,
but do have outbound FTP access, is to use
<ulink url="http://dhirajbhuyan.hypermart.net/ftp-tunnel.html"
>FTP tunnel</ulink>.
</para>
<para>
A tool to maintain a permanent connection between a firewalled host and
an external proxy, so as to export services from the host to the world, is
<ulink url="http://www.employees.org/~hek2000/projects/firewallTunnel/"
>firewall tunnel</ulink>.
</para>
</sect2>
</sect1>
<sect1>
<title>Final notes</title>
<sect2>
<title>Other settings</title>
<para>
I have no idea how to pierce firewalls with lesser operating systems,
but you can take one of these old disused computers
(about anything with 8MB of RAM and an ethernet card should do),
install Linux or BSD as on it, and pierce the firewall with it,
while serving as a router for other machines running lesser OSes.
See appropriate HOWTOs about routing, IP forwarding, NAT, etc.
</para>
<para>
I don't know the details, but a promising tool to pierce firewalls is
Chris Mason's <ulink url="http://www.r00t3d.org.uk/">Bouncer</ulink>,
which acts as a SOCKS-proxy-over-SSL.
</para>
<para>
There are other kinds of firewalls
than those that allow for direct ssh or telnet connections.
As long as a continuous flow of packets
may transmit information through a firewall in both directions,
it is possible to pierce it;
only the price of writing the piercer may be higher or lower.
</para>
<para>
In a very easy case, we saw that you can just launch <command>ssh</command>
over a pty master and do some <command>pppd</command> in the slave tty.
You may even want to do it without an adverse firewall,
just so as to build a secure ``VPN'' (Virtual Private Network).
The <ulink url="http://www.linuxdoc.org/HOWTO/mini/VPN.html"
>VPN mini-HOWTO</ulink>
gives all the details you need about this.
We invite you, as an exercise,
to modify <command>fwprc</command>
so as to use this technique,
or perhaps even so as to use it
inside a previous non-secure <command>fwprc</command> session.
</para>
<para>
Now, if the only way through the firewall is a WWW proxy
(usually, a minimum for an Internet-connected network),
you might want to use
<ulink url="http://www.snurgle.org/~griffon/">Chris Chiappa</ulink>'s
script
<ulink url="http://www.snurgle.org/~griffon/ssh-https-tunnel"
>ssh-https-tunnel</ulink>.
</para>
<para>
Another promising program for piercing through HTTP is
<ulink url="http://lars.nocrew.org/">Lars Brinkoff</ulink>'s
<ulink url="http://www.nocrew.org/software/httptunnel/">httptunnel</ulink>,
a http server and client combination that achieves a TCP/IP tunnel connection
through the proxy-friendly HTTP protocol.
You should then be able to run <command>fwprc</command>
(preferably over <command>ssh</command>)
over that connection, although I haven't tried it yet.
Could anyone test and report?
Note that <command>httptunnel</command> is still under development,
so you may help implement
the features it currently lacks,
like, having multiple connections, and/or serving fake pages
so as to mislead suspicious adverse firewall administrators.
</para>
<para>
Whatever goes through your firewall,
be it telnet, HTTP or other TCP/IP connections,
or something real weird like DNS queries, ICMP packets, e-mail
(see <ulink url="http://www.detached.net/mailtunnel/">mailtunnel</ulink>,
<ulink url="http://www.detached.net/icmptunnel/">icmptunnel</ulink>),
or whatelse,
you can always write a tunnel client/server combination,
and run a <command>ssh</command> and/or PPP connection through it.
The performance mightn't be high,
depending on the effective information communication rate
after paying the overhead for coding around filters and proxies;
but such a tunnel is still interesting as long as it's good enough
to use <command>fetchmail</command>, <command>suck</command>,
and other non-interactive programs.
</para>
<para>
If you need cross a 7-bit line, you'll want to use SLIP instead of PPP.
I never tried, because lines are more or less 8-bit clean these days,
but it shouldn't be difficult.
If necessary, fall back to using the
<ulink url="http://www.linuxdoc.org/HOWTO/mini/Term-Firewall.html"
>Term-Firewall mini-HOWTO</ulink>.
</para>
<para>
If you have an 8-bit clean connection and you're root on linux both sides
of the firewall, you might want to use ethertap for better performance,
encapsulating raw ethernet communications on top of your connection.
David Madore has written ethertap-over-TCP and ethertap-over-UDP tunneling
<ulink url="ftp://quatramaran.ens.fr/pub/madore/misc/"
>ftp://quatramaran.ens.fr/pub/madore/misc/</ulink>.
There remains to write some ethertap-over-tty to combine with fwprc-like tools.
</para>
<para>
If you really need more performance than you can get
while paying for a user-space sequential communication tunnel
through which to run PPP,
then you're in the very hard case
where you might have to re-hack a weird IP stack,
using (for instance) the Fox project's packet-protocol functors.
You'll then achieve some direct IP-over-HTTP, IP-over-DNS, IP-over-ICMP,
or such, which requires not only an elaborate protocol,
but also an interface to an OS kernel, both of which are costly to implement.
</para>
<para>
Finally, if you're not fighting against an adverse firewall,
but just building your own VPN, there is a large offer of VPN tools,
and although the tricks I present are simple, work well,
and might be enough for your needs, it could be a good idea
to look at this evolving offer (that I do not know much about)
for a solution that fits your requirements of performance and maintainability.
</para>
</sect2>
<sect2>
<title>HOWTO maintenance</title>
<para>
I felt it was necessary to write it,
but I don't have that much time for that,
so this mini-HOWTO is very rough.
Thus will it stay,
until I get enough feedback so as to know what sections to enhance,
or better, until someone comes and takes over maintenance for the mini-HOWTO.
Feedback welcome. Help welcome. mini-HOWTO maintenance take-over welcome.
</para>
<para>
In any case, the above sections have shown many problems
whose solution is just a matter of someone (you?)
spending some time (or money, by hiring someone else)
to sit down and write it:
nothing conceptually complicated,
though the details might be burdensome or tricky.
</para>
<para>
Do not hesitate to contribute more problems, and hopefully more solutions,
to this mini-HOWTO.
</para>
</sect2>
<sect2>
<title>Related Documents</title>
<para>
The <ulink url="http://www.linuxdoc.org/">LDP</ulink>
publishes many documents related to this
<ulink url="http://www.linuxdoc.org/HOWTO/HOWTO-INDEX/mini.html"
>mini-HOWTO</ulink>.
most notably the
<ulink url="http://www.securityportal.com/lskb/"
>Linux Security Knowledge Base</ulink>,
the <ulink url="http://www.linuxdoc.org/HOWTO/VPN.html">VPN HOWTO</ulink>
and the <ulink url="http://www.linuxdoc.org/HOWTO/mini/VPN.html"
>VPN mini-HOWTO</ulink>.
For more general questions about networking, routing and firewalling,
start from the
<ulink url="http://www.linuxdoc.org/HOWTO/Networking-Overview-HOWTO.html"
>Networking Overview HOWTO</ulink>.
See also the
<ulink url="http://www.linux-firewall-tools.com/linux/"
>Linux Firewall and Security site</ulink>.
</para>
<para>
Then again, when facing a problem with some program,
one reflex for any Linux user should be to
<ulink url="http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?RTFM">RTFM</ulink>:
Read The Fscking Manual pages for the considered programs.
</para>
</sect2>
<sect2>
<title>Final Word</title>
<para>
I've come to the conclusion that much like the need for Design Patterns
came directly from the fact that people were using inferior languages
like <productname>C++</productname> or <productname>Java</productname>
that don't allow to directly express higher-level programming constructs
(whereas good languages such as <productname>LISP</productname>
allow to express them),
the need HOWTOs comes directly from the fact that
<productname>Linux</productname> and <productname>UNIX</productname> systems
are inferior operating systems that do not allow to directly express
those simple tasks that people attempt to do with them.
</para>
<para>
If you think that all this mucking around with stupid scripts and silly HOWTOs
is overly complicated and that a decent computer system ought
to automate it all for you, then welcome with me among
<ulink url="http://www.research.microsoft.com/~daniel/preface.html"
>UNIX haters</ulink>
and other people who hate current low-level operating systems,
and yearn for declarative computing systems
that take care of the silly details and let us focus on things that matter.
(Maybe have a peek at my own
<ulink url="http://tunes.org/">TUNES project</ulink>).
</para>
</sect2>
<sect2>
<title>Extra copy of IMPORTANT DISCLAIMER --- BELIEVE IT!!!</title>
<para>
<quote><emphasis>I hereby disclaim all responsibility for
<emphasis>your</emphasis> use of this hack.
If it backfires on you in any way whatsoever,
that's the breaks. Not my fault.
If you don't understand the risks inherent in doing this, don't do it.
If you use this hack and it allows vicious vandals
to break into your company's computers and costs you your job and
your company millions of dollars, well that's just tough nuggies.
Don't come crying to me.</emphasis>
</quote>
</para>
</sect2>
</sect1>
</article>