So, you want to use port forwarding with ipchains. Throughout this series, I will show you some interesting tips and try to explain ipchains and ipmasq in a simple but clear way. This is probably not the best way to do things, but it works. And it has been my experience as a sys admin to not fsck with things that work. My approach to building a firewall is probably a little unorthodox, because I tend to take a very relaxed stance on building them at first and then begin enforcing rules. Being a former electronic technician I tend to look at problems in half-steps, meaning that I take the problem and jump back in increment until I get something that works and jump forward half way to the broken part. Most of this is taken from lessons learned the hard way. I'm not a security guru nor a ipchains guru. But this stuff seems to work.
You need to pick a distribution to use. Most of this should apply to all of them, but each distribution does things a little differently. I will try to cover some of the different distros, but covering all of them would make this extremely long. I personally like Debian and Storm, but the others will work also. This example was performed on a Storm Firewall for Linux, and Mandrake 7.1., so it should cover most of the bases.
First you need to get a fresh box; when I say fresh I mean freshly built. You can do this on a previously built box, but if you have inherited it from someone you need to check your kernel configs and make sure that IP_MASQ and IPCHAINS support is built in. I would also recommend checking the other options for the kernel and making sure you don't lose something during a recompile. That could be ugly! I won't go into the details of kernel configuration, but if you are reading this, I hope that you know how to roll your own. If not, the Kernel How-To provides a great wealth of information about this. One other note; the box you are using needs to have two(2) NICs. I know some people say they have to be the same model card, but I have never had any problems with running two different ones as long as they are supported by the kernel.
In the kernel config you should have the following configuration directives for this to work. You also need to make sure you have all the right drivers for the network cards.
CONFIG_FIREWALL=y CONFIG_IP_FIREWALL=y
There are three packages you are going to need to make sure are installed.
ipchains - Available for Red Hat src.rpm, i386.rpm and if you are using
Debian just run "apt-get install ipchains".
ipmasq - I haven't found an RPM but for Debian you need to run "apt-get
install ipmasq"
ipmasqadm - Available here for RPMS, and for debian just use the "apt-get
install ipmasqadm" command.
Once all that is done, we can start the firewall building.
On the Storm system the firewall is located in /etc/network/firewall
and is called by /etc/init.d/networking script. Most RedHat systems I have
seen have a /etc/rc.d/rc.firewall script in /etc/rc.d/rc.local calling
the script last.
You need to open up the firewall script in your favorite text editor, wherever you have chosen to put it. I would put a little header in the top with some things like date, your initials, and a purpose, just to be nice to the guys who come in after you and are trying to figure it out.
In the first installment, I will cover how to get a WWW firewall server available to the outside world and I will also show some modifications that you can make to enable certain IPs access to an intraweb server from remote locations.
I) Preliminary Setup:
On your WWW server the default gw needs to be the firewall box. If you run the command "route -n", the default gw should be listed as the internal IP address of the gateway.
For testing, you need to be outside the network. When I say outside the network, it helps to be on another class C entirely. There is a bug in IP Masquerading that doesn't allow you to use the same external gateway. A patch was posted to the Masquerade mailing list.
II) Firewall Setup
In your firewall script add the following lines. These basically just do some set up stuff, like #! and the path and some variables. You can do this with IPs, but if you do a lot of rules with the destination IP as your own, it reduces the typing a little.
#!/bin/sh
# Default block firewall configuration template with masquerading.
PATH="/sbin:/usr/sbin:/usr/local/sbin:$PATH" EXTERNAL_IFACE="eth0" #This assumes that you external interfaceis eth0.LOOPBACK="lo" # Sets the loopback interfaceINTERNAL_IFACE="eth1" # Set the internal interfaceMY_EXT_IP="my_ipaddress" # Your external IPMY_INT_IP="my.internal.address" # Your internal IP
ANYWHERE="0.0.0.0/0.0.0.0" # Basically setting for anyone from anywhereWWW_SERVER ="10.0.0.10" # This would be your web server address
Set up the proc system to allow or disallow things--basically, put a one or a zero in a few files. Red Hat does this a little differently, by allowing you to add the line "net.ipv4.ip_forward = 1" to the /etc/sysctl.conf file. I would rather do it explicitly in the firewall script.
echo 0 > /proc/sys/net/ipv4/ip_forwardecho 1 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 1 > /proc/sys/net/ipv4/conf/default/rp_filterecho 0 > /proc/sys/net/ipv4/conf/all/accept_source_routeecho
0 > /proc/sys/net/ipv4/conf/default/accept_source_routeecho 0 > /proc/sys/net/ipv4/conf/all/accept_redirectsecho
0 > /proc/sys/net/ipv4/conf/default/accept_redirects
Now that all the preliminary stuff is done, we can begin the ipchains configuration.
ipchains -F # -F is for flush all the old rulesipchains -X # -X is for
delete chainipchains -M -S 7200 240 500 # -M sets upt the masquerade time
out variables.ipchains -P input DENY # -P is policy setting in this case
deny inputipchains -P forward ACCEPT # in this sense accept forwardipchains
-P output ACCEPT # and accept outputsipchains -N inside # Sets up a new
chainipchains -N outside # sets up a new chainipchains -A inside -p -p
ip -j ACCEPT # Allows everything from the inside.ipchains -A input -i lo
-j ACCEPT # Accept everything from the loipchains -A output -i eth0 -j
ACCEPT # Accept all output to the external interfaceipchains -A input -i
eth1 -j outside # This will be used later.ipchains -A input -i ! eth1 -j
inside # This will be used later.
Set up masquerading so you can get packets out from the web server.
ipchains -A forward -i eth1 -s $WWW_SERVER/32 -j MASQ
Set up the web server rule. This rule allows anyone, from anywhere,
to hit the external interface on port 80, the www port.
ipchains -A input -s $ANYWHERE -d $MY_EXT_IP 80 -p tcp -i eth1 -j ACCEPT
Set up the masquerade port forward to the internal WWW Server. This
will takes all requests on port 80 of the external IP address and forwards
them to the WWW Server address behind the firewall. The -f flushes the
ipmasqadm rules.
The second line provides for -a, add the rule, -P, tcp protocol, -L,
local interface and port number, -R, remote address and port, and -p, a
load balancing command. One hundred (100) sets it to 100% of the time do
this.
ipmasqadm portfw -f ipmasqadm portfw -a -P tcp -L 198.17.136.45 80 -R 10.0.0.199 80 -p 100
That pretty much does it. More advanced IP Chains guys may say I didn't do a lot of the other extra stuff, but I blocked all INPUT and only allowed anything out from the www server, so it should do the job.
For limiting who can get to the server, just take the rule from Step 4 above
ipchains -A input -s $ANYWHERE -d $MY_EXT_IP 80 -p tcp -i eth1 -j ACCEPT
and modify it. Say you only want the network 111.111.111.111 to connect. You can add extra ones as necessary to cover different locations.
ipchains -A input -s 111.111.111.111/32 -d $MY_EXT_IP 80 -p tcp -i eth1
-j ACCEPT
That's it.....