# Start firewall script at boot or iptables

## Decibels

I see a lot of questions on firewall scripts and starting them at boot.

I am trying to figure if I am missing something here.

1)  If you have iptables configured and some firewall rules written in the 

     tables and added it to /etc/init.d for starting at bootup. Then that should     

     be loading any firewall rules you have written when you bootup.

2)  If #1 is true then there is no need to install another firewall program

     and add it to default runlevel too.  Cause the rules are being loaded 

     and implimented at bootup. 

3)  You would only need another firewall program installed if you didn't  

     want to or couldn't write your own rules. Then still, after it is ran once, 

     it should have the rules written to iptables and as long as iptables is  

     default runlevel, the firewall program you installed doesn't need to

     run at boot cause it has done it's job. 

4)  Then you should only need to run the firewall program again if you

     wanted to changed some rules.

Are these assumptions correct or am I missing something? Cause I have iptables setup with some rules. Recently read Daniel Robbins Stateful IPTables tutorial at Intel and really like what he had to say on them. I took his script and modified it to meet several needs (I don't need forwarding, but a friend does). 

I was going to put the script in /etc/init.d and set it to run at boot. But realized that I already have the rules in place now and unless I want to change it or stop the firewall. I don't need to run the script again cause iptables starts at boot.

----------

## xpunkrockryanx

when iptables loads, it doesnt automatically load the rules that you had set in place previously, it relies on you running the script to add the rules. for example, you have your firewall set up currently, but if you rebooted, it would no longer be in place. you should set the script you have there to run on each boot. to answer your individual questions specifically:

1.) only if what added to /etc/init.d to run on boot was actually the rules themselves, not just the iptables module.

2.) correct, if #1 was correct.

3.) some confusion here as to what you refer when you say "another firewall program." if by "firewall program" you mean shell script to add iptables rules, then no, in fact the "program" would need to be run on boot each time. i guess it would need to be run on boot each time regardless. to be clear, everything that was entered into iptables is lost on reboot.

4.) correct, unless you reboot, in which case you'd need to run the firewall program again.

-ryan

----------

## Decibels

Hence the confusion. See, they are saved if you want them saved.

Iptables userspace when emerged doesn't make the directory /var/lib/iptables or the file /var/lib/iptables/rules-save.

But, /etc/conf.d/iptables states:

```
# Location in which iptables initscript will save set rules on

# service shutdown

IPTABLES_SAVE="/var/lib/iptables/rules-save"
```

So you: mkdir /var/lib/iptables  and touch /var/lib/iptables/rules-save

Run your firewall script or write some rules to iptables. Then run

/etc/init.d/iptables restart

The result is:

```
 * Stopping firewall and saving iptables state...                       [ ok ]

 * Loading iptables state and starting firewall...

 * Restoring iptables ruleset                                                          
```

Test they are there with iptables -L -v or iptables -L -n

```
Chain INPUT (policy DROP)

target     prot opt source               destination

ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:80 state NEW

ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0          tcp dpt:25 state NEW

LOG        icmp --  0.0.0.0/0            0.0.0.0/0          icmp type 8 limit: avg 1/min burst 5 LOG flags 0 level 5 prefix `PING:'

ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0          icmp type 8 limit: avg 2/sec burst 5

myfilter   all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy DROP)

target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

Chain myfilter (1 references)

target     prot opt source               destination

ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          state RELATED,ESTABLISHED

ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0          state NEW

LOG        all  --  0.0.0.0/0            0.0.0.0/0          state INVALID LOG flags 0 level 4 prefix `INVALID:'

REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0          reject-with tcp-reset

REJECT     all  --  0.0.0.0/0            0.0.0.0/0          reject-with icmp-port-unreachable

```

Now, reboot, they are still there and being enforced. As long as you had iptables default runlevel.

----------

## Decibels

I must take part of the back. In essence you do load the firewall rules up upon each reboot from the /var/lib/rules-save. But it isn't I guess what you would really call a script, it is just the rules that you already wrote saved.

----------

## Printhead

Instead of running iptables from init.d and having the rules as they stand saved on shutdown, you can just add your script to /etc/conf.d/local.start and the ruleset will load from there on each boot.

That way, the script stays just as you set it up with comments and layout retained, which makes things easier to tweak and understand in my inexperienced opinion.

----------

## Decibels

Oh, I don't want to be misunderstood. You can do it either way!!!

It just seems that some people think you need to run iptables from init.d and also install a firewall program like fwbuilder or guarddog,... and also start it from init.d (unless I am wrong, and could be).

All I am trying to say is that you can write your own rules or use a program like fwbuilder to help you write one. But you don't have to 'also' have both programs start from init.d. Just starting iptables is good enough. If you made the folder /var/lib/iptables and touched the file /var/lib/iptables/rules-save, then the iptables rules ARE SAVED and will be reloaded upon reboot. 

