Help with rc.firewall script

Hello experts:

I'm fairly new to iptables, so I used a firewall generator to create my iptable firewall script.  Everything seems to work fine, except I wanted to limit what ports could be used for our internal users.  My firewall script is 16 pages long, so I didn't want to clutter up this site with several pages, so I've included a link to a pdf file of my firewall script.

I'm trying to forward ports 80 and 3389 to an internal server, but I seem to be having difficulties when I remove the highlighted line on page 13 of the firewall script.  The catch 22 is, if I leave this line in the script, users have access to more ports than I want to provide.

How can one overcome the problem by limiting the outgoing ports [which I have specified on pages 11-12 in the tcp_outbound chain] while allowing traffic from the outside to be forwarded to an internal server?

http://www.jotathought.com/rc.pdf  <-- firewall script address
LVL 4
escheiderAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Tim_UtschigCommented:
<PET_PEEVE>
Dear lord, why complicate a text file by converting it to PDF?  If you wanted to point us at a certain section, just add a comment in it or tell us a line number.
</PET_PEEVE>

Try changing "ACCEPT" in that highlighted line to "DROP".

Or change the default FORWARD policy to DROP rather than ACCEPT (see page 6).
ahoffmannCommented:
please post the relevant line(s), not all 16 pages
escheiderAuthor Commented:
PET PEEVE Noted ..


Here is the rule that I am having trouble with.  The difficulty I am having is I need

1) Restrict internal users by providing the necessary services [ports] they need to accomplish their jobs.  I have done this by specifying which ports should be available.

2) Allow ports 80 and 3389 to be forwarded to an internal server to provide access to web and terminal service services.

The problem I am having, is when I either remove the rule below or change it to DROP, WEB and Terminal Service services are not available to the outside.  If I keep it at ACCEPT, then users have a plethora of ports available to use.  So I need to provide the two services to the public while restricting access to specified ports to internal users.


# If not blocked, accept any other packets from the internal interface
$IPT -A FORWARD -p ALL -i $LOCAL_IFACE -j ACCEPT           <------------------ this rule

# Deal with responses from the internet
$IPT -A FORWARD -i $INET_IFACE -m state --state ESTABLISHED,RELATED \
     -j ACCEPT

# Port Forwarding is enabled, so accept forwarded traffic
$IPT -A FORWARD -p tcp -i $INET_IFACE --destination-port 80 \
     --destination 10.1.1.91 -j ACCEPT

$IPT -A FORWARD -p tcp -i $INET_IFACE --destination-port 3389 \
     --destination 10.1.1.91 -j ACCEPT

# Log packets that still don't match
$IPT -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
    --log-prefix "FORWARD packet died: "


Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

ahoffmannCommented:
> $IPT -A FORWARD -p ALL -i $LOCAL_IFACE -j ACCEPT           <------------------ this rule
should be rewritten as follows for each port (80 just as example)

$IPT -A FORWARD -p ALL -i $LOCAL_IFACE -o $INET_IFACE --dport 80 -j ACCEPT

then you need the way back, which depends on your other network/firewall settings, if you're using private IP, then you probably use NAT also, then the general -j MASQUERADE should do the trick
Tim_UtschigCommented:
I just noticed that page 7 is the actual place the chain policies are set.  Page 6 just resets them all to the defaults.  So FORWARD was set to DROP after all.

Is there any more to this file?  Last line I see on page 15 is:

    echo "Load rules for mangle table..."

and page 16 is blank.

If this were a plain text file I could test these rules.  pdftotext mangles it beyond usefulness.
Tim_UtschigCommented:
Quoting ahoffman:
> > $IPT -A FORWARD -p ALL -i $LOCAL_IFACE -j ACCEPT           <------------------ this rule
> should be rewritten as follows for each port (80 just as example)

> $IPT -A FORWARD -p ALL -i $LOCAL_IFACE -o $INET_IFACE --dport 80 -j ACCEPT

It seems there is already a "tcp_outbound" chain which should be the place to set the allowed outbound TCP ports.

So I guess we need to figure out why the tcp_outbound chain isn't doing its job.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ahoffmannCommented:
> I'm fairly new to iptables ..
> .. , so I used a firewall generator to create my iptable firewall script. ..
> ..  My firewall script is 16 pages long, ..
hmm, you either need to get used to iptables, at least to its concepts
or I'd suggest that you break down your rules to exactly those you need.
Start with a simple setup which uses DROP as policy and add only those rules you need, I guess something up to 20 rules (which is 1/2 page ;-)

To help you we also need a description of your network topology.
escheiderAuthor Commented:
[Routable IP] Router [192.168.1.1]  ----> DMZ -----> [192.168.1.2] Linux [10.1.1.1] ----->  [10.1.1.0/24] Private network

I'd love to have something simple that is easy to understand.  I'm using Squid Proxy server on this firewall, and need the following available to internal users:  20,21,22,25,110,3128,3389 and 6873.  I also need to have port 80 redirected to port 3128.

In addition, ports 80 and 3389 from the external interface need to be forward to 10.1.1.91.

Of course I'd need to be able to ssh to the firewall/proxy server and have unlimited access on lo.

The only reason I used the iptables generator is because I searched this forum and that was a solution provided.
escheiderAuthor Commented:
Tim:

I entered the following commands:

