old-www/LDP/LG/issue58/ward.html

221 lines
11 KiB
HTML

<!--startcut ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>Hooking Up a Local School Network to the Net with a Java Proxy LG #58</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->
<CENTER>
<A HREF="http://www.linuxgazette.com/">
<H1><IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.jpg"
WIDTH="600" HEIGHT="124" border="0"></H1></A>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="taylor.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue58/ward.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="washington.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>
<!--endcut ============================================================-->
<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>
<P> <HR> <P>
<!--===================================================================-->
<center>
<H1><font color="maroon">Hooking Up a Local School Network to the Net with a Java Proxy</font></H1>
<H4>By <a href="mailto:award@mypic.ad">Alan Ward</a></H4>
</center>
<P> <HR> <P>
<!-- END header -->
<p>I'm writing this article after a couple of weeks of messing around
getting our local school network hooked up to the net. Our problem was
similar, I guess, to that of many schools: how do you give students'
boxes access to the net, but restricting both certain types of content
and certain services altogether (IRC)?</p>
<p>A minor extra point was that I wanted to separate our two
computer labs' networks into different segments with some kind
of packet filtering in between. With the number of computers going up, so
was the collision rate.</p>
<p>I had the following material considerations to take into account:</p>
<p><ul>
<li>A connection to our ISP via an ISDN card - of a make unfortunately not
supported right now by the Mandrake kernels I use. So the box connecting
directly to the net had to run under Windoze, with the WinGate proxy
installed. This is not in itself a bad thing, as configuring dial-on-demand
on a Linux box would have taken too much of my time to find
out how it is done.</li>
<li>An eclectic collection of Windows 95 / 98 / 2000 client machines,
plus an occasional Macintosh and PC under Linux or QNX. All running
various browsers.</li>
<li>A P-III 450 MHz I managed to scrounge, with several ethernet cards.
This one was to do the filtering, and was so definately a Linux box.</li>
<li>Finally, I wanted http and ftp access to a local web server in
much the same way as access to the net: i.e. the user just has a
different address to type in.</li>
</ul></p>
<p>By now, the network hardware setup was more or less clear, thusly:</p>
<p align=center><img src="misc/ward/net1.jpg"></p>
<p>The filtering server also runs our local web server (Apache).
<p>Now came the interesting part: how was I to configure the lot into a
working setup?<p>
<p><b>The Linux built-in firewall</b></p>
<p>My first idea was to use Linux' routing capacities. You can set
up just about any Linux box as a router to separate two or more ethernet
segments. It just needs a card for each segment - not even necesserily
running at the same speed. You then configure the kernel built-in firewall
to ignore packets that have source and destination addresses within
the same segment, but to forward packets with source and destination
addresses in different segments.</p>
<p>This can be a definite gain of speed as the number of collisions
on an ethernet network goes up with the number of nodes on each
segment - and each collision requires a time-out to retry sending
the packet. So, for example, three segments with ten nodes each and a
Linux firewall in between outperforms a single segment with all
thirty nodes under normal and heavy traffic loads.
<p>For more information, read the Firewall-HOWTO and the ipchains manual
page</p>
<p>A simple setup would then be to program the clients to use the
net access server as their web proxy, and use the filtering server
as a firewall. This is just about the most classical distribution of
roles imaginable.</p>
<p>So why couldn't this work for me? The answer lies in the fact that
to enable routing, both the client boxes and the net access server had to
have the filtering server as their gateway. This worked fine as long
as the ISDN wasn't up. But when ISDN went up, the default gateway on
the net access server (running under Windows, remember?) became our
ISP.</p>
<p>So a request emanating from a client box goes into the filter,
and is forwarded to the net access. The WinGate proxy does its
stuff, and replies to our local client - but this message is
routed back off to our ISP ... and the client gets no reply.</p>
<p><b>The Squid proxy</b></p>
<p>As a second approach, I thought of using the squid proxy,
cascaded under WinGate. This way, a client request goes to squid on the
filter. Squid then determines if the request goes to the local
server, or has to be forwarded to the WinGate machine:</p>
<p algin=center><img src="misc/ward/net2.jpg"></p>
<p>And did this work? Yes, very well ... as long as the client
requested either the local server or an internet website by giving
its IP address. The problem was with DNS.</p>
<p>The squid proxy has to determine where to send each request.
So even if you give it a default cascaded proxy, it still tries
to perform DNS address resolution on each URL it receives.</p>
<p>I then tried the following: set up WinGate as a DNS proxy
as well as www, and tell the filter to use the net access
box as its main DNS. The requests went through to WinGate,
but got no reply from the 'net. Confounding ... and the client
box gets a message from squid complaining it can't proceed with
address resolution. Needless to say,
the net access server's DNS setup works well on its own.</p>
<p>Another approach was to use the Apache webserver's proxy
capabilities. This worked just as well - and just as badly -
as squid.</p>
<p>Recommended reading: all 1907 lines of /etc/squid/squid.conf .
Same for /etc/httpd/conf/httpd.conf .</p>
<p><b>Homebuilt Java proxy</b></p>
<p>As you may imagine, I was at this time fresh out of ideas. And
school-in was 48 hours away. So I took the only reasonable decision -
write my own proxy daemon in Java, to be installed on the filter.</p>
<p>This may take a bit of explaining. First of all, why is writing
a proxy daemon reasonable? In this case, the proxy just had to:<br>
<ul>
<li>accept a socket connection from a client, and read the client browser's
request;</li>
<li>establish a second socket connection to WinGate, send the client's
request on with no changes;</li>
<li>listen on the second connection, and send whatever came down
the line back on the first connection;</li>
<li>terminate the first connection as soon as the second one is dropped
by WinGate.</li>
</ul></p>
<p align=center><img src="misc/ward/net3.jpg"></p>
<p>There is no caching, no address resolution, nothing else to be done.</p>
<p>Secondly, why is it reasonable to write such a program in Java,
when network programming is traditionnaly done in C? Mainly because
programming sockets in C is a pain, and doing it in Java is painless.
All relevant classes are available in java.net.* : Socket, ServerSocket,
DataInputStream and PrintStream are about all you need.</p>
<p>It is also as easy in Java as is C to fork off a process to handle
separately each client connection. The difference is that in Java,
one usually uses a <u>thread</u>, not a separate process. This has some
advantages on the typical C solution. Each process has its own memory
allocation, etc, and so takes relatively longer to establish. A thread
is an altogether lighter structure.</p>
<p>Finally, it works. To be quite honest, it works more quickly
than I thought, and what was initially conceived as a quick solution
looks to stay as a permanent one. In fact, with 20-30 clients going
full steam on Internet, the limiting factor is ... our ISP.</p>
<p><b>Future improvements</b></p>
<p>Just one on my TODO list: as it stands, there is no page
content filtering. I will work on that later on (and cut out
web-based chats at the same time).</p>
<p>My source code is here: <a href="misc/ward/proxy.java.txt">proxy.java</a>,
naturally under GPL. Please send me any comments you may have.</p>
<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P -->
<H5 ALIGN=center>
Copyright &copy; 2000, Alan Ward<BR>
Published in Issue 58 of <i>Linux Gazette</i>, October 2000</H5>
<!-- *** END copyright *** -->
<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="taylor.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue58/ward.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="washington.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->