Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to configure a complex firewall for my team. We're looking at six interfaces with different types of security zones and flows.

I have a well-documented, clean firewall configuration script, but if I run iptables-save, the results will of course have no comments. The results will also be out of sync with our documented policy.

Is there a nice, clean way that I can use my own configuration file on Redhat without undoing Redhat's Rube Goldberg scripts? at the same time, I'd like to ensure that those same scripts don't stomp on my config or e.g., rip the firewall wide-open as soon as somebody does an ifdown/ifup.

share|improve this question

4 Answers 4

up vote 3 down vote accepted

I'd suggest writing a script, e.g.:

#!/bin/bash

## Firewall flushing etc
for t in raw nat mangle filter; do
  iptables -t $t -F
  iptables -t $t -X
done

## Default policies
while read table chain policy; do
  [[ -z $table ]] && continue  ## Skip empty lines
  iptables -t $table -P $chain $policy
done <<< "
  raw    PREROUTING DROP
  filter FORWARD    DROP
  filter INPUT      DROP
  filter OUTPUT     ACCEPT
"

## These rules perform foo
iptables ...
iptables ...

## These rules perform bar
iptables ...
iptables ...

... and so on ...

## Save them
iptables-save > /etc/firewall-rules.conf

exit 0

Then, edit rc.local and add:

/sbin/iptables-restore < /etc/firewall-rules.conf

Right before the exit 0 line.

Now, if you need to modify your firewall, just edit and execute the first script.

share|improve this answer
    
IMHO writing scripts for iptables is dumb. –  poige Apr 2 '11 at 6:48
    
This looks like a good solution, it's scripting on top of Redhat's system, so nothing needs to be modified. rc.local is easy for novice admins to understand. A single script is really easy to backup, restore and port in the event the box needs to be rebuilt. An admin who understands Redhat, but doesn't know the firewall config won't be trapped by this either. Thank you :-) –  mgjk Apr 2 '11 at 13:28
    
@mgjk remember not to actually call tens or hundreds of iptables command from rc.local; every invocation of iptables is slower because of how it works. Always use only iptables-restore from rc.local –  pepoluan Apr 3 '11 at 8:46

The easiest way to manage your iptables configs on RHEL is to simply ignore the system provided config scripts entirely. I manage all of my RHEL systems with puppet, and use a fragments based approach as per Module Iptables Patterns.

This may not work for you if you're not a puppet shop, but at it's base all this does is build out the file /etc/sysconfig/iptables directly. That approach will likely work very well for you. In this way you can still keep your comments, and order the rules however you would like.

share|improve this answer

As I've already said IMHO writing SHELL scripts for configuring iptables is a dumb approach.

iptables own facilities allow implementing 99.99 % of policies w/o need to bring in some additional things like SHELL-scripting, for e. g.

If you need comments to be saved inside your iptables config, you use -m comment --comment ""

share|improve this answer
    
(1) -m comment maxes out at 256 chars, and you can't put in newlines. (2) when you redisplay the rules using iptables-save or iptables -L, they will most likely be not the same order as you put it in, making complex rules harder to debug. –  pepoluan Apr 3 '11 at 8:45
    
1) Are you writing books or firewall rules? Long comments are prohibited in the whole IT-industry. Comments are either small explanations or a reference to long one. 2) Use proper chaining for that issue. –  poige Apr 3 '11 at 9:11
    
if the firewall is managed by only one person, no need for comments beside those to help you remember what you're doing. but for maintainability, you will want to make your iptables rules as clear as possible. in the future, when you get promoted let's say to a VP position, you will no longer be the one handling the nitty-gritty iptables stuff; it's your grunts doing the job, and you'd want them to 'hit the ground running', so to speak. –  pepoluan Apr 4 '11 at 5:47
    
You're deeply mistaken. If the firewall is NOT managed by the only one person it is to be documented with external docs (Wiki or alike). But it doesn't mean it has to be every-line commented. If the codes needs every line to be commented this is throw-out-immediately code. IT basis, man. –  poige Apr 4 '11 at 7:02

You could make your own startup script and add it to your existing services with chkconfig.

Here's a template that I often use.

It flushes all rules in place and replaces them with a custom set that allows ssh, http and https in.

#!/bin/bash
#
# firewall  firewall script
# description:  a firewall script
# chkconfig: 2345 91 09
#

IPTABLES=/sbin/iptables

start() {
    ret=0
    # input chain
    $IPTABLES -A INPUT -m state --state INVALID -j DROP || ret=1
    $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT || ret=1
    $IPTABLES -A INPUT -i lo -j ACCEPT || ret=1
    $IPTABLES -A INPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT || ret=1
    $IPTABLES -A INPUT -p tcp --dport 80 --syn -m state --state NEW -j ACCEPT || ret=1
    $IPTABLES -A INPUT -p tcp --dport 443 --syn -m state --state NEW -j ACCEPT || ret=1
    # output chain
    $IPTABLES -A OUTPUT -m state --state INVALID -j DROP || ret=1
    $IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT || ret=1
    $IPTABLES -A OUTPUT -o lo -j ACCEPT || ret=1
    return $ret
}

stop() {
    ret=0
    $IPTABLES -F || ret=1
    $IPTABLES -F -t nat || ret=1
    $IPTABLES -X || ret=1
    $IPTABLES -P INPUT ACCEPT || ret=1
    $IPTABLES -P OUTPUT ACCEPT || ret=1
    $IPTABLES -P FORWARD ACCEPT || ret=1
    return $ret
}

panic() {
    ret=0
    $IPTABLES -F || ret=1
    $IPTABLES -F -t nat || ret=1
    $IPTABLES -X || ret=1
    $IPTABLES -P INPUT DROP || ret=1
    $IPTABLES -P OUTPUT DROP || ret=1
    $IPTABLES -P FORWARD DROP || ret=1
    $IPTABLES -Z || ret=1
    $IPTABLES -t nat -Z || ret=1
    return $ret
}

status() {
    $IPTABLES -t filter -L -v --line-numbers
    $IPTABLES -t nat -L -v --line-numbers
    return 0
}

restart() {
    stop
    start
}

case "$1" in
    start)
        stop
        start
        RETVAL=$?
        ;;
    stop)
        stop
        RETVAL=$?
        ;;
    restart)
        restart
        RETVAL=$?
        ;;
    status)
        status
        RETVAL=$?
        ;;
    panic)
        panic
        RETVAL=$?
            ;;
    *)
        echo $"Usage: $0 {start|stop|restart|status|panic}"
        exit 1
        ;;
esac

exit $RETVAL

You could simple put this script inside /etc/init.d/, make it executable and run chkconfig firewall --add && chkconfig firewall on.

You can now enable the firewall with service firewall start, service firewall panic stops all network traffic and service firewall stop disables the firewall.
I think you get the idea.

The major advantage of this system is that you have one script that you can heavily customize and write comments in, without touching any of the existing iptables settings of the OS.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.