* Looking for some feedback on iptables manager script
@ 2009-08-27 1:30 Alex Samad
0 siblings, 0 replies; only message in thread
From: Alex Samad @ 2009-08-27 1:30 UTC (permalink / raw)
To: netfilter-devel
[-- Attachment #1.1: Type: text/plain, Size: 1019 bytes --]
Hi
I have a script that i use to manager my iptables rules, been working on
it a bit, basically for my own use.
I was wondering if I could get some feed back on it suggestions, hints
etc
basically it works on a directory structure to hold the chain for
example
/etc/firewall/DB/<PROFILE>/<TABLE>/<CHAIN>/<RULES>
Profile is optional
table - corresponds to filter/raw/mangle/nat/...
chain - the default ones and user created ones
rules - are in the format <orderID>Name
where orderID process in
ii<Number>
<number>
aa<number>
all sorted by number
I have used the iptables save and restore to build the changes into a
change file and I use traps to capture any issues and try and put the
tables back to their original state if there is a failure.
I was even thing that i could take the flat files and make then some
sort of tar/bzip/gzip + if you add in some sort of enc + sign you would
end up file a compressed signed file
I have attached the file
thanks
Alex
[-- Attachment #1.2: makefirewall --]
[-- Type: text/plain, Size: 10838 bytes --]
#!/bin/dash
# Makefirewall scripts
# uses a file/directory DB to store firewall information
# does an atomic add of rules, using iptables-restore
# Creates a WRKFILE in each directory from the rules
# places all the wrkfiles into a single file
# and process that with ip[,6]tables-restore
# Any errors will roll back to the original set of rules
#
# Verbose level
# 0x01 - actions
VRBFLG_ACTION=0x01
VERBOSEFLG=${VERBOSEFLG:-"0"}
# Base directory
BASEDIR=${BASEDIR:-"/etc/firewall"}
# Echo a string and limit it based on the flags
pstr(){
if [ $(( $VERBOSEFLG & $VRBFLG_ACTION )) -eq 1 ]
then
echo $1
fi
}
# Allow for different policy sets
[ ! -z "$BASE2DIR" ] && BASEDIR="$BASEDIR/$BASE2DIR"
if [ ! -d $BASEDIR ]
then
pstr "Base directory doesn't exist ($BASEDIR)"
exit 1
fi
#
# Database directory
DBDIR=${DBDIR:-"./DB"}
DB6DIR=${DB6DIR:-"./DB6"}
#
# DB specific variables names are in ./DB/.variables
VARIABLES=${VARIABLES:-".variables"}
#
# Defined Names
# Names of all the top level
TABLE_NAMES="filter nat mangle"
TABLE_filter="INPUT OUTPUT FORWARD"
TABLE_nat="PREROUTING POSTROUTING OUTPUT"
TABLE_mangle="PREROUTING INPUT OUTPUT FORWARD POSTROUTING"
TABLE6_NAMES="filter mangle"
TABLE6_filter="INPUT OUTPUT FORWARD"
TABLE6_mangle="PREROUTING INPUT OUTPUT FORWARD POSTROUTING"
# Used in BLOCKED chains
BLOCKED='.blocked'
NOTBLOCKED='.notblocked'
# Chain policy's
POLICY_FILE='.policy'
DEFAULT_POLICY=${DEFAULT_POLICY:-'DROP'}
DEFAULT_CHAIN='.defaultchain'
# Work file name
WRKFILE=${WRKFILE:-'.wrkfile'}
#
# Check for Programs
# Use full paths for the filenames
if [ -x /usr/local/sbin/iptables ]; then
IPTABLES="/usr/local/sbin/iptables"
else
IPTABLES="/sbin/iptables"
fi
if [ ! -x $IPTABLES ]
then
echo "$IPTABLES is not executable"
exit 1
fi
if [ -x /usr/local/sbin/ip6tables ]; then
IP6TABLES="/usr/local/sbin/ip6tables"
else
IP6TABLES="/sbin/ip6tables"
fi
if [ ! -x $IP6TABLES ]
then
echo "$IP6TABLES is not executable"
exit 1
fi
if [ -x /usr/local/sbin/iptables-restore ]; then
IPTABLES_BATCH="/usr/local/sbin/iptables-restore"
else
IPTABLES_BATCH="/sbin/iptables-restore"
fi
if [ ! -x $IPTABLES_BATCH ]
then
echo "$IPTABLES_BATCH is not executable"
exit 1
fi
if [ -x /usr/local/sbin/ip6tables-restore ]; then
IP6TABLES_BATCH="/usr/local/sbin/ip6tables-restore"
else
IP6TABLES_BATCH="/sbin/ip6tables-restore"
fi
if [ ! -x $IP6TABLES_BATCH ]
then
echo "$IP6TABLES_BATCH is not executable"
exit 1
fi
#if [ $(( $VERBOSEFLG & $VRBFLG_ACTION )) -eq 1 ]
#then
# IPTABLES_BATCH='>> /tmp/makefirewall.output.debug 2>&1'
# IP6TABLES_BATCH='>> /tmp/makefirewall.output.debug 2>&1'
#fi
#
# Usage Message
usage (){
echo $0
echo "\tcleantables\tClean the iptables tables"
echo "\tshowtables\tShow the iptables tables"
echo
echo "\tsetsecurity\tInsert all the rules (DEFAULT)"
echo
echo "\tprocessdirectory\tProcess the current directory"
echo "\tprocess6directory\tProcess the current directory for ipv6"
echo
echo "VARIABLES = name of variables file (.variables)"
echo "WRKFILE = name of workfile user (.wrkfile)"
echo "DEFAULT_POLICY = default policy for rules (ACCEPT)"
echo "DBDIR = directory name where all the rules are. (./DB)"
echo "DB6DIR = directory name where all the rules are. (./DB6)"
echo "BASEDIR = directory name program change path to.. (/etc/firewall)"
echo "BASE2DIR = second level into the DB, allows for profiles.. ('')"
echo
}
#
# Clean iptables
CleanTables(){
{ # pipe into iptables-restore
# Flush and set default Policies First
for MAINDIR in $TABLE_NAMES; do
echo "*$MAINDIR"
echo "-F"
echo "-X"
SEC_TABLE="TABLE_$MAINDIR"
eval "set -- \$$SEC_TABLE"
for SECDIR do
echo ":$SECDIR $DEFAULT_POLICY [0:0]"
done
echo "COMMIT"
done
} | $IPTABLES_BATCH
{ # pipe into iptables-restore
# Flush and set default Policies First
for MAINDIR in $TABLE6_NAMES; do
echo "*$MAINDIR"
echo "-F"
echo "-X"
SEC_TABLE="TABLE6_$MAINDIR"
eval "set -- \$$SEC_TABLE"
for SECDIR do
echo ":$SECDIR $DEFAULT_POLICY [0:0]"
done
echo "COMMIT"
done
} | $IP6TABLES_BATCH
}
# Show tables
ShowTables(){
for MAINDIR in $TABLE_NAMES; do
pstr "\n=====\nProcessing - table $MAINDIR\n=====\n"
$IPTABLES -t $MAINDIR -nvL
done
# IPv6
for MAINDIR in $TABLE6_NAMES; do
pstr "\n=====\nProcessing - table6 $MAINDIR\n=====\n"
$IP6TABLES -t $MAINDIR -nvL
done
}
#
# Process files in directory
ProcessFiles(){
# So we can use defined variables we use EVAL
eval "
cat <<- EOF
$(sed "/[[:blank:]]*#/d; /^[[:blank:]]*$/d; s/^\(.*\)#.*$/\\1/; s/^/-A $CHAIN /" \
$(find ii* ! -name '*.dpkg-old' ! -name '*.dpkg-dist' 2>/dev/null | sort ) \
$(find [0-9]* ! -name '*.dpkg-old' ! -name '*.dpkg-dist' 2>/dev/null | sort ) \
$(find aa* ! -name '*.dpkg-old' ! -name '*.dpkg-dist' 2>/dev/null | sort) \
< /dev/null )
EOF
"
}
# Process BLOCK files
ProcessBlockFiles(){
if [ -f $BLOCKED ]; then
eval "
cat <<- EOF
$(sed "/[[:blank:]]*#/d; /^[[:blank:]]*\$/d; s/^/-I $CHAIN /g; s/\$/ -j DROP/" $BLOCKED )
EOF
"
# if we have TARPIT use it :)
grep -q TARPIT /proc/net/ip*_tables_targets > /dev/null 2>&1
if [ $? -eq 0 ]; then
eval "
cat <<- EOF
$(sed "/[[:blank:]]*#/d; /^[[:blank:]]*\$/d; s/^/-I $CHAIN /g; s/\$/ -p tcp -j TARPIT/" $BLOCKED )
EOF
"
fi
fi
if [ -f $NOTBLOCKED ]; then
eval "
cat <<- EOF
$(sed '/[[:blank:]*#/d; /^[[:blank:]]*$/d; s/^/-I $CHAIN /g; s/$/ -j RETURN/' $NOTBLOCKED )
EOF
"
fi
}
#
# Process a ipv4 directory
ProcessDirectory(){
set +e
pstr "Working on $MAINDIR $CHAIN"
{
echo "*$MAINDIR"
echo "-F $CHAIN"
ProcessFiles
[ "$CHAIN" = "BLOCKED" ] && ProcessBlockFiles
echo "COMMIT"
} | tee -a "$IPTNEW" > "$WRKFILE"
if [ $? -ne 0 ]
then
pstr "Current Directory $(pwd)"
exit 1
fi
set -e
}
#
# Process a ipv6 Directory
Process6Directory(){
set +e
pstr "Working on $MAINDIR $CHAIN"
{
echo "*$MAINDIR"
echo "-F $CHAIN"
ProcessFiles
[ "$CHAIN" = "BLOCKED" ] && ProcessBlockFiles
echo "COMMIT"
} | tee -a "$IPTNEW6" > "$WRKFILE"
if [ $? -ne 0 ]
then
pstr "Current Directory $(pwd)"
exit 1
fi
set -e
}
#
# Process the files
SetSecurity(){
# Change into DBDIR
if [ -d "$BASEDIR/$DBDIR" ]; then
cd "$BASEDIR/$DBDIR"
else
pstr "\nNo Database Directory ($DBDIR)"
exit 0
fi
(
[ -f ./$VARIABLES ] && . ./$VARIABLES
for MAINDIR in $TABLE_NAMES; do
if [ ! -d $MAINDIR ]; then
pstr "\nNo Default Directory ($MAINDIR)"
exit 1
fi
# Enter table directory
cd $MAINDIR
# Find all the directories that we are going to process
SDIRS="$(find -maxdepth 1 -type d ! -name 'CVS' ! -name '.' -printf '%f ' )"
# Process the DEFAULT tables and set their default policy
{
echo "*$MAINDIR"
echo "-F"
echo "-X"
for CHAIN in $SDIRS; do
if [ -f $CHAIN/$POLICY_FILE ]
then
POLICY=$(cat $CHAIN/$POLICY_FILE)
echo ":$CHAIN $POLICY"
else
echo ":$CHAIN -"
fi
done
echo "COMMIT"
} | tee -a "$IPTNEW" > "$WRKFILE"
# have to process the Chains first and then the rules
for CHAIN in $SDIRS; do
# Enter chain Directory
cd $CHAIN
ProcessDirectory
# Back out chain directory
cd ..
done
# Go back a directory from a table directory
cd ..
done
$IPTABLES_BATCH -n < "$IPTNEW"
)
if [ $? -ne 0 ]
then
exit 1
fi
# Change into DBDIR
if [ -d "$BASEDIR/$DB6DIR" ]; then
cd "$BASEDIR/$DB6DIR"
else
pstr "\nNo Database 6 Directory ($DB6DIR)"
exit 0
fi
(
[ -f ./$VARIABLES ] && . ./$VARIABLES
for MAINDIR in $TABLE6_NAMES; do
if [ ! -d $MAINDIR ]; then
pstr "\nNo Default Directory ($MAINDIR)"
exit 1
fi
# Enter table directory
cd $MAINDIR
# Find all the directories that we are going to process
SDIRS="$(find -maxdepth 1 -type d ! -name 'CVS' ! -name '.' -printf '%f ' )"
# Process the DEFAULT tables and set their default policy
{
echo "*$MAINDIR"
echo "-F"
echo "-X"
for CHAIN in $SDIRS; do
if [ -f $CHAIN/$POLICY_FILE ]
then
POLICY=$(cat $CHAIN/$POLICY_FILE)
echo ":$CHAIN $POLICY"
else
echo ":$CHAIN -"
fi
done
echo "COMMIT"
} | tee -a "$IPTNEW6" > "$WRKFILE"
# have to process the Chains first and then the rules for the
for CHAIN in $SDIRS; do
# Enter chain Directory
cd $CHAIN
Process6Directory
# Back out chain directory
cd ..
done
# Go back a directory from table
cd ..
done
$IP6TABLES_BATCH -n < "$IPTNEW6"
)
if [ $? -ne 0 ]
then
exit 1
fi
}
#
# Start of the main script
set +e
# Save current state
IPTSAV="$(tempfile)"
IPTSAV6="$(tempfile)"
iptables-save > $IPTSAV 2> /dev/null
ip6tables-save > $IPTSAV6 2> /dev/null
# new workfiles
IPTNEW="$(tempfile)"
IPTNEW6="$(tempfile)"
# on error exit
set -e
trap "$IPTABLES_BATCH -c < $IPTSAV ; $IP6TABLES_BATCH -c < $IPTSAV6; rm \"$IPTSAV\" \"$IPTSAV6\" \"$IPTNEW\" \"$IPTNEW6\" " EXIT
#
# change to lower case
ACTION=$( echo $1 | tr A-Z a-z)
# Default action
ACTION=${ACTION:-"setsecurity"}
case $ACTION in
'cleantables')
CleanTables
;;
'showtables')
ShowTables
;;
'setsecurity')
SetSecurity
;;
'processdirectory')
CHAIN="$(echo $PWD | sed -n 's/.*\/\([^/]*\)/\1/p')"
MAINDIR="$(echo $PWD| sed -n 's/.*\/\([^/]*\)\/.*/\1/p')"
$IPTABLES -t $MAINDIR -F $CHAIN
echo "Chain [$CHAIN]"
echo "Maindir [$MAINDIR]"
echo "Pwd [$oldPwd]"
echo
(
[ -f ../../$VARIABLES ] && . ../../$VARIABLES
ProcessDirectory
$IPTABLES_BATCH -n < $IPTNEW
)
if [ $? -ne 0 ]
then
exit 1
fi
;;
'process6directory')
CHAIN="$(echo $PWD | sed -n 's/.*\/\([^/]*\)/\1/p')"
MAINDIR="$(echo $PWD| sed -n 's/.*\/\([^/]*\)\/.*/\1/p')"
$IP6TABLES -t $MAINDIR -F $CHAIN
echo "Chain [$CHAIN]"
echo "Maindir [$MAINDIR]"
echo "Pwd [$oldPwd]"
echo
(
[ -f ../../$VARIABLES ] && . ../../$VARIABLES
Process6Directory
$IP6TABLES_BATCH -n < $IPTNEW6
)
if [ $? -ne 0 ]
then
exit 1
fi
;;
'-h' | '--help')
usage
;;
*)
usage
;;
esac
#
# Everything okay do not retore
trap "-" EXIT
rm "$IPTSAV" "$IPTSAV6" "$IPTNEW" "$IPTNEW6"
# Exit
exit 0
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-08-27 1:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-27 1:30 Looking for some feedback on iptables manager script Alex Samad
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.