1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
#!/bin/bash
# wfchkintegrity v0.2.2: various ruleset integrity checks based on comparison
# with previous state.
# This script is part of the WallFire project. See http://www.wallfire.org/.
# (C) Herve Eychenne, 2003
# When called with no argument, a diff between the current
# configuration stored on disk and the current configuration on kernel
# memory is printed on stdout, unless -d option (nodiff) is specified.
# If no difference is found, no files are modified on disk. Otherwise,
# the old configuration file is renamed for backup, and the current
# kernel configuration is stored on disk.
# If firewalling rules do not change again in the meanwhile, next invocations
# of the command will show no change (changes are reported only one time).
# Exit code is 0 if no changes occured, != 0 otherwise.
# When called with "diff" argument, only a diff between the current
# configuration stored on disk and the current configuration in kernel
# memory is printed on stdout, unless -d option (nodiff) is specified.
# No files are modified on disk.
# Exit code is 0 if no changes occured, != 0 otherwise.
# When called with "difflast" argument, only a diff between the previous
# configuration stored on disk and the current configuration stored on disk
# is printed on stdout.
# No files are modified on disk.
# Exit code is 0 if there are no changes between the two, != 0 otherwise.
# When called with "clean" argument, old configurations stored on disk are
# removed (more than 60 days old)
# When called with "reset" argument, current configuration in kernel memory
# is stored as the current configuration stored on disk (erasing the previous
# one).
# In any case, -e option means no warning or error message printed on stderr
# (return code is still set adequately, though).
# Option -q implies -d and -e (quiet mode: no output at all).
# Exit code can be 2 if an unexpected error occurs.
# TODO:
# - add an option (-D ?) to make it a daemon
# - add more checks
RULEFILE=/var/lib/wallfire/configdump
dumpprocentry() {
echo -n "${1}: "; cat $1
}
dumpall() {
iptables-save | /bin/sed -e '/^#/d' -e 's/^\(:.*\) \[[0-9]*:[0-9]*\]$/\1/'
dumpprocentry /proc/sys/net/ipv4/ip_forward
# Here we could add much more things (according to a config file) @@6
}
log() {
[ "$NOERROR" ] || echo "$0: $@" >&2
}
createrulefile() {
[ -d "$DIR" ] || /bin/mkdir -p "$DIR"
if [ $? != 0 ]; then
log "Error: ${DIR}: could not create directory"
exit 2
fi
dumpall >$1
if [ $? != 0 ]; then
log "Error: ${1}: could not create file"
exit 2
fi
}
[ "$DIFF" ] || DIFF=/usr/bin/diff
umask 177
NODIFF=
NOERROR=
while : ; do
case "$1" in
-d)
NODIFF=1 ;;
-e)
NOERROR=1 ;;
-q)
NODIFF=1
NOERROR=1
;;
*)
break ;;
esac
shift
done
DIR="$(/usr/bin/dirname "$RULEFILE")"
if [ $# != 0 ]; then
case "$1" in
diff)
dumpall | eval $DIFF "$RULEFILE" - ${NODIFF:+>/dev/null}
exit
;;
difflast)
$DIFF "${RULEFILE}_changed.last" "$RULEFILE"
exit
;;
clean)
find $DIR -name "configdump_changed_*" -ctime +60 | xargs rm -f
exit
;;
reset)
[ -e "$RULEFILE" ] && rm "$RULEFILE"
createrulefile "$RULEFILE"
exit 0
;;
*)
log "Error: unknown argument $*"
exit 2
esac
fi
# From here, no command line argument was specified.
if [ ! -r "$RULEFILE" ]; then
log "Warning: ${RULEFILE}: file is not readable or does not exist: create it"
createrulefile "$RULEFILE"
exit 1 # there is a difference, as we just created the state file
fi
createrulefile "${RULEFILE}.new"
if eval $DIFF "$RULEFILE" "${RULEFILE}.new" ${NODIFF:+>/dev/null} ; then
/bin/rm "${RULEFILE}.new"
exit 0 # no difference, it's ok
fi
# There are differences.
# Rename file to keep an archive.
CHANGED="${RULEFILE}_changed_$(date '+%y%m%d-%X')"
log "Warning: ruleset changed: moving old file $RULEFILE to $CHANGED"
/bin/mv "$RULEFILE" "$CHANGED"
# Create a symbolic link on the last configuration.
rm -f "${RULEFILE}_changed.last"
ln -s "$CHANGED" "${RULEFILE}_changed.last"
# Store the new current configuration.
/bin/mv "${RULEFILE}.new" "$RULEFILE"
exit 1
|