Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- # Written by Simon Richter <sjr@debian.org>
- # Modified by Jonathan Wiltshire <jmw@debian.org>
- # with help from Christoph Anton Mitterer
- # Modified by Konstantin Demin <rockdrilla@gmail.com>
- # with God willing
- ### BEGIN INIT INFO
- # Provides: iptables-persistent
- # Required-Start: mountkernfs $local_fs
- # Required-Stop: $local_fs
- # Default-Start: 2 3 4 5
- # Default-Stop: 0 1 6
- # X-Start-Before: $network
- # X-Stop-After: $network
- # Short-Description: Set up iptables rules
- # Description: Loads/saves current iptables rules from/to /etc/iptables
- # to provide a persistent rule set during boot time
- ### END INIT INFO
- NAME=iptables-persistent
- RULES=/etc/iptables/rules
- RULES_set=${RULES}.ipset
- RULES_v4=${RULES}.ipv4
- RULES_v6=${RULES}.ipv6
- export PATH=/sbin:/bin
- . /lib/lsb/init-functions
- # partial /bin/which realization
- # only checks if binary exists
- binary_exist() {
- IFS_BAK=${IFS} IFS=':' notfound=1
- # if PATH ends with ':' then search in current directory too (IFS hack)
- case "${PATH}" in
- *[!:]:) PATH="${PATH}:" ;;
- esac
- case "$1" in
- */*)
- binary_exist_h "$1" && notfound=0
- ;;
- *)
- for location in ${PATH}; do
- test -z "${location}" && location=.
- binary_exist_h "${location}/$1" && notfound=0 && break
- done
- ;;
- esac
- IFS=${IFS_BAK}
- return ${notfound}
- }
- binary_exist_h() { test -f "$1" && test -x "$1"; }
- load_module() {
- module=
- case "$1" in
- ipset) module=ip_set ;;
- ipv4) module=iptable_filter ;;
- ipv6) module=ip6table_filter ;;
- *) return 2 ;;
- esac
- modprobe -q ${module}
- return 0
- }
- # keep in sync with test_avail()
- init_avail() {
- for subsys in ipset ipv4 ipv6; do
- case "${subsys}" in
- ipset)
- dirs='/sys/module/ip_set '
- files=
- binaries='ipset '
- ;;
- ipv4)
- dirs=
- files='/proc/net/ip_tables_names '
- binaries='iptables iptables-restore iptables-save '
- ;;
- ipv6)
- dirs=
- files='/proc/net/ip6_tables_names '
- binaries='ip6tables ip6tables-restore ip6tables-save '
- ;;
- *) continue ;; # this may not happen at all.
- esac
- load_module ${subsys}
- for flavour in K U; do
- err=0
- case "${flavour}" in
- K) for i in ${dirs}; do test -d $i || err=1; done
- for i in ${files}; do test -e $i || err=1; done
- ;;
- U) for i in ${binaries}; do binary_exist $i || err=1; done
- ;;
- *) continue ;; # this may not happen at all.
- esac
- eval "avail_${subsys}_${flavour}() { return ${err};}"
- done
- done
- return 0
- }
- test_avail() {
- subsys=$1 flavour=
- case "$2" in
- kernel) flavour=K ;; # kernel-space
- *) flavour=U ;; # user-space
- esac
- case "${subsys}" in
- ipset|ipv4|ipv6) ;;
- *) return 2 ;;
- esac
- eval "avail_${subsys}_${flavour}"
- }
- m_ok='[ok]'
- m_err='{ERROR}'
- m_skip='[skip]'
- m_skip_kernel='[skip: no kernel modules]'
- m_skip_user='[skip: no userspace bin]'
- m_skip_rules='[skip: no rules]'
- load_rules() {
- log_begin_msg "${NAME} loading rules:"
- subsystems='ipset ipv4 ipv6'
- test $# -ne 0 && subsystems=$@
- c_total=0 c_success=0
- for i in ${subsystems}; do
- c_total=$((c_total+1))
- title= cmd= file=
- case "$i" in
- ipset) title=IPset cmd=load_rules_ipset file=${RULES_set} ;;
- ipv4) title=IPv4 cmd=load_rules_ipv4 file=${RULES_v4} ;;
- ipv6) title=IPv6 cmd=load_rules_ipv6 file=${RULES_v6} ;;
- *)
- log_progress_msg " $i[unrecognized]"
- continue
- ;;
- esac
- log_progress_msg "${title}"
- if ! test_avail $i kernel; then
- log_progress_msg "${m_skip_kernel}"
- continue
- fi
- if ! test_avail $i user; then
- log_progress_msg "${m_skip_user}"
- continue
- fi
- if ! test -f ${file}; then
- log_progress_msg "${m_skip_rules}"
- continue
- fi
- ${cmd} < ${file}
- if test $? -ne 0; then
- log_progress_msg "${m_err}"
- else
- # log_progress_msg "${m_ok}"
- c_success=$((c_success+1))
- fi
- done; unset subsystems i title cmd file
- rc=0 # success
- test ${c_success} -lt ${c_total} && rc=255 # warning
- test ${c_success} -eq 0 && rc=1 # failure
- unset c_total c_success
- log_end_msg ${rc}; unset rc
- return 0
- }
- load_rules_ipset() { ipset restore; }
- load_rules_ipv4() { iptables-restore; }
- load_rules_ipv6() { ip6tables-restore; }
- save_rules() {
- log_begin_msg "${NAME} saving rules:"
- subsystems='ipset ipv4 ipv6'
- test $# -ne 0 && subsystems=$@
- c_total=0 c_success=0
- for i in ${subsystems}; do
- c_total=$((c_total+1))
- title= cmd= file=
- case "$i" in
- ipset) title=IPset cmd=save_rules_ipset file=${RULES_set} ;;
- ipv4) title=IPv4 cmd=save_rules_ipv4 file=${RULES_v4} ;;
- ipv6) title=IPv6 cmd=save_rules_ipv6 file=${RULES_v6} ;;
- *)
- log_progress_msg " $i[unrecognized]"
- continue
- ;;
- esac
- log_progress_msg "${title}"
- if ! test_avail $i kernel; then
- log_progress_msg "${m_skip_kernel}"
- continue
- fi
- if ! test_avail $i user; then
- log_progress_msg "${m_skip_user}"
- continue
- fi
- if ! test -f ${file}; then
- log_progress_msg "${m_skip_rules}"
- continue
- fi
- ${cmd} > ${file}
- if test $? -ne 0; then
- log_progress_msg "${m_err}"
- else
- # log_progress_msg "${m_ok}"
- c_success=$((c_success+1))
- fi
- done; unset subsystems i title cmd file
- rc=0 # success
- test ${c_success} -lt ${c_total} && rc=255 # warning
- test ${c_success} -eq 0 && rc=1 # failure
- unset c_total c_success
- log_end_msg ${rc}; unset rc
- return 0
- }
- save_rules_ipset() { ipset save; }
- save_rules_ipv4() { iptables-save; }
- save_rules_ipv6() { ip6tables-save; }
- flush_rules() {
- log_begin_msg "${NAME} flushing rules:"
- # reversed order IS correct
- subsystems='ipv6 ipv4 ipset'
- test $# -ne 0 && subsystems=$@
- c_total=0 c_success=0
- for i in ${subsystems}; do
- c_total=$((c_total+1))
- case "$i" in
- ipset) title=IPSet cmd=flush_rules_ipset ;;
- ipv4) title=IPv4 cmd=flush_rules_ipv4 ;;
- ipv6) title=IPv6 cmd=flush_rules_ipv6 ;;
- *)
- log_progress_msg " $i[unrecognized]"
- continue
- ;;
- esac
- log_progress_msg "${title}"
- if ! test_avail $i kernel; then
- log_progress_msg "${m_skip_kernel}"
- continue
- fi
- if ! test_avail $i user; then
- log_progress_msg "${m_skip_user}"
- continue
- fi
- ${cmd}
- if test $? -ne 0; then
- log_progress_msg "${m_err}"
- else
- # log_progress_msg "${m_ok}"
- c_success=$((c_success+1))
- fi
- done; unset subsystems i title cmd
- rc=0 # success
- test ${c_success} -lt ${c_total} && rc=255 # warning
- test ${c_success} -eq 0 && rc=1 # failure
- unset c_total c_success
- log_end_msg ${rc}; unset rc
- return 0
- }
- flush_rules_ipset() {
- ipset flush
- ipset destroy
- }
- flush_rules_ipv4() {
- for chain in INPUT FORWARD OUTPUT; do
- iptables -P ${chain} ACCEPT
- done; unset chain
- for table in $(cat /proc/net/ip_tables_names); do
- iptables -t ${table} -F
- iptables -t ${table} -X
- iptables -t ${table} -Z
- done; unset table
- }
- flush_rules_ipv6() {
- for chain in INPUT FORWARD OUTPUT; do
- ip6tables -P ${chain} ACCEPT
- done; unset chain
- for table in $(cat /proc/net/ip6_tables_names); do
- ip6tables -t ${table} -F
- ip6tables -t ${table} -X
- ip6tables -t ${table} -Z
- done; unset table
- }
- work_init() {
- init_avail
- # stderr redirection to /tmp/tmp.XXXXXXXXXX
- U=$(umask); umask 0077 # more restrictive umask
- T=$(mktemp)
- umask $U; unset U # restore origin umask
- exec 2>>$T
- }
- work_done() {
- exec 2>/dev/null
- if test -s $T; then
- N=10 i=0 S=
- log_begin_msg "${NAME} log contains some info; here is first $N (or less) lines of them:"
- log_end_msg 255
- exec 3< $T
- while test $i -lt $N; do
- read -r S <&3 || break
- printf '%s\n' "$S"
- i=$((i+1))
- done; unset i N
- exec 3<&-
- fi
- rm -f $T; unset T
- }
- R=0
- act=$1; test $# -gt 0 && shift
- case "${act}" in
- start|reload)
- work_init
- load_rules "$@"
- work_done
- ;;
- save)
- work_init
- save_rules "$@"
- work_done
- ;;
- flush)
- work_init
- flush_rules "$@"
- work_done
- ;;
- restart|force-reload)
- work_init
- flush_rules "$@"
- load_rules "$@"
- work_done
- ;;
- stop)
- # Why? because if stop is used, the firewall gets flushed for a variable
- # amount of time during package upgrades, leaving the machine vulnerable
- # It's also not always desirable to flush during purge
- echo 'Automatic flushing disabled, use "flush" instead of "stop"' >&2
- ;;
- *)
- echo "Usage: $0 {start|restart|reload|force-reload|save|flush} [ipset|ipv4|ipv6]" >&2
- R=1
- ;;
- esac
- exit $R
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement