Hello, fakakuk-ga.
Firewalling can be fun when things work out right, and a real
pain-in-the-neck when they don't. This was a fun question to
answer because I learned more about iptables. I run Redhat 8.0 on
a few boxes and use masquerading so all of my internal network can
access the Internet.
Your firewall script looks good as far as outgoing connections and
masquerading. The problem comes when you want an internal
machine--a box behind your firewall--to be able to accept certain
connections from the outside world. Since you are masquerading,
you only have one IP address visible to the external network. As
far as the Internet is concerned, you only have one computer
hooked to it...that's the whole point of masquerading. What you
want to do is tell the firewall that any traffic coming in from
the network heading for the firewall machine's address with
destination port 3389, 80, 110 or 25 should be sent to your
internal machine. To do this, you must use destination NAT
(DNAT). Unlike SNAT (source NAT -- e.g., masquerading) which is
always done POSTROUTING, DNAT is done PREROUTING. This makes
sense if you think about it: since we are trying to decide where
the packet goes, it must be done before the routing decision is
made.
I'm going to define a variable called ISERVER which is the address
of your internal web/mail server. Let's use port 25 as an
example:
$IPTABLES -t nat -A PREROUTING -p tcp --dport 25 -i eth0 -j DNAT
--to-destination $ISERVER
You could send it to a different port if you wanted to. Let's say
you wanted all incoming connections to port 80 to be sent to your
internal server on port 8080:
$IPTABLES -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT
--to-destination ${ISERVER}:8080
You could enter the necessary line for each port you want to allow
through, but I'm inherently lazy and don't like to type that much.
So here is what I would do:
IPORTS="3389 80 110 25"
for port in $IPORTS; do
$IPTABLES -t nat -A PREROUTING -p tcp --dport $port -i eth0 -j DNAT
--to-destination $ISERVER
done
Now adding or removing ports is really easy--just add/remove them
from the IPORTS variable. Note that I'm specifying that the
protocal must be TCP. If you want UDP to, be sure to adjust it
accordingly. It is always good to be as specific as possible,
which is why I specify TCP instead of allowing just anything.
Plus you have to specify a protocol in order to specify a port.
If you wanted to allow all TCP and UDP connections to these ports,
use this:
for port in $IPORTS; do
$IPTABLES -t nat -A PREROUTING -p tcp --dport $port -i eth0 -j DNAT
--to-destination $ISERVER
$IPTABLES -t nat -A PREROUTING -p udp --dport $port -i eth0 -j DNAT
--to-destination $ISERVER
done
That takes care of your NAT, but now you have to deal with the
packet filtering. Fortunately, NAT and packet filtering work well
together. In your packet filter, you just use the real
destination address, ignoring all NAT you are doing--in our case
it is $ISERVER. Since you are allowing all packets being
FORWARDed from eth0 to eth1 to pass throught, I think you are
okay. However, if you decide to tighten things up a bit, you can
do this:
Take out your line that says
$IPTABLES -A FORWARD -i eth0 -o eth1 -j ACCEPT
and insert these
for port in $IPORTS; do
$IPTABLES -A FORWARD -i eth0 -o eth1 -p tcp -d $ISERVER --dport $port
-j ACCEPT
done
Note that I explicitly specified that the destination address
should be $ISERVER. Another example of being as specific as
possible.
Here's the modified script. Watch out for wrapped lines! Also,
don't forget to change the ISERVER variable to match your server's
address.
-------------------
#!/bin/sh
IPTABLES=/sbin/iptables
# ISERVER is the internal address of your web/mail server
ISERVER=192.168.1.2
# IPORTS are the ports you want to allow through to the mail
# server.
IPORTS="3389 80 110 25"
#Enable forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward
# Take care of DNAT
for port in $IPORTS; do
$IPTABLES -t nat -A PREROUTING -p tcp --dport $port -i eth0 -j DNAT
--to-destination $ISERVER
$IPTABLES -t nat -A PREROUTING -p udp --dport $port -i eth0 -j DNAT
--to-destination $ISERVER
done
$IPTABLES -P INPUT ACCEPT
$IPTABLES -F INPUT
#The following three lines are not necessary for NAT, but provide some
security
#by blocking any connections from being initiated from outside the
network.
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -m state --state NEW -i ! eth0 -j ACCEPT
$IPTABLES -A INPUT -j DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -F OUTPUT
$IPTABLES -P FORWARD DROP
$IPTABLES -F FORWARD
$IPTABLES -t nat -F
$IPTABLES -A FORWARD -i eth0 -o eth2 -m state --state
ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i eth2 -o eth0 -j ACCEPT
# After making sure it works as is, comment out the following
# line, and uncomment the four for the FOR loop to increase
# security.
$IPTABLES -A FORWARD -i eth0 -o eth1 -j ACCEPT
#for port in $IPORTS; do
# $IPTABLES -A FORWARD -i eth0 -o eth1 -p tcp -d $ISERVER --dport
$port -j ACCEPT
# $IPTABLES -A FORWARD -i eth0 -o eth1 -p udp -d $ISERVER --dport
$port -j ACCEPT
#done
$IPTABLES -A FORWARD -i eth1 -o eth0 -j ACCEPT
# Allow Connection between the Web/Mail Server and the DHCP Server
$IPTABLES -A FORWARD -i eth2 -o eth1 -j ACCEPT
$IPTABLES -A FORWARD -i eth1 -o eth2 -m state --state
ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -t nat -A POSTROUTING -o eth0 -j MASQUERADE
--------------------------
Additional Links:
The netfilter homepage:
http://www.netfilter.org/
Packet Filtering HOWTO
http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO.html
NAT HOWTO
http://www.netfilter.org/documentation/HOWTO//NAT-HOWTO.html
Networking Concepts HOWTO
http://www.netfilter.org/documentation/HOWTO//networking-concepts-HOWTO.html
The above HOWTOs are very useful. Paul 'Rusty' Russell is a pretty
entertaining author, too.
The iptables manpage
$ man iptables
Search Strategy:
No searching, just read the HOWTOs and iptables manpage.
I hope this solves your problems. If something doesn't work
right, let me know. If you have further problems, you will
probably need to turn logging on--see the Packet Filtering HOWTO
for details.
Best regards,
bikerman |