#!/bin/bash # Restore firewall state at boot, and store it at shutdown. # Version: 0.1.1 ### BEGIN INIT INFO # Provides: firewall # Required-Start: $network # Required-Stop: $network # Default-Start: 1 2 3 4 5 # Default-Stop: 0 6 # Short-Description: Firewalls' state save/restore/flush # Description: Store the firewalls' state at shutdown, and restores it at boot. # Aalso set the firewalls to a default state, and flush all rules. ### END INIT INFO SYSTEM_DIR="/etc/firewall" LOCAL_DIR="/root/.local/etc/firewall" DEFAULT_V4="default_v4.rules" DEFAULT_V6="default_v6.rules" STATE_V4="state_v4.rules" STATE_V6="state_v6.rules" # Confirm the iptables utilities are available. [[ ! -x "/usr/sbin/iptables" ]] || [[ ! -x "/usr/sbin/ip6tables" ]] || [[ ! -x "/usr/sbin/iptables-save" ]] || [[ ! -x "/usr/sbin/iptables-restore" ]] || [[ ! -x "/usr/sbin/ip6tables-save" ]] || [[ ! -x "/usr/sbin/ip6tables-restore" ]] && { printf "%s: %s\\n" "${0##*/}" "iptables package not installed" >&2 exit 1 } states_restore() { local ERR=0 # Restore the saved (or default) v4 firewall state. iptables-restore "$RULES_DIR/$STATE_V4" 2>/dev/null || { printf "%s: %s" "${0##*/}" "failed to restore saved" >&2 if iptables-restore "$$RULES_DIR/DEFAULT_V4" 2>/dev/null; then printf "%s" ", only default" >&2 else printf " %s" "and default" >&2 ERR=1 fi printf " %s\\n" "v4 firewall state" >&2 } # Restore the saved (or default) v6 firewall state. ip6tables-restore "$RULES_DIR/$STATE_V6" 2>/dev/null || { printf "%s: %s" "${0##*/}" "failed to restore saved" >&2 if ip6tables-restore "$RULES_DIR/$DEFAULT_V6" 2>/dev/null; then printf "%s" ", only default" >&2 else printf " %s" "and default" >&2 ERR=1 fi printf " %s\\n" "v6 firewall state" >&2 } return "$ERR" } states_save() { local ERR=0 # Store the state of the v4 firewall. iptables-save >"$RULES_DIR/$STATE_V4" 2>/dev/null || { printf "%s: %s\\n" "${0##*/}" "failed to save v4 firewall state" >&2 ERR=1 } # Store the state of the v6 firewall. ip6tables-save >"$RULES_DIR/$STATE_V6" 2>/dev/null || { printf "%s: %s\\n" "${0##*/}" "failed to save v6 firewall state" >&2 ERR=1 } return "$ERR" } defaults_restore() { local ERR=0 # Restore the default v4 firewall state. iptables-restore "$RULES_DIR/$DEFAULT_V4" 2>/dev/null || { printf "%s: %s\\n" "${0##*/}" "failed to restore default v4 firewall state" >&2 ERR=1 } # Restore the default v6 firewall state. ip6tables-restore "$RULES_DIR/$DEFAULT_V6" 2>/dev/null || { printf "%s: %s\\n" "${0##*/}" "failed to restore default v6 firewall state" >&2 ERR=1 } return "$ERR" } flush() { # Set the default policies to ACCEPT. iptables -P INPUT ACCEPT ip6tables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT ip6tables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT ip6tables -P FORWARD ACCEPT # Flush all the rules in the tables. iptables -F INPUT ip6tables -F INPUT iptables -F OUTPUT ip6tables -F OUTPUT iptables -F FORWARD ip6tables -F FORWARD # Delete all user defined tables. iptables -X ip6tables -X # Reset packet counters to zero. iptables -Z ip6tables -Z return 0 # All the above commands should never fail. } # Locate the rules directory. # We need to support the LOCAL_DIR because on the SANs you can't put config files in /etc and have them persist over a reboot or upgrade. if [[ -d "$LOCAL_DIR" ]]; then RULES_DIR="$LOCAL_DIR" elif [[ -d "$SYSTEM_DIR" ]]; then RULES_DIR="$SYSTEM_DIR" else printf "%s: %s\\n" "${0##*/}" "no rules directory found" exit 1 fi case "$1" in start|restart|reload|force-reload) states_restore exit "$?" ;; stop) states_save exit "$?" ;; defaults) defaults_restore || { printf "%s: %s\\n" "${0##*/}" "failed to restore default firewall state" >&2 exit 1 } exit "$?" ;; flush) flush # Should never fail. ;; *) printf "%s %s\\n" "${0##*/}" "" exit 2 ;; esac exit 0