So as long as you didn't just type the rules in at the prompt in a terminal, but wrote a small script to do it for you like I did.  Then you still have

 (to quote): "the script stays just as you set it up with comments and layout retained"

For example I wrote a script to encompass two setups: I don't have forwarding enabled or a LAN that I want to masquerade for ICS, my Dad does. So the script looks for the forwarding enabled in /etc/conf.d/iptables, if set then inserts the ip_forwarding and masquerade rules. The script is also setup with start (write the rules and save them) and stop (flush the rules). SO you could run start, stop, change the rules, add comments,... BUT, the script doesn't have to be restarted at boot each time, iptables rules are already saved and loaded upon next reboot.

Most of this is copied from 'Daniel Robbins': Stateful IPTables tutorial at Intel.com. Then changed to work with the tutorial I wrote to Masquerade on a  LAN with Two Computers, or a standalone with no LAN. BUT, it only has to be ran once to implement the rules, unless you want to change them.

```
#!/bin/bash

# To use: chmod +x firewall-script.sh  (rename if want).

# To start: ./firewall-script.sh start

# To stop:  ./firewll-script.sh stop

#

# interfaces:

# eth0 : Connected to Internet (untrusted Cable Modem)

# eth1 : Connected to internal LAN (trusted LAN)

#

# Setup your CABLE & LAN Interfaces here. 

CABLEE="eth0"     #Set Cable Modem Interface

LANE="eth1"       #Set LAN Interface 

#

# Services Enabling for INPUT chain, respectively TCP ports -- 80 and 25

# You will see them in INPUT chain (iptables -L -n).

SERVICES="http smtp"

#

# variable to check for IP_FORWARD setting.

FRWD=0 

#

# Start case: Insert rules into iptables.  

case "$1" in

start)

    {

   echo "Inserting Rules and Starting Firewall."

   # Check if IP_FORWARD enabled in /etc/conf.d/iptables.

   # Don't need it if not Masquerading or on LAN.

   echo "    >> Checking if IP_FORWARDING is enabled."

   if grep -q 'ENABLE_FORWARDING_IPv4="no"' /etc/conf.d/iptables < /dev/null

   then

      {  # Just a notice to Root if wants to Enable IP_FORWARDING.

      echo

      echo -e "   --> If on LAN or want MASQUERADING, change"

      echo -e "       \042no\042 to \042yes\042 in /etc/conf.d/iptables:"

      echo -e "       ENABLE_FORWARDING_IPv4=\042no\042"

      echo    "       Then Stop Firewall, then Start Firewall."

      echo

      }

    else

      {

      echo

      echo "   --> FORWARDING IS Enabled in /etc/conf.d/iptables."

      echo "       Enabling FORWARDING & MASQUERADE in Rules."    

      echo

      FRWD=1   # Forwarding is enabled, set variable to 1

      }

   fi

   

   # Set a Default ( -P )policy of DROP; deny-by-default for security:

   iptables -P INPUT DROP

   iptables -P FORWARD DROP

   # myfilter chain:

   # this chain contains rules common to our FORWARD (if enabled) and INPUT chains, all in one place.

   # first, we create a new "myfilter" chain;

   # then, we add a rule to accept ESTABLISHED and RELATED connections from anywhere;

   # then, we add a rule to accept NEW connections coming in from anywhere but our untrusted eth0 interface;

   # then, we add a rule to log any incoming INVALID packets;

   # then, we add a rule to reject any incoming tcp connection with tcp-reset for fast, stealthy disconnect;

   # then, we add a rule to reject any not-yet-handled connections with icmp-port-unreachable.

   # everything else falls off the end of this chain and goes back to the next rule (if any) in the

   # parent INPUT or FORWARD (if enabled) chain.

   #

   iptables -N myfilter

   iptables -A myfilter -m state --state ESTABLISHED,RELATED -j ACCEPT

   iptables -A myfilter -m state --state NEW -i ! $CABLEE -j ACCEPT

   iptables -A myfilter -m state --state INVALID -j LOG --log-prefix "INVALID:" --log-level warning

   iptables -A myfilter -p tcp -j REJECT --reject-with tcp-reset

   iptables -A myfilter -j REJECT --reject-with icmp-port-unreachable

   #

   # INPUT chain:

   # first, we loop through our SERVICES variable and add a rule for each public service on our firewall;

   # then, we add a rule to log any pings to our firewall box from the Internet (max 1/minute);

   # then, we add a rule to accept up to 2 pings per second to our firewall box from the Internet;

   # then, we direct any traffic that doesn't match these rules to our standard myfilter chain.

   # everything else falls off the end of this chain and gets a default policy of DENY.

   #

   for x in $SERVICES

   do

      iptables -A INPUT -p tcp --dport ${x} -m state --state NEW -j ACCEPT

   done

   iptables -A INPUT -p icmp -i $CABLEE --icmp-type echo-request -m limit --limit 1/minute -j LOG --log-prefix "PING:" --log-level notice

   iptables -A INPUT -p icmp -i $CABLEE --icmp-type echo-request -m limit --limit 2/second -j ACCEPT

   iptables -A INPUT -j myfilter

   #FORWARD chain:

   #simply forward all FORWARD traffic to our myfilter chain.

   #if any traffic were to make it through the myfilter chain, it would fall off the end of the FORWARD

   #chain and get a default policy of DENY.

   if [ "$FRWD" -eq 1 ]

      then

         iptables -A FORWARD -j myfilter

   fi

   #Setup Masquerading 

   if [ "$FRWD" -eq 1 ]

      then

         {

         iptables -A FORWARD -i $CABLEE -o $LANE -m state --state ESTABLISHED,RELATED -j ACCEPT

            iptables -A FORWARD -i $LANE -o $CABLEE -j ACCEPT

              iptables -A FORWARD -j LOG

         iptables -t nat -A POSTROUTING -o $CABLEE -j MASQUERADE

         }

   fi

   # Restart iptables to save rules in /var/lib/iptables/rules-save

   /etc/init.d/iptables restart

   exit 0

         }

   ;;   # End of Start

 

stop)

    {

   echo "Stopping firewall and Clearing Rules."

   # Clear tables

   echo 0 > /proc/sys/net/ipv4/ip_forward

   echo "    --> Disabling IP_FORWARD"

   # Note: above only disables forwarding in sysctl temp.

   # You will have to disable/enable in /etc/conf.d/iptables or /etc/sysctl.conf

   # if you want it changed upon reboot.

   iptables -F INPUT               # Flush INPUT Chains

   iptables -P INPUT ACCEPT        # Set INPUT Default Policy to ACCEPT

   iptables -F FORWARD             # Flush FORWARD Chains

   iptables -P FORWARD ACCEPT      # Set FORWARD Default Policy to ACCEPT

   iptables -t nat -F POSTROUTING  # Flush NAT table

   iptables -F myfilter            # Flush myfilter chains

   iptables -X myfilter            # Delete myfilter chain

   echo "    --> Note: If you reboot before running firewall script again"

   echo "        your firewall rules will not be saved and you will have NO"

   echo "        firewall. If you want to just temporarily stop firewall use:"

   echo "       ( /etc/init.d/iptables stop)  instead."

   exit 0

         }

   ;;   # End of Stop

esac

```

