LDP/LDP/retired/Term-Firewall.sgml

418 lines
12 KiB
Plaintext

<!DOCTYPE ARTICLE PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
<article>
<articleinfo>
<title>Using Term to Pierce an Internet Firewall mini-HOWTO</title>
<copyright><year>1996</year><holder>Barak Pearlmutter</holder></copyright>
<copyright><year>2001</year><holder>David C. Merrill</holder></copyright>
<author>
<firstname>Barak</firstname>
<surname>Pearlmutter</surname>
<affiliation>
<address><email>bap@cs.unm.edu</email></address>
</affiliation>
</author>
<author>
<firstname>David</firstname>
<othername>C.</othername>
<surname>Merrill</surname>
<affiliation>
<address>david -AT- lupercalia.net</address>
</affiliation>
</author>
<revhistory>
<revision>
<revnumber>1.1</revnumber>
<date>2001-07-14</date>
<authorinitials>dcm</authorinitials>
<revremark>
Cleaned up a bit, reorganized a bit, converted to DocBook SGML
and relicensed under GFDL.
</revremark>
</revision>
<revision>
<revnumber>1.0</revnumber>
<date>1996-07-15</date>
<authorinitials>pb</authorinitials>
<revremark>Initial Release.</revremark>
</revision>
</revhistory>
<abstract>
<para>
This document explains how to use the <command>term</command> program
to pierce a firewall from the inside, even without root privileges.
</para>
<para>
Term is an old program that almost no one uses anymore,
because the 7-bit serial lines it is meant to cross are nowhere
to be found anymore, and full IP ppp access is dirt cheap.
</para>
<para>
<important>
<para>
<emphasis role="strong">Archived Document Notice: </emphasis>
This document has been archived by the LDP because it does not apply
to modern Linux systems. It is no longer being actively maintained.
</para>
</important>
</para>
</abstract>
</articleinfo>
<sect1 id="preface">
<title>Preface</title>
<sect2 id="disclaimer">
<title>Disclaimer</title>
<para>
While every precaution has been taken in the preparation of this document,
the Linux Documentation Project and the author(s) assume no responsibility
for errors or omissions, or for damages resulting from the use of the
information contained herein.
</para>
</sect2>
<sect2 id="license">
<title>License</title>
<para>
This document is made available under the terms of the
<ulink url="http://www.gnu.org/copyleft/fdl.html"><citetitle>GNU Free Documentation License (GFDL)</citetitle></ulink>,
which is hereby incorporated by reference.
</para>
</sect2>
</sect1>
<sect1 id="introduction">
<title>Introduction</title>
<para>
The <command>term</command> program is usually used to provide host-to-host services
over a modem or serial line.
However, sometimes it is useful to establish a term
connection between two machines that communicate via telnet.
The most
interesting example is connecting two hosts which are
separated by ethernet firewalls or SOCKS servers. Such firewalls
provide facilities for establishing a telnet connection through the
firewall, typically by using the SOCKS protocol, to allow inside
machines to get connections out, and requiring outside users to telnet
first to a gateway machine which requires a one-time password. These
firewalls make it impossible to, for instance, have X clients on an
inside machine communicate with an X server on an outside machine.
But, by setting up a term connection, these restrictions can all be
bypassed quite conveniently, at the user level.
</para>
</sect1>
<sect1 id="basics">
<title>The Basic Procedure</title>
<para>
Setting up a term connection over a telnet substrate is a two-phase
process. First your usual telnet client is used to set up a telnet
connection and log in. Next, the telnet client is paused and control
of the established telnet connection is given to term.
</para>
</sect1>
<sect1 id="details">
<title>Detailed Directions</title>
<para>
First, from a machine inside the firewall, telnet to a target machine
outside the firewall and log in.
</para>
<para>
Unless you are under linux and will be using the proc filesystem (see
below) make sure your shell is an sh style shell. Ie if your default
shell is a csh variant, invoke telnet by:
</para>
<para><screen>setenv SHELL /bin/sh; telnet machine.outside</screen></para>
<para>
After logging in, on the remote (outside) machine invoke the command:
</para>
<para><screen>term -r -n off telnet</screen></para>
<para>
Now break back to the telnet prompt on the local (inside) machine,
using <literal>^]</literal> or whatever, and use the telnet shell escape command
<literal>!</literal> to invoke term:
</para>
<para><screen>telnet&gt; ! term -n on telnet &gt;&amp;3 &lt;&amp;3</screen></para>
<para>
That's it!
</para>
<para>
If you have a variant telnet, you might have to use some other file
descriptor than 3; easy to check using strace. But three seems to
work on all bsd descendent telnet clients I've tried, under both SunOS
4.x and the usual linux distributions.
</para>
<para>
Some telnet clients do not have the ! shell escape command. Eg the
telnet client distributed with Slackware 3.0 is one such client. The
sources that the Slackware telnet client is supposedly built from
</para>
<para>
<ulink url="ftp://ftp.cdrom.com:/pub/linux/slackware-3.0/source/n/tcpip/NetKit-B-0.05.tar.gz">
<citetitle>ftp://ftp.cdrom.com:/pub/linux/slackware-3.0/source/n/tcpip/NetKit-B-0.05.tar.gz</citetitle></ulink>
</para>
<para>
A simple solution is therefore to
obtain these sources and recompile them. This unfortunately is a task
I have had no luck with. Plus, if you are running from inside a SOCKS
firewall, you will need a SOCKSified telnet client anyway. To that
end, I was able to compile a SOCKSified telnet client from:
</para>
<para><ulink url="ftp://ftp.nec.com/pub/security/socks.cstc/socks.cstc.4.2.tar.gz">
<citetitle>ftp://ftp.nec.com/pub/security/socks.cstc/socks.cstc.4.2.tar.gz</citetitle></ulink>
</para>
<para>
or, if you're outside the USA,
</para>
<para><ulink url="ftp://ftp.nec.com/pub/security/socks.cstc/export.socks.cstc.4.2.tar.gz">
<citetitle>ftp://ftp.nec.com/pub/security/socks.cstc/export.socks.cstc.4.2.tar.gz</citetitle></ulink>
</para>
<para>
Alternatively, under linux kernels up to 1.2.13, you can pause the
telnet with <literal>^]^z</literal>, figure out its pid, and invoke:
</para>
<para><screen>term -n on -v /proc/&,t;telnetpid&gt;/fd/3 telnet</screen></para>
<para>
This doesn't work with kernels after 1.3.x, which closed some
mysterious security hole by preventing access to these fd's by
processes other than the owner process and its children.
</para>
</sect1>
<sect1 id="termsockets">
<title>Multiple Term Sockets</title>
<para>
It is a good idea to give the term socket an explicit name.
This is the <literal>telnet</literal>; argument in the invocations
of term above.
Unless you have the TERMSERVER environment variable set to telnet as
appropriate, you invoke term clients with the -t switch,
e.g., <literal>trsh -t telnet</literal>.
</para>
</sect1>
<sect1 id="termrc.telnet">
<title>The <<filename>&tilde;/.term/termrc.telnet</filename> Init File</title>
<para>
I have checked line clarity using linecheck over this medium.
I expected it to be completely transparent, but it is not.
However, the only bad character seems to be 255.
The <filename>&tilde;/.term/termrc.telnet</filename> I use
(the <filename>.telnet</filename> is the name of the term connection, see above)
contains:
</para>
<para><screen>baudrate off
escape 255
ignore 255
timeout 600</screen></para>
<para>
Perhaps it could be improved by diddling,
I am getting a throughput of only about 30k cps over
a long-haul connection through a slow firewall.
Ftp can move about 100k cps over the same route.
A realistic baudrate might avoid some timeouts.
</para>
</sect1>
<sect1 id="direction">
<title>Direction</title>
<para>
Obviously, if you are starting from outside the firewall and zitching
in using a SecureID card or something, you will want to reverse the
roles of the remote vs local servers given above. (If you don't
understand what this means, perhaps you are not familiar enough with
term to use the trick described in this file responsibly.)
</para>
</sect1>
<sect1 id="security">
<title>Security</title>
<para>
This is not much more of a vulnerability than the current possibility
of having a telnet connection hijacked on an unsecured outside
machine. The primary additional risk comes from people being able to
use the term socket you set up without you even being aware of it. So
be careful out there. (Personally, I do this with an outside machine
I know to be pretty secure, namely a linux laptop I maintain myself
that does not accept any incoming connections.)
</para>
<para>
Another possibility is to add
</para>
<para>
<screen>socket off</screen>
</para>
<para>
to the remote <filename>&tilde;/.term/termrc.telnet</filename> file, or
</para>
<para>
<screen>add &quot;-u off&quot;</screen>
</para>
<para>
to the invocation of term.
This prevents the socket from being hijacked from the remote end,
with only a minor loss of functionality.
</para>
</sect1>
<sect1 id="telnet">
<title>Telnet Mode</title>
<para>
Be sure the remote telnetd is not in some nasty seven-bit mode.
Or if it is, you have to tell term about it when you invoke term,
by adding the <literal>-a</literal> switch at both ends.
(I sometimes use <literal>&gt;^] telnet&gt; set outbin</literal> or
<literal>set bin</literal>, or invoke telnet with a <literal>-8</literal> switch
to put the connection into eight-bit mode.)
</para>
</sect1>
<sect1 id="bugs">
<title>Bugs and Term Wish List</title>
<para>
The <command>linecheck</command> program has some problems checking telnet connections
sometimes. This is sometimes because it doesn't check the return code
of the <function>read()</function> call it makes. For network connections,
this call to <function>read()</function> can return <literal>-1</literal>
with an <literal>EINTR</literal> (interrupted) or
<literal>EAGAIN</literal> (try again) error code.
Obviously this should be checked for.
</para>
<para>
There are a number of features that could ease the use of term over
telnet. These primarily relate to an assumption that influenced the
design of term, namely that the connection is low bandwidth, low
latency, and somewhat noisy.
</para>
<para>
A telnet connection is in general high bandwidth, high latency, and
error free. This means that the connection could be better utilized
if (a) the maximum window size was raised, well above the limit
imposed by term's <literal>N_PACKETS/2=16</literal>,
(b) there was an option to turn off sending and checking packet checksums,
and (c) larger packets were permitted when appropriate.
</para>
<para>
Also, to enhance security, it would be nice to have a term option to
log all connections through the socket it monitors to a log file, or
to <literal>stderr</literal>, or both. This would allow one to see if one's term
connection is being subverted by nasty hackers on the outside insecure
machine.
</para>
</sect1>
<sect1 id="tricks">
<title>Tricks That Do Not Seem to Work</title>
<para>
Some telnet clients and servers agree to encrypt their communications,
to prevent eavesdropping on the connection. Unfortunately, the hack
used above (using the network connection that the telnet client has
set up while the telnet client is idle) won't work in that case.
Instead, one really must go through the telnet client itself, so it
can do its encryption. It seems like that requires a simple hack to
the telnet client itself, to add a command that runs a process with
its <literal>stdin</literal> and <literal>stdout</literal> are connected
to the live telnet connection.
This would also be useful for various bots, so perhaps someone has
already hacked it up.
</para>
</sect1>
<sect1 id="resources">
<title>Related Resources</title>
<para>
A vaguely related trick is to SOCKSify one's Term library.
Details, including patches to SOCKS, are available from
Steven Danz <ulink url="mailto:danz@wv.mentorg.com"><citetitle>danz@wv.mentorg.com</citetitle></ulink>.
</para>
</sect1>
<sect1 id="acknowledgements">
<title>Acknowledgments</title>
<para>
Thanks for valuable suggestions from:
</para>
<itemizedlist>
<listitem>
<para>Gary Flake <ulink url="flake@scr.siemens.com"><citetitle>flake@scr.siemens.com</citetitle></ulink></para>
</listitem>
<listitem>
<para>Bill Riemers <ulink url="bcr@physics.purdue.edu"><citetitle>bcr@physics.purdue.edu</citetitle></ulink></para>
</listitem>
<listitem>
<para>Greg Louis <ulink url="glouis@dynamicro.on.ca"><citetitle>glouis@dynamicro.on.ca</citetitle></ulink></para>
</listitem>
</itemizedlist>
</sect1>
</article>