1. |
Overview |
- Multiple Rule-Sets
- Saves multiple rule-sets — OK, this bit is borrowed from Debian.
- Modular Rule-Sets with Separate Restart of Modules
- Breaks the rule-set into many distinct chains each of which represents one service and where each such service can be restarted/reconfigured separately and easily.
- Automatic Reversion of Prevous Ruleset
- There is a simple mechanism for automatically reverting to a previous ruleset, which is essential for remote-administration of firewalls!
Kudos to the Debian people from which the multiple rule sets stuff is borrowed.
2. |
Complete File Listing |
init script and configuration file for it:
Scripts to setup the rule-set (which can be saved and used by the init) script:
- /root/etc/:
At least these two rule-sets are required — these are the rule-sets applied by /etc/init.d/iptables start and stop, respectively:
/var/lib/iptables/active
inactive
3. |
Initial Setup |
- Setup and Save an "Empty" Rule-Set
-
This is the rule-set used to "switch off" the firewall. Set all
policies to ACCEPT and delete/flush all chains:
iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT for i in filter nat mangle do $IPT -t $i -F $IPT -t $i -X doneSave the "empty" rule-set:/etc/init.d/iptables save inactive # # ...this is used by <C>/etc/init.d/iptables stop... # - Setup and Save Your (Default) Firewall Rule-Set
-
Customise /root/etc/iptables.rules.sh, then, and only then:
root> /root/etc/iptables.rules.sh --restart-total --no-revert ...enter NOREVERT to confirm or Ctrl-C to exit... NOREVERT root>and then save it as your standard firewall rule-set:root> /etc/init.d/iptables save active
4. |
Starting and Stopping the Firewall |
To switch off the firewall:
/etc/init.d/iptables stop
#
# ...which is the same as "/etc/init.d/iptables load inactive"...
#
To start the firewall:
root> /etc/init.d/iptables start
#
# ...same as "/etc/init.d/iptables load active"...
#
5. |
Other Rulesets |
Once you have initialised your alternative rule-set, for example by using a modified version of /root/etc/iptables.rules.sh, save for future use
/etc/init.d/iptables save customrules
and in that future
/etc/init.d/iptables load customrules
if required.
6. |
Automatic Reversion to Previous Ruleset |
root> /root/etc/iptables.rules.sh --restart-total
Total restart...
Will revert to saved set in 2 minutes...
Reverting using:
at -m -f /root/etc/iptables.load_active.sh now + 2 minutes
warning: commands will be executed using /bin/sh
job 25 at Wed Apr 2 17:40:00 2008
Issuing remaining firewall commands...
Function: restart_chain_ssh_service...
Time for a nice mug of tea.
and
root> atq
26 Wed Apr 2 17:43:00 2008 a root
After 2 minutes the previously-saved default rule-set is loaded and replaces
the set just initialised.
How does the automatic reversion work?
The following code fragment should explain.
From /root/etc/iptables.rules.sh:
Q_REV=""
REVERT_TIME="2 minutes"
if [ "$2" == "--no-revert" ] ; then
echo -e "\nNot reverting..."
until [ "$Q_REV" == "NOREVERT" ] ; do
echo -e " ...enter NOREVERT to confirm or Ctrl-C to exit..."
read Q_REV
done
echo -e "Confirmed --- NOT reverting..."
else
echo -e "\nWill revert to saved set in $REVERT_TIME..."
sleep 1
AT_CMD="at -m -f /root/etc/iptables.load_active.sh now + $REVERT_TIME"
echo -e "\nReverting using:"
echo -e " $AT_CMD\n"
$AT_CMD
echo -e "\nIssuing remaining firewall commands..."
fi
7. |
Avoiding Automatic Reversion to Previous Ruleset |
root> ./iptables.rules.sh --restart-total --no-revert
Total restart...
Not reverting...
...enter NOREVERT to confirm or Ctrl-C to exit...
NOREVERT
Confirmed --- NOT reverting...
Function: restart_chain_ssh_service...
Function: restart_chain_ssh_client...
Time for a nice mug of tea.
The new set of rules replaces those previously in place — the new set
is not yet saved. (Use /etc/init.d/iptables save active to save
the new rules ad the default set; otherwise use
/etc/init.d/iptables save <customset>.)
8. |
Breaking the Firewall into Chunks |
Example chunk:
# ...we want to talk to our local DNS servers...
$IPT -N DNS_LOOKUPS
$IPT -t filter -A OUTPUT -o $EXTINT -s $EXTIP -p udp --dport 53 -j DNS_LOOKUPS
$IPT -t filter -A INPUT -i $EXTINT -d $EXTIP -p udp --sport 53 -j DNS_LOOKUPS
for host in 130.88.13.7 130.88.203.7 130.88.200.6
do
$IPT -t filter -A DNS_LOOKUPS -d $host -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -t filter -A DNS_LOOKUPS -s $host -m state --state ESTABLISHED -j ACCEPT
done
$IPT -t filter -A DNS_LOOKUPS -j LOG --log-prefix " **DNS_LOOKUPS DROP** "
$IPT -t filter -A DNS_LOOKUPS -j DROP
#
# -- Pinhole chain:
# -- default-log-and-drop;
# -- we should use only trusted DNS servers, else nothing is secure!
#
9. |
Breaking the Firewall into Independently-Restartable Chunks |
One can restart the chain giving access to the SSH service on the machine independently of the rest of the firewall. After editing /root/etc/itables.rules.ssh_service as required:
/root/etc/iptables.rules.sh --restart-ssh-service
How does the SSH-service restart work?
The following code fragments should explain.
From /root/etc/iptables.rules.sh:
if [ "$1" == "--restart-ssh-service" ] ; then
restart_chain_ssh_service
exit
elif [ "$1" == "--restart-total" ] ; then
echo -e "\nTotal restart..."
else
echo -e "\nDoing nothing."
echo -e "\nUsage:"
echo -e " --restart-ssh-client"
echo -e " --restart-ssh-service"
echo -e " --restart-total [--no-revert]"
echo -e "\n"
exit
fi
From /root/etc/iptables.rules.sh
$IPT -N SSH_SERVICE $IPT -t filter -A INPUT -i $EXTINT -p tcp --dport 22 -d $EXTIP -j SSH_SERVICE $IPT -t filter -A OUTPUT -o $EXTINT -p tcp --sport 22 -s $EXTIP -j SSH_SERVICE restart_chain_ssh_servicewhere, from iptables.rules.functions.sh
restart_chain_ssh_service() {
echo "Function: restart_chain_ssh_service..."
$IPT -t filter -F SSH_SERVICE
for host in `cat /users/simonh/etc/iptables.rules.ssh_service | sed s/\#.*// | egrep "[a-z0-9]+"`; do
echo -n ""
$IPT -t filter -A SSH_SERVICE -s $host -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -t filter -A SSH_SERVICE -d $host -m state --state ESTABLISHED -j ACCEPT
done
$IPT -t filter -A SSH_SERVICE -j LOG --log-prefix " **SSH_SERVICE DROP** "
$IPT -t filter -A SSH_SERVICE -j DROP
#
# -- Pinhole chain for service on low-numbered port:
# -- default-log-and-drop:
# -- should be no other traffic to/from our port 22;
#
}