\documentclass[twocolumn,twoside]{article} \usepackage{graphics} \title{IPv4 Masquerading for the Hypothetical Geek} \author{Ben Pfaff $<$pfaffben@msu.edu$>$} \date{24 May 2000} \setlength{\textwidth}{6.5in} \setlength{\oddsidemargin}{0pt} \setlength{\evensidemargin}{0pt} \setlength{\textheight}{8.5in} \setlength{\topmargin}{0pt} \newcommand{\hyply}{\emph{hypothetically}} \newcommand{\hyp}{\emph{hypothetical}} \newcommand{\Hyply}{\emph{Hypothetically}} \newcommand{\Hyp}{\emph{Hypothetical}} \begin{document} \maketitle \tableofcontents \section{Introduction} \Hyply, if you're a geek, you have any number of computers just sitting around, and you have enough random parts to build another half dozen or so without video or disks. So, \hyply, the thing to do is to network them all together, just for hack value, using a combination of old thinwire Ethernet cards and a 386 with 6 NE2000s acting as a bridge. Remember, all this is \hyp. I would never do this. I am not a geek. The only problem is that all these machines will be wanting Internet access. What good is a computer without Internet access, after all? So you call up the \hyp{} local DSL provider and order 18 \hyp{} DSL lines and companion IP addresses, or 25 to allow room for expansion. Ahem! Not even your \hyp{} geek can pay for 25 \hyp{} DSL lines, and anyway no DSL provider exists out in the \hyp{} boonies where the \hyp{} geek lives. So, in reality, your \hyp{} geek is stuck with a 56 kbps\footnote{Current FCC regulations limit speed to 53 kbps. It's only your crappy phone lines that limit speed to 20 kbps.} modem on a single phone line. How can such a geek make the best of this? The \hyp{} geek still wants all the machines to have Internet access. He doesn't want to put a modem in all 18 computers, which would \hyply{} result in the \hyp{} geek slitting his \hyp{} wrists\footnote{Down, not across.} on a jagged case fragment anyhow. The real answer to this \hyp{} problem of connectivity is \textit{masquerading}, also known as \textit{network address translation} or NAT. Masquerading makes any number of machines on a single network look like a single host with a single network address. More specifically, masquerading for IPv4\footnote{IPv4, or Internet Protocol version 4, is the version used in real life. IPv6, the next version, is used only in pipe dreams\texttt{\^{}W\^{}W}experimental settings.} has been a feature of the Linux kernel since version 1.2.\textit{x} for some value \textit{x}. This article covers the basics of IP masquerading under Linux 2.0.\textit{x} and 2.2.\textit{x}. For more information on IP masquerading under Linux, please see David Ranch's excellent IP Masquerading HOWTO, available from your local Linux documentation site. \section{Planning} \begin{figure*}[th] \centering\resizebox{6in}{!}{\includegraphics{network.ps}} \caption{Architecture of typical home network.} \label{network} \end{figure*} Figure~\ref{network} on page~\pageref{network} shows the architecture of a typical home network set up under IP masquerading. Notice how all the machines in the network are ultimately connected to the Internet through the server in the lower right of the diagram. This is probably the way that you want to plan for your IP masquerading setup to work. You'll need all of the following in order to set up masquerading: \begin{itemize} \item A Linux-capable server computer with a network card and an Internet connection. A 386 or 486 is fine for basic setups. \item One or more client computers with network cards. These can run just about any operating system. \item A hub to connect all the computers together. \item A range of IP addresses (see below). \item A geek, for debugging purposes. This can be the most expensive part of the setup, but some geeks can be bribed with interesting bits of old hardware or discounts on new hardware. \end{itemize} You'll have to come up with the hardware and the geek on your own. But selecting the IP address range to use is easy. I recommend that you use the 16-bit ``Class B''-size address range at 192.168.\textit{x}.\textit{y}, which is reserved specifically for private networks like the one you're building. As long as you have fewer than 65,000 or so computers on your network\footnote{Around here, that reads ``as long as you're not Ed Glowacki.''}, this should be plenty. As a consequence, the examples below assume that all of your computers have IP addresses of the form 192.168.0.\textit{x}, where \textit{x} is a number between 1 and 254\footnote{192.168.0.0 and 192.168.0.255 are reserved for the network address and the broadcast address, respectively.}. Specifically, it is assumed that your server is at 192.168.0.1. Now that we're done with the formalities, plug everything together and proceed to the next section, where we'll set up basic masquerading on the server and the clients. \section{Basic server setup} The toughest setup for masquerading is on the server, and even that isn't very hard. Now, let's a look at how to actually do it. Start by logging into your Linux 2.0.\textit{x} or 2.2.\textit{x} server as \texttt{root}, the superuser. Then follow the simple steps below. If you're going to use masquerading on a regular basis, you should integrate these commands into a system startup script in \texttt{/etc/init.d}, but the first time through it might be more educational to type them directly at a shell prompt. \begin{enumerate} \item Modern Linux kernels disable packet forwarding by default. This means that incoming IP packets will never be passed on to other computers. However, for masquerading we need to turn on packet forwarding, using the following command: \begin{verbatim} echo 1 > /proc/sys/net/ipv4/ip_forward \end{verbatim} \item If you use the most common type of PPP dialup account, where you get a new IP address every time you dial, you should turn on kernel support for dynamic IP address hacking, too: \begin{verbatim} echo 1 > /proc/sys/net/ipv4/ip_dynaddr \end{verbatim} \item (Optional.) By default, masqueraded connections that are idle for 15 minutes or longer ``time out'' and expire. This timeout duration can be adjusted; e.g., the following command sets the expiration timer to 2 hours (7200 seconds): \begin{description} \item[(2.0)] \verb|ipfwadm -M -s 7200 10 160| \item[(2.2)] \verb|/sbin/ipchains -M -S 7200 10 160| \end{description} \item (Optional.) Some IP-based protocols need extra kernel support for successful masquerading. You can load modules to support these protocols. For instance, to load the FTP masquerading module: \begin{verbatim} modprobe ip_masq_ftp \end{verbatim} Besides FTP, masquerading modules exist for CuSeeMe, IRC, Quake, RealAudio, and VDOLive, among others. Note that most protocols do not require specific masquerading support. \item Set default forwarding policy to ``deny.'' This is very important; if omitted, then you allow anyone on the Internet to tunnel through your network, making it appear as if their network activity were originating from your own network. \begin{description} \item[(2.0)] \verb|/sbin/ipfwadm -F -p deny| \item[(2.2)] \verb|/sbin/ipchains -P forward DENY| \end{description} \item Turn on masquerading for your local network: \begin{description} \item[(2.0)] \verb|/sbin/ipfwadm -F -a m| \\ \verb|-S 192.168.0.0/255.255.255.0| \\ \verb|-D 0.0.0.0/0.0.0.0| \item[(2.2)] \verb|/sbin/ipchains -A forward| \\ \verb|-s 192.168.0.0/255.255.255.0|\\ \verb|-j MASQ| \end{description} In the commands above you should replace \verb|192.168.0.0| and \verb|255.255.255.0| by the actual network address and netmask of your local network. If you're using my recommended setup, no changes are necessary. \end{enumerate} That's it! You should now have a functioning IP masquerading setup. If not, refer to the following section. \subsection{Troubleshooting} This is where you should contact your geek. But if you want to try to debug it on your own, consider the following points: \begin{description} \item[Does the kernel support masquerading?] A lot of distributions now come out-of-the-box with kernel support for masquerading. But yours might not. If you suspect that your kernel lacks IP masquerading support, refer to the IP Masquerading HOWTO for information on what options need to be enabled when recompiling the kernel. \item[Is the network card set up correctly?] Can the server can \texttt{ping} other hosts in the network and that they can \texttt{ping} the server? If not, you've got a problem. \item[Are you online?] Nothing in these instructions will make your server automatically auto-dial when a web page is requested. (That's explained later.) \item[Did you do the ritual sacrifice?] Arachnae, goddess of networks, appreciates the sacrifice of hardware, the newer the better. \end{description} \section{Client setup} Once you've set up the server, it's time to set up the clients. This is pretty easy. I'll cover how to set up Linux clients and Windows 9\textit{x} clients. For more exotic systems, follow your nose, or refer to the IP Masquerading HOWTO. \subsection{Linux} Your distribution probably has some GUI method\footnote{``It's GUI-riffic!''} for setting up networking. These instructions assume that you're not using that method. As a result, the following should work with just about any Linux kernel. It probably works, with little modification, under many other Unix-like kernels, too. Again, you'll want to modify your startup scripts to do the following automatically. \begin{enumerate} \item Set the machine's IP address, network address, and netmask. For instance: \begin{verbatim} ifconfig eth0 192.168.0.2 netmask 255.255.255.0 \end{verbatim} \item Tell the machine how to get to the local network. (Some newer kernels may set this up automatically.) \begin{verbatim} route add -net 192.168.0.0 eth0 \end{verbatim} \item Instruct the machine that everything not on the local network should go through the server (it already knows how to get packets to the server, since it's on the local network; if it weren't, you'd have to tell it how), using it as a gateway: \begin{verbatim} route add default gw 192.168.0.1 \end{verbatim} \item If you don't already have DNS set up, then create \texttt{/etc/resolv.conf} with the content shown below. Replace the values shown by your own domain(s) and local DNS server(s): \begin{verbatim} search msu.edu debian.org gnu.org nameserver 35.8.2.41 35.8.2.42 \end{verbatim} \end{enumerate} \subsubsection{Troubleshooting} If it doesn't work, you're doing something wrong. Duh. Your geek will know what's wrong. If he's on vacation, think about the following: \begin{description} \item[Can you see the server?] Try using \verb|ping| to test your connectivity to the server. \item[Is ICMP masqueraded?] ICMP, the protocol used by \verb|ping|, is only masqueraded by newer kernels. So if you're trying to ping the Internet through the server, it might not work. Try something else, like a web browser. \item[\texttt{route} is not idempotent.] If you run \texttt{route} a lot, your routes will accumulate. You can view the routing table with \verb|route| or \verb|route -n|. To clear out the routing table, use \verb|route del|. For more information, see route(8). \end{description} \subsection{Windows 9\textit{x}} Open ``Control Panel'' under ``Settings'' on the Start menu. Inside Control Panel, double-click on ``Network.'' Within the main list box in the dialogue box that appears, find ``TCP/IP'' associated with your Ethernet card and double-click on it. Then make the following selections from the listed tabs: \begin{description} \item[IP Address] Specify the client's IP address and netmask. For instance, you might use \texttt{192.168.0.2} and \texttt{255.255.255.0}. \item[Gateway] Add a single entry, the address of your server. If you're following my recommendations, this is \texttt{192.168.0.1}. \item[DNS Configuration] Select the ``Enable DNS'' setting. Enter a host name in ``Host''; the name itself is not particularly important. Enter your preferred domain name within ``Domain.'' Put your DNS servers in ``DNS Server Search Order''; for instance, \texttt{35.8.2.41} and \texttt{35.8.2.42}. Enter any additional domains within ``Domain Suffix Search Order.'' \item[Other] Set as desired \end{description} You'll probably need to reboot after making these settings. \subsubsection{Troubleshooting} What do I look like, a Windows expert? ``Fiddle with it until it starts working'' is my advice. There's probably no point in talking to your geek about it. He doesn't know, either. \section{Advanced server setup} If you've gone through what's above, you now have a working IP masquerading setup. Congratulations. But there's lots more that you can set up, with some extra work. You might be interested in setting up one or more of the following: \begin{itemize} \item Automatic dialing whenever Internet sites are accessed. \item Web and FTP caching to accelerate surfing. \item A DHCP server to simplify client setup. \item A nameserver to speed DNS lookups and allow naming client computers. \item An NTP client/server to synchronize machines' clocks. \end{itemize} The following sections briefly cover each of these possibilities. \subsection{Autodialing} Most of the time, what you really want to happen is for the modem to dial when you're using the Internet, then hang up when you're done. This is pretty easy to do using \verb|diald|, and that's what I recommend that you use. I'll assume that you can set up \verb|diald| on your own; it's not that hard. But sometimes that's not what you want to do. For instance, you might want to keep the connection up permanently for a while, or you might want to prevent the modem from dialing entirely if you're using the line for other purposes. To conveniently allow for that, you can set up a helpful CGI script on your webserver. A sample CGI script for this purpose is shown in Figure~\ref{cgi} on page~\pageref{cgi}. You should install this script into your web server directory (e.g., \verb|/var/www|) and make it available only to machines on the local network. In addition, you need to add a line to \verb|diald|'s configuration file, of this form: \begin{verbatim} fifo /var/run/diald.fifo \end{verbatim} The script has to be setuid to a user empowered to write to the FIFO mentioned above. Sometimes this has to be \verb|root|, but you might be lucky enough that \verb|dialout| or similar will work, too, or you may be able to adjust the ownership or permissions on the FIFO created by \verb|diald|. \begin{figure*} \begin{verbatim} #! /usr/bin/perl use CGI; $q = new CGI; if ($q->param ('action') eq 'up') { fifo_cmd ('unblock'); fifo_cmd ('up'); fifo_cmd ($q->param ('keep') ? 'force' : 'unforce'); } elsif ($q->param ('action') eq 'down') { fifo_cmd ('unforce'); fifo_cmd ('down'); fifo_cmd ($q->param ('keep') ? 'block' : 'unblock'); } print $q->header(-expires=>'now'); print $q->start_html(-title=>'Modem Control'); print "
action | bring the connection\n"; print $q->popup_menu ('action', ['up','down'], 'up'); print " | To dial the modem, select up, or\n"; print "to disconnect, select down. |
permanence | \n"; print $q->checkbox(-name=>'keep', -label=>'Keep it that way.'); print " | If you don't check this box, then the normal\n"; print "semantics will be applied to the connection. That is,\n"; print "if you selected down above, the modem will dial when\n"; print "there is Internet activity; if you selected up,\n"; print "the modem will disconnect after idle time.\n"; print "Checking this box will disable that behavior: the connection\n"; print "will stay up or down, as appropriate, until you come back to\n"; print "this page and resubmit the form."; print " |