[SLUG] iptables woes

From: Ian C. Blenke (ian@blenke.com)
Date: Wed Jul 26 2006 - 23:57:03 EDT


Steve forwarded this to me privately, I'm going to go ahead and copy the
SLUG list on this to benefit others.

steve szmidt wrote:

> Hi Ian,
>
> Do you have time to help me with an iptables rule issue?
>
>

We've been using a perl script that Derek Glidden write a while ago when
he worked at NKS (with some heavy modifications since then to work with
our automated deployment evironment) to generate our iptables rules for
quite some time now. Honestly, I _rarely_ look at a raw iptables rules
anymore (haven't in years at this point). Here is an early raw Derek
shell script in the SLUG FAQ:

    http://www.suncoastlug.org/faq.html#iptables

Check that out and see if it helps, or read on...

> I've only used OpenBSD as a firewall, subsequently I'm not at all familiar
> with iptables. I've been all over but not been able to see what's wrong.
>
>

Why not continue? If something isn't broke, and you understand it, why
change?

I've used ipfw and openbsd quite a bit, also ipfw and mac os/x, but
we've long ago required abilities from iptables that exceed those of
ipfw. OpenBSD does have traffic shaping and prioritization if you're
doing an A/V solution of some sort, though I personally prefer the many
Linux options. Jason Boxman can go on at length about Linux shaping and
prioritization if you're interested (he's actually far more adept at the
latest stuff than I am at this point).

> Basically I got a router with on the wire antivirus checking over ports 21 25
> 80 & 110. I got all of it to work including inbound web access, except for
> outbound web traffic. Which ought to have been easy.
>
> The structure is like this:
>
> (Internet) - [Router & NAT] - [A/V & Firewall] - (LAN)
> Internal Router IP is 192.168.1.254
> External A/V IP is 192.168.1.253
> Internal A/V IP is 192.168.0.254
> Web server on 192.168.10
>
>

Er, this just confused me, actually. Is 192.168.1.0/24 _internal_ or
_external_? And did you mean 192.168.0.10 for the web server?

> Router redirects inbound port 80 to web server.
> Web server cannot reside elsewhere as its a MS box will all sorts of internal
> SQL use and so on. (I know bad design, not mine. I added the A/V box)
>
> Internal users use the webserver, remote clients use it too.
>
> Looking over the layout with lines starting with colon etc, and the sequence
> of it all, seem to have meanings which I can't find references to.
>
> I need to debug this to allow outbound web access over port 80.
>
> Maybe you can just insert some comments as to what is going on?
>
> # Starting with NAT
> *nat
>
> # Redirect outbound traffic to different ports (for virus scanning).
> # But what's the significance of these first lines and the next three
> # following them?
> :PREROUTING ACCEPT [15:2530]
> :POSTROUTING ACCEPT [0:0]
> :OUTPUT ACCEPT [0:0]
> # Preroute so that it's done first
> -A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9080
> -A PREROUTING -i eth1 -p tcp -m tcp --dport 25 -j REDIRECT --to-ports 9025
> -A PREROUTING -i eth1 -p tcp -m tcp --dport 110 -j REDIRECT --to-ports 9110
>
>

Packets coming in on eth1 destined to be ip forwarded to another segment
behind the firewall are rewritten from port 80 to 9080, from port 25 to
9025, and from port 110 to port 9110. This just rewrites the destination
ports in the packets, it doesn't actually NAT them.

You probably want something like:

    # NAT rule for outbound routed traffic from 192.168.0.0/32 appearing
to come from 192.168.1.1 on eth0
    -A POSTROUTING -s 192.168.0.0/32 -o eth0 -j SNAT --to-source 192.168.1.1

    # DNAT rule for incoming traffic to 192.168.1.1:80 to 192.168.0.40:80
    -A PREROUTING -i eth0 -d 192.168.1.1 -p tcp -m tcp --dport 80 -j
DNAT --to 192.168.0.40:80

I don't see this anywhere in your original message. These are what
actually do the NAT.
The key here is understanding Destination NAT (DNAT) and Source NAT (SNAT).

> # OK here are the filters. Again same significance with colons
> *filter
> :INPUT ACCEPT [0:0]
> :FORWARD ACCEPT [0:0]
> :OUTPUT ACCEPT [4527:1298184]
> :RH-Firewall-1-INPUT - [0:0]
> ACCEPT
> -A INPUT -j RH-Firewall-1-INPUT
>
>

INPUT packets are those received directly by the firewall destined for
the firewall itself.

> -A FORWARD -j RH-Firewall-1-INPUT
>
>

FORWARD packets are those received to be ip forwarded along to another
network on the other side of the firewall.

Both INPUT and FORWARD are being chained to run through the
"RH-Firewall-1-INPUT" ruleset below:

> -A RH-Firewall-1-INPUT -i lo -j ACCEPT
>
>

Always allow loopback traffic to 127.0.0.1. This has security
implications for spoofed traffic, just so you know, though this isn't
causing any visible problems (probably saving you from some).

> -A RH-Firewall-1-INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
>
>

TCP port 80 packets coming in on eth1 are being marked as state NEW and
ACCEPTed, primarily used for the stateful RELATED,ESTABLISHED check
below. Note: this doesn't NAT anything, it just sets up packets to
statefully not be dropped.

> -A RH-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
>
>

Allow any icmp packet. Also dangerous, but also not causing your problems.

> -A RH-Firewall-1-INPUT -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT
>
>

Permit incoming multicast UDP zeroconf bonjour dynamic DNS announcements

> -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
>
>

Allow UDP IPP (Internet Printing Protocol). Odd that you're excluding
TCP here.

> -A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
>
>

Allow related,established state packets through, as marked by the above
NEW state match for port 80 traffic. Still no NAT though, this just lets
the packets through, it doesn't rewrite the IPs.

> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
> -A RH-Firewall-1-INPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 110 -j ACCEPT
>
>

Allow FTP, SMTP, SSH, DNS, HTTP, and POP3 packets. Still no NAT though,
just permitting the packets.

> # These might not need a rule as it's internal redirect. I just did it to
> # cover my bases.
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 9080 -j ACCEPT
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 9012 -j ACCEPT
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 9025 -j ACCEPT
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 9021 -j ACCEPT
> -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 9110 -j ACCEPT
>
>

More permitting packets, no NAT...

> # Grab all rule
> -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
> COMMIT
>
>

Send an icmp host prohibited reject message for everything else.

Your big problem here is a lack of NAT/masquerading.

Look at Derek's script, particularly at the MASQUERADE line:

        ## Set up IP Masquerading for internal network
        iptables -t nat -A POSTROUTING -o $EXTERNAL_IFACE -s $INTERNAL_NET -j MASQUERADE

You need something like this in your config, or something like the
DNAT/SNAT I pasted above.

Again, look at Derek's script and then let me know if you stumble on
something you can't figure out.

    http://www.suncoastlug.org/faq.html#iptables

Enjoy!

 - Ian C. Blenke <ian@blenke.com> http://ian.blenke.com/



-----------------------------------------------------------------------
This list is provided as an unmoderated internet service by Networked
Knowledge Systems (NKS). Views and opinions expressed in messages
posted are those of the author and do not necessarily reflect the
official policy or position of NKS or any of its employees.



This archive was generated by hypermail 2.1.3 : Fri Aug 01 2014 - 15:07:30 EDT