----------

## doug-x07

I have another approach that you may find easier to manage. Firslty modify you /etc/init.d/firwall script as described in the Gentoo security guide to automatically check on start up if you have a given firewall rules file or load default rules. 

You can then create a second shell script to handle the on the fly changes and firewall configuration as in the stateful IP Tables tutorial. No need to run it from start up as it doesn't handle the actual daemon directly. This allows you to call the start, stop and reset functions of /etc/init.d/firewall as needed whilst maintaining the service dependcies and sanity checks of Gentoo init. 

The example in the security guide only allows me to call the start stop and reset functions. I looked in the runscript.sh source and that is apparently all it accepts as arguments (??). So I then stuck a panic, save (to the same file as referenced in /etc/init.d/firewall that way you save a rule set for next startup) and showstatus functions in my shell script and defined other dynamic rules that I occasionally require. Now you have two firewall scripts, the basic init.d one for service start ups and a general shell script that you run on top of it as needed for managing the dynamic rule configuration, adding or saving configurations.

Drobbins tutorial can be a bit misleading for use with geentoo as it appears to be deliberately aimed for compatibility with all the different start up mechanisms that you can find in Linux. Great tutorial though and check out the dynfw ebuild in portage if you don't want to hack your own scripts.

Just my 2 cents on the subject.

----------

## tomaw

```

 * Stopping firewall and saving iptables state...                       [ ok ]

 * Loading iptables state and starting firewall...

 * Restoring iptables ruleset                                                          

 
```

It seems that iptables no longer saves the rules when shut down, only when doing:

```
/etc/init.d/iptables save
```

Is there a way to make it 'just happen'?

Tom[/b]

----------

## ventricle

I don't know how to explain this, but when I run your script (changing CABLEE to PPPE because I have a modem) it starts OK, but I am unable to 'ping www.google.com'. 

In fact, even if I run stop on your script, it doesn't fix it. I actually have to /etc/init.d/iptables stop in order to let me ping google again!

----------