$IPT -A FORWARD -p ALL -i $LOCAL_IFACE -o $INET_IFACE --dport 80 -j ACCEPT
$IPT -A FORWARD -p ALL -i $LOCAL_IFACE -o $INET_IFACE --dport 3389 -j ACCEPT

and received the following errors when I ran the script:

iptables v1.2.8: Unknown arg `--dport'
Try `iptables -h' or 'iptables --help' for more information.
iptables v1.2.8: Unknown arg `--dport'
Try `iptables -h' or 'iptables --help' for more information.
Tim_UtschigCommented:
--dport is not available unless you use -p tcp or -m tcp
Tim_UtschigCommented:
(or one of several other protocols that use port numbers)
ahoffmannCommented:
good eyes :)
escheiderAuthor Commented:
Okay guys .. I appreciate the effort, but I'm still stuck.

Can you help me with a basic script, scraping the old one, so I can grasp the iptables concepts?
Jon_FergusonCommented:
Here is a sample of a script that I use.

WAN = eth0 # Red/Internet/Untrusted interface
LAN = eth1 # Black/Intranet/Trusted interface

## CLEAR TABLES
for T in filter nat; do
  iptables -t $T -F
  iptables -t $T -X
done

# Create tables for custom rules.
iptables -N input_rule
iptables -N output_rule
iptables -N forwarding_rule
iptables -t nat -N prerouting_rule
iptables -t nat -N postrouting_rule

### INPUT
###  (connections with self as destination)

  # base case
  iptables -P INPUT DROP
  iptables -A INPUT -m state --state INVALID -j DROP
  iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
  iptables -A INPUT -p tcp --tcp-flags SYN SYN --tcp-option \! 2 -j  DROP

  #
  # insert accept rule or to jump to new accept-check table here
  #
  iptables -A INPUT -j input_rule

  # allow
  iptables -A INPUT -i \! $WAN  -j ACCEPT       # allow from lan/wifi interfaces
  iptables -A INPUT -p icmp     -j ACCEPT       # allow ICMP

  # reject (what to do with anything not allowed earlier)
  iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
  iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable

### OUTPUT
### (connections with the self as source)

  # base case
  iptables -P OUTPUT DROP
  iptables -A OUTPUT -m state --state INVALID -j DROP
  iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

  #
  # insert accept rule or to jump to new accept-check table here
  #
  iptables -A OUTPUT -j output_rule
  # allow
  iptables -A OUTPUT -j ACCEPT          #allow everything out

  # reject (what to do with anything not allowed earlier)
  iptables -A OUTPUT -p tcp -j REJECT --reject-with tcp-reset
  iptables -A OUTPUT -j REJECT --reject-with icmp-port-unreachable

### FORWARDING
### (connections routed through self)

  # base case
  iptables -P FORWARD DROP
  iptables -A FORWARD -m state --state INVALID -j DROP
  iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
  iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

  #
  # insert accept rule or to jump to new accept-check table here
  #
  iptables -A FORWARD -j forwarding_rule

  # allow
  # iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT # Commented out to control lan access, everyting is blocked

  # reject (what to do with anything not allowed earlier)
  # uses the default -P DROP

### MASQ
  iptables -t nat -A PREROUTING -j prerouting_rule
  iptables -t nat -A POSTROUTING -j postrouting_rule
  iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE


## Place custom rules in input_rule, output_rule, forwarding_rule, prerouting_rule, and postrouting_rule

### dns rules for LAN clients
iptables -t nat -A prerouting_rule -i $LAN -p tcp --dport 53 -j ACCEPT
iptables        -A input_rule      -i $LAN -p tcp --dport 53 -j ACCEPT
iptables -t nat -A prerouting_rule -i $LAN -p udp --dport 53 -j ACCEPT
iptables        -A input_rule      -i $LAN -p udp --dport 53 -j ACCEPT

### dhcp rules for LAN clients
iptables -t nat -A prerouting_rule -i $LAN -p udp --dport 67:68 -j ACCEPT
iptables        -A input_rule      -i $LAN -p udp --dport 67:68 -j ACCEPT

### www access for LAN clients
iptables        -A forwarding_rule -i $LAN -p tcp --dport 80 -j ACCEPT
iptables        -A forwarding_rule -i $LAN -p tcp --dport 443 -j ACCEPT

### mail access for LAN clients
iptables        -A forwarding_rule -i $LAN -p tcp --dport 110 -j ACCEPT
iptables        -A forwarding_rule -i $LAN -p tcp --dport 25 -j ACCEPT

### Allow SSH on the WAN interface
iptables -t nat -A prerouting_rule -i $WAN -p tcp --dport 22 -j ACCEPT
iptables        -A input_rule      -i $WAN -p tcp --dport 22 -j ACCEPT

### rdp on wintel host
iptables -t nat -A prerouting_rule -i $WAN -p tcp --dport 3389 -j DNAT --to 10.0.0.12
iptables        -A forwarding_rule -i $WAN -p tcp --dport 3389 -d 10.0.0.21 -j ACCEPT




### DMZ (should be placed after port forwarding / accept rules)
iptables -t nat -A prerouting_rule -i $WAN -j DNAT --to 10.0.0.250
iptables        -A forwarding_rule -i $WAN -d 10.0.0.250 -j ACCEPT
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Linux Security

From novice to tech pro — start learning today.