"The Linux Gazette...making Linux just a little more fun!"


(?) The Answer Guy (!)


By James T. Dennis, linux-questions-only@ssc.com
Starshine Technical Services, http://www.starshine.org/


(?) Linux as Router and Proxy Server: HOWTO?

From kdeshpande on Sat, 05 Dec 1998

(?) we want to setup linux server as a proxy server with two ethernet cards. kindly guide me for installtion process.

i am ms win 95 user and does not know any thing about unix / linus pl. reply on [another mail address].

(!) You'll want to start with the "Linux Installation and Getting Started." That's an LDP guide that's often included with Linux distributions in the /usr/doc directory and is available on-line at any mirror of the LDP. That covers the basics of Linux (although it is getting a bit long in the tooth).
Configuring a proxy server and router is a fairly advanced process and will involve a considerable understanding of Unix and of TCP/IP concepts. It sounds like your skills in English may make some of my explanation inaccessible to you. Hopefully the guide to routing that I've also written for this month's LG article (should appear for the January 1999 issue) will help.
There are a couple of other HOW-TO documents written on using Linux as a "Firewall" (proxies are often a component in a firewall). Many of these have been translated into various languages. You'll want to see if there's one in your native language.
Personally I'd suggest that you get a consultant to come in and configure it for you. That is likely to be far easier and less of a hassle than trying to do it yourself.
Now, with all of those disclaimers out of the way here's a simple configuration:
                                    _________
		192.168.1.x  -------| proxy |------ the Internet
                                    ^^^^^^^^^
In order to have a proxy system, you have to have a "multi-homed host" (a system with two interfaces in it).
In this case you've specified that you want to have two ethernet cards. So, first you install those. Be sure to set their IRQ's and I/O base address settings to non-conflicting values. The exact process varies greatly from one card to another. With the 3c5x9 and 3c900 cards you use a program to set them (3C5X9CFG.EXE under MS-DOS, or the appropriate utility that was written for Linux --- I found a copy at the VAResearch ftp site: ftp.varesearch.com under a relatively obvious name).
Let's say that you have one of them set to IRQ 10, I/O 300 and the other set to IRQ 11, I/O 330 (make sure that these don't conflict with any SCSI, sound or other cards that you have installed). Typically you'll also want to disable any "Plug & Play" support on your motherboard since these features may change the settings on your ethernet card while you boot, causing you no end of consternation later.
You'll also have to make sure that the appropriate driver is linked into your kernel, or that you've built the appropriate modules.
It is also common for the Linux kernel to require that you provide it with a hint that there are multiple ethernet cards to initialize. You just provide the kernel with a boot parameter (read the 'bootparam(7)' man page and/or the "Boot Parameter HOWTO" for details). The HOWTO has an example at:
http://metalab.unc.edu/LDP/HOWTO/BootPrompt-HOWTO-7.html#ss7.1
... showing the command case using:
ether=0,0,ether1
... (no spaces --- and don't change the case of any letters).
This option is passed to the kernel by typing it in at the LILO boot prompt, or adding an append directive to your /etc/lilo.conf like:
append="ether=0,0,ether1"
...(the double quotes are required).
This option forces the kernel to look for a second ethernet adapter (the first ethernet adapter is labelled as 'ether0' and will normally be detected automatically). The 0,0 forces it to search for the IRQ and I/O base addresses automatically. If that's not successful, or you want to be conservative, you can just provide the information manually.
This is extensively documented in the "Ethernet HOWTO" at:
http://metalab.unc.edu/LDP/HOWTO/Ethernet-HOWTO-10.html#ss10.1
You should see boot time message indicated that the ethernet cards have been found. You can use the 'dmesg' command to review those after the system is finished booting and you've logged in.
The last step in the hardware/driver layer is to issue 'ifconfig' command for each of these interfaces.
Let's say your ISP router (cable modem, ISDN or DSL gizmo, whatever) is using address 172.17.100.1 on your ethernet (that's a private net address from RFC1918 --- but let's pretend is was your real address).
Let's fill in our diagram a bit more:
                              _________      __________
          192.168.1.x  -------| proxy |------| router | -- Internet
                              ^^^^^^^^^      ^^^^^^^^^^
                            eth0     eth1    ^-------- 172.17.100.1
                       192.168.1.1   172.17.100.2

Here we see a private network (all of 192.168.1.*), our proxy servier with two ethernet interfaces, with eth0 on our "inside LAN" (taking up the conventional .1 address for a router --- it is the router to the outside/perimeter segment. eth1 is the proxy host's interface on the "perimeter" or "exposed" segment (outside of our LAN).
There is a small perimeter segment in this case. In many organizations it will be populated with web servers, DNS and mail servers and other systems that are intended to be publicly visible.
Obviously each of the systems that are shown on this segment (the proxy and the router) need their own IP address. I've assigned 172...2 to the proxy since I said that 172...1 was the border router's inside address. The border router would also have some sort of link (usually a point-to-point (PPP) link over a modem, ISDN, frame relay FRAD, CSU/DSU codec, DSL ATM or other device --- the telephony is not my specialty they hand me a "black box" and I plug the wires into the little tabs where they fit).
For our example we don't care what the IP addresses over the PPP link are. all we care about is that our ISP gets packets to and from the 172...* network or subnet. They have to have routes to us.
This example will work with any subnet mask --- we'll assume that we have a whole class C range, from 172.17.100.1 through 172.17.100.254 for simplicity's sake (read all about subnetting and proxyarp for gory details on those scenarios).
So, on our Linux proxy server we use the following commands to configure our interfaces:
ifconfig eth0 192.168.1.1 netmask 255.255.255.0
ifconfig eth1 172.17.100.2 netmask 255.255.255.0
... we could leave the netmask option off the first command since it will default to this mask due to the address class. With most modern ISP's we'll have to use some other netmask for the second case --- unless we're paying for a whole Class C block. We might need to anyway (our ISP might have a Class B address block and be subnetting it into Class C chunks). We'll just assume that we need it on both of them.
We can optionally specify the broadcast addresses for these --- however it shouldn't be necessary if we're following normal conventions. It will default to the last valid number in the address range (192.168.1.255 for the first case and 172.17.100.255 in the other).
So we have IP addresses on each interface. Now we need routes. In the newer 2.1.x kernels (and presumably in the 2.2 kernels and later) the 'ifconfig' operation automatically results in an addition to the routing table. This is more like the way Solaris works. Under earlier kernels you have to add routes with commands like:
route add -net 192.168.1.0 eth0
route add -net 172.17.100.0 eth1
... this defines routes to the two local segments (one on the inside, and one on the outside). Again, newer kernels may not require this entry.
Now, for our proxy to reach the Internet we'll have to set a "default route" like:
route add default gw 172.17.100.1
If we have other networks that must be accessed through our LAN (something like a 10.*.*.* network in the back office or for our server room) we may also want to add other "static" routes to this list. Let's say that 192.168.1.17 was a router between our desktop LAN and our 10-net server segment. We'd add a command like:
route add 10.0.0.0 gw 192.168.1.17
Notice that we are not forwarding packets between our interior LAN and the outside world. If we did the routers on the Internet will not have any valid routes back to us (that's what these 192.168.*.* and 10.*.*.* addresses are all about. Read RFC 1918 for details on that). 172.16.*.* through 172.31.*.* addresses (16 Class B blocks) are also reserved for this use --- but we're "pretending" that 172.17.100.* is a "real address" for these examples.
So now we need to enable our interior systems to access the outside world. We can use IP Masquerading and/or proxying to accomplish this. Masquerading is a bit easier than proxying under Linux since the support is compiled into most kernels.
Masquerading is a process by which we make a group of systems (our internal clients) look like one very busy system (our proxy). We do this by re-writing the "source" addresses on each package as we route it --- and by patching the TCP port numbers.
TCP "port" numbers allow a host to determine which process on a system is to receive a given packet. This is why two users on one system can telnet to another system without there being ambiguity.
Using masquerading all of the connections that are being handled at any given modem essentially look like "processes" or "sockets" on the proxy server.
Thus IP masquerading is "network layer proxying."
Do do this under Linux 2.0.x and earlier (back to the 1.3.x series) we could simply use a command like:
ipfwadm -F -m -a accept -S 192.168.0.0/16 -D 0.0.0.0/0
... which adds (-a) a masquerading (-m) rule to accept packets from any source address matching 192.168.*.* (16 bits of the address are the "network part" --- that's equivalent to a netmask of 255.255.0.0) and whose destination is "anywhere." This rule must be added to the "forwarding" (-F) set of packet filters.
The Linux 2.0.x IP packet filtering subsystem (kernel features) maintain four sets of rules (tables): Accounting, Input, Forwarding, Output
... we only care about the "forwarding" rule in this case.
With all recent Linux kernels we also have to issue a command like:
echo 1 > /proc/sys/net/ipv4/ip_forward
... to enable the kernel's forwarding code. These kernels default to ignoring packets that aren't destined to them for security reasons (this and a TCP/IP "option" called "source routing" have been used to trick systems into providing inappropriate access to systems --- so it is better for systems to leave these features disabled by default). Older versions of Unix and Linux were more "promiscuous" -- they would forward any packet that "landed on them" so long as the could find a valid route.
Lastly we'd just configure our client systems with IP addresses in the range 192.168.1.2 through 192...254 and cofigure them to treat 192.168.1 as their default route. Packets will get to the proxy from any of these, be re-written to look like they came from some socket on the 172...2 interface and forwarded out to the Internet. Returning packets will come in on the socket which will provide the kernel with an index into a table that stores the 192.168.*.* owner of this connection, and the return packet will be re-written and forwarded accordingly (back into the internal network).
That's how masquerading works.
Applications layer proxying is actually a bit easier than this. You install packages like SOCKS, Delegate, the FWTK (firewall toolkit), and a Squid or Apache caching web server unto the proxy system. These listen for connections on the inside interface (192.168.1.1). Proxy aware software (or users) on the internal system direct their connections to the proxy server (on port 1080 for SOCKS and Delegate) and then relay the real destination address and service to the proxy server. The proxy server, in turn, opens up its own connection to the intended server, makes the requests (according to the type of service requested, and relays the information back to the client).
In addition to the basically relaying a good proxy server can provide caching (some multiple requests for the same static resource are handled locally --- saving time and conserving bandwidthy), additional logging (so big brother can tell who's been bad), and can enforce various access control policies (no FTP to popular mirror sites in the middle of the day, all users must be Kerberos authenticated in order to access the Internet, whatever).
The main disadvantage to applications layer proxying is that the proxy clients must be "socksified" or proxy aware. Either that, or with some of them (FWTK and optionally DeleGate) the user of a normal client (such as FTP) can manually connect to the proxy server and use some special command (login sequence) to provide the proxy with the information about the real destination and user/account info. (Almost needless to say that a compromised proxy host is a great place to put password grabbing trojan horses!)
However, one of the major advantages of the proxy system is that it can support strange protocols --- like "active FTP" which involves two co-ordinated IP connections, one outbound control connection and one inbound data channel. There are other protocols that connection pass information "in band" and make masquerading more difficult and sometimes unreliable.
It's possible to use both, even concurrently with just one host acting in both roles.
So far my favorite applications proxy package is "DeleGate" by Yutaka Sato, of the Electrotechnical Laboratory (ETL) in Japan. You can find it at:
http://wall.etl.go.jp/delegate
... it's easy to compile and configure and it's available under a very liberal license (very BSD'ish but less wordy).
DeleGate can be used as a SOCKS compatible server (i.e. SOCKSified client software will work with DeleGate); and it can be "manually operated" as well.
My only complaint about DeleGate is that the English documentation can be a bit sparse (and my paltry studies of Japanese are nowhere near the task of reading the native docs).
The easiest way to install SOCKS clients on your Linux systems is to just grab the RPM's from any Red Hat "contrib" mirror. That's also the easiest way to install a SOCKS server.
To configure the clients for use with the SOCKS5 libraries you have to create a file, /etc/libsocks5.conf, to contain something like:
socks5          -       -       -            -          192.168.1.1
noproxy         -       192.168.1.           -
... note that the "noproxy" line ends with a "." to specify that this apples to the whole 192.168.1.* address range.
configuring the socks server you need to create a file, /etc/socks5.conf and put it at least something like:
route   192.168.1.      -       eth1
permit  -       -       -       -       -       -
... and you might have to change that inferface for our example (I don't remember but I think it's "destination addresses and target interface).
Naturally the docs on these are abysmal. However, I did eventually get this setup working when I last tried it.


Copyright © 1999, James T. Dennis
Published in The Linux Gazette Issue 36 January 1999


[ Answer Guy Index ] a b c 1 2 3 4 5 6 7 9 10 11 12
15 16 18 19 20 21 22 23 24 25 26 27 28
29 31 32 33 34 35 36 37 38 39 40 41 42 44
45 46 47 48 49 50 51 52 53 54 55 56 57 60 61 62 63 64 65 66
67 69 72 76 77 78 79 80 81 82 84 85 86 87 91 94 95 96 97 98


[ Table Of Contents ] [ Front Page ] [ Previous Section ] [ Next Section ]