SHOW:
|
|
- or go back to the newest paste.
| 1 | #!/bin/sh | |
| 2 | - | # Written by Simon Richter <[email protected]> |
| 2 | + | # Written by Simon Richter <[email protected]> |
| 3 | - | # Modified by Jonathan Wiltshire <[email protected]> |
| 3 | + | # Modified by Jonathan Wiltshire <[email protected]> |
| 4 | - | # with help from Christoph Anton Mitterer |
| 4 | + | # with help from Christoph Anton Mitterer |
| 5 | - | # Modified by Konstantin Demin <[email protected]> |
| 5 | + | # Modified by Konstantin Demin <[email protected]> |
| 6 | - | # with God willing |
| 6 | + | # with God willing |
| 7 | ||
| 8 | ### BEGIN INIT INFO | |
| 9 | # Provides: iptables-persistent | |
| 10 | # Required-Start: mountkernfs $local_fs | |
| 11 | # Required-Stop: $local_fs | |
| 12 | # Default-Start: 2 3 4 5 | |
| 13 | # Default-Stop: 0 1 6 | |
| 14 | # X-Start-Before: $network | |
| 15 | # X-Stop-After: $network | |
| 16 | # Short-Description: Set up iptables rules | |
| 17 | # Description: Loads/saves current iptables rules from/to /etc/iptables | |
| 18 | # to provide a persistent rule set during boot time | |
| 19 | ### END INIT INFO | |
| 20 | ||
| 21 | export PATH=/sbin:/bin | |
| 22 | ||
| 23 | . /lib/lsb/init-functions | |
| 24 | ||
| 25 | RULES=/etc/iptables/rules | |
| 26 | RULES_set=${RULES}.ipset
| |
| 27 | RULES_v4=${RULES}.ipv4
| |
| 28 | RULES_v6=${RULES}.ipv6
| |
| 29 | ||
| 30 | ||
| 31 | binary_exist() {
| |
| 32 | - | # todo: partial re-implement /bin/which |
| 32 | + | IFS_BAK=${IFS} IFS=':' notfound=1
|
| 33 | ||
| 34 | # if PATH ends with ':' then search in current directory too (IFS hack) | |
| 35 | case "${PATH}" in
| |
| 36 | *[!:]:) PATH="${PATH}:" ;;
| |
| 37 | esac | |
| 38 | ||
| 39 | case "$1" in | |
| 40 | */*) | |
| 41 | binary_exist_h "$1" && notfound=0 | |
| 42 | ;; | |
| 43 | *) | |
| 44 | for location in ${PATH}; do
| |
| 45 | test -z "${location}" && location=.
| |
| 46 | binary_exist_h "${location}/$1" && notfound=0 && break
| |
| 47 | done | |
| 48 | ;; | |
| 49 | esac | |
| 50 | IFS=${IFS_BAK}
| |
| 51 | return ${notfound}
| |
| 52 | } | |
| 53 | binary_exist_h() { test -f "$1" && test -x "$1"; }
| |
| 54 | ||
| 55 | # keep in sync with test_avail() | |
| 56 | init_avail() {
| |
| 57 | for subsys in ipset ipv4 ipv6; do | |
| 58 | case "${subsys}" in
| |
| 59 | ipset) | |
| 60 | - | K) for i in ${dirs}; do test -d $i || err=1; done
|
| 60 | + | |
| 61 | files= | |
| 62 | binaries='ipset ' | |
| 63 | - | U) for i in ${binaries}; do binary_exist $i || err=1; done
|
| 63 | + | |
| 64 | ipv4) | |
| 65 | dirs= | |
| 66 | files='/proc/net/ip_tables_names ' | |
| 67 | binaries='iptables iptables-restore iptables-save ' | |
| 68 | ;; | |
| 69 | ipv6) | |
| 70 | dirs= | |
| 71 | files='/proc/net/ip6_tables_names ' | |
| 72 | binaries='ip6tables ip6tables-restore ip6tables-save ' | |
| 73 | ;; | |
| 74 | *) continue ;; # this may not happen at all. | |
| 75 | esac | |
| 76 | ||
| 77 | for flavour in K U; do | |
| 78 | err=0 | |
| 79 | case "${flavour}" in
| |
| 80 | K) for i in ${dirs}; do test -d $i || err=1; done
| |
| 81 | for i in ${files}; do test -e $i || err=1; done
| |
| 82 | ;; | |
| 83 | U) for i in ${binaries}; do binary_exist $i || err=1; done
| |
| 84 | ;; | |
| 85 | *) continue ;; # this may not happen at all. | |
| 86 | esac | |
| 87 | ||
| 88 | eval "avail_${subsys}_${flavour}() { return ${err};}"
| |
| 89 | done | |
| 90 | done | |
| 91 | ||
| 92 | return 0 | |
| 93 | } | |
| 94 | ||
| 95 | test_avail() {
| |
| 96 | subsys=$1 flavour= | |
| 97 | case "$2" in | |
| 98 | kernel) flavour=K ;; # kernel-space | |
| 99 | *) flavour=U ;; # user-space | |
| 100 | esac | |
| 101 | ||
| 102 | case "${subsys}" in
| |
| 103 | ipset) ;; | |
| 104 | ipv4) ;; | |
| 105 | ipv6) ;; | |
| 106 | *) return 2 ;; | |
| 107 | esac | |
| 108 | ||
| 109 | eval "avail_${subsys}_${flavour}"
| |
| 110 | } | |
| 111 | ||
| 112 | m_ok=' [ok]' | |
| 113 | m_skip=' [skip]' | |
| 114 | m_err=' {ERROR}'
| |
| 115 | ||
| 116 | ||
| 117 | load_rules() {
| |
| 118 | log_action_begin_msg "Loading iptables rules" | |
| 119 | ||
| 120 | subsystems='ipset ipv4 ipv6' | |
| 121 | test $# -ne 0 && subsystems=$@ | |
| 122 | ||
| 123 | for i in ${subsystems}; do
| |
| 124 | title= cmd= file= | |
| 125 | case "$i" in | |
| 126 | ipset) title=IPset cmd=load_rules_ipset file=${RULES_set} ;;
| |
| 127 | ipv4) title=IPv4 cmd=load_rules_ipv4 file=${RULES_v4} ;;
| |
| 128 | ipv6) title=IPv6 cmd=load_rules_ipv6 file=${RULES_v6} ;;
| |
| 129 | *) | |
| 130 | # todo: notify user if subsystem isn't recognized or supported | |
| 131 | continue | |
| 132 | ;; | |
| 133 | esac | |
| 134 | ||
| 135 | test_avail $i user || continue | |
| 136 | ||
| 137 | log_action_cont_msg " ${title}"
| |
| 138 | ||
| 139 | if test -f ${file}; then
| |
| 140 | ${cmd} < ${file} 2> /dev/null
| |
| 141 | ||
| 142 | if test $? -ne 0 | |
| 143 | then log_action_cont_msg "${m_err}"
| |
| 144 | # else log_action_cont_msg "${m_ok}"
| |
| 145 | fi | |
| 146 | else | |
| 147 | log_action_cont_msg "${m_skip}"
| |
| 148 | fi | |
| 149 | done | |
| 150 | ||
| 151 | log_action_end_msg 0 | |
| 152 | return 0 | |
| 153 | } | |
| 154 | load_rules_ipset() {
| |
| 155 | ipset restore | |
| 156 | } | |
| 157 | load_rules_ipv4() {
| |
| 158 | iptables-restore | |
| 159 | } | |
| 160 | load_rules_ipv6() {
| |
| 161 | ip6tables-restore | |
| 162 | } | |
| 163 | ||
| 164 | save_rules() {
| |
| 165 | log_action_begin_msg "Saving rules" | |
| 166 | ||
| 167 | subsystems='ipset ipv4 ipv6' | |
| 168 | test $# -ne 0 && subsystems=$@ | |
| 169 | ||
| 170 | for i in ${subsystems}; do
| |
| 171 | title= cmd= file= | |
| 172 | case "$i" in | |
| 173 | ipset) title=IPset cmd=save_rules_ipset file=${RULES_set} ;;
| |
| 174 | ipv4) title=IPv4 cmd=save_rules_ipv4 file=${RULES_v4} ;;
| |
| 175 | ipv6) title=IPv6 cmd=save_rules_ipv6 file=${RULES_v6} ;;
| |
| 176 | *) | |
| 177 | # todo: notify user if subsystem isn't recognized or supported | |
| 178 | continue | |
| 179 | ;; | |
| 180 | esac | |
| 181 | ||
| 182 | test_avail $i user || continue | |
| 183 | ||
| 184 | log_action_cont_msg " ${title}"
| |
| 185 | ||
| 186 | if test -f ${file}; then
| |
| 187 | ${cmd} > ${file} 2> /dev/null
| |
| 188 | ||
| 189 | if test $? -ne 0 | |
| 190 | then log_action_cont_msg "${m_err}"
| |
| 191 | # else log_action_cont_msg "${m_ok}"
| |
| 192 | fi | |
| 193 | else | |
| 194 | log_action_cont_msg "${m_skip}"
| |
| 195 | fi | |
| 196 | done | |
| 197 | ||
| 198 | log_action_end_msg 0 | |
| 199 | return 0 | |
| 200 | } | |
| 201 | save_rules_ipset() {
| |
| 202 | ipset save | |
| 203 | } | |
| 204 | save_rules_ipv4() {
| |
| 205 | iptables-save | |
| 206 | } | |
| 207 | save_rules_ipv6() {
| |
| 208 | ip6tables-save | |
| 209 | } | |
| 210 | ||
| 211 | flush_rules() {
| |
| 212 | log_action_begin_msg "Flushing rules" | |
| 213 | ||
| 214 | # reversed order IS correct | |
| 215 | subsystems='ipv6 ipv4 ipset' | |
| 216 | test $# -ne 0 && subsystems=$@ | |
| 217 | ||
| 218 | for i; do | |
| 219 | case "$i" in | |
| 220 | ipset) title=IPSet cmd=flush_rules_ipset ;; | |
| 221 | ipv4) title=IPv4 cmd=flush_rules_ipv4 ;; | |
| 222 | ipv6) title=IPv6 cmd=flush_rules_ipv6 ;; | |
| 223 | *) | |
| 224 | # todo: notify user if subsystem isn't recognized or supported | |
| 225 | continue | |
| 226 | ;; | |
| 227 | esac | |
| 228 | ||
| 229 | test_avail $i || continue | |
| 230 | ||
| 231 | log_action_cont_msg " ${title}"
| |
| 232 | ||
| 233 | if test_avail $i kernel; then | |
| 234 | ${cmd}
| |
| 235 | ||
| 236 | if test $? -ne 0 | |
| 237 | then log_action_cont_msg "${m_err}"
| |
| 238 | # else log_action_cont_msg "${m_ok}"
| |
| 239 | fi | |
| 240 | else | |
| 241 | log_action_cont_msg "${m_skip}"
| |
| 242 | fi | |
| 243 | done | |
| 244 | ||
| 245 | log_action_end_msg 0 | |
| 246 | return 0 | |
| 247 | } | |
| 248 | flush_rules_ipset() {
| |
| 249 | ipset flush | |
| 250 | ipset destroy | |
| 251 | } | |
| 252 | flush_rules_ipv4() {
| |
| 253 | for chain in INPUT FORWARD OUTPUT; do | |
| 254 | iptables -P ${chain} ACCEPT
| |
| 255 | done | |
| 256 | for table in $(cat /proc/net/ip_tables_names); do | |
| 257 | iptables -t ${table} -F
| |
| 258 | iptables -t ${table} -X
| |
| 259 | iptables -t ${table} -Z
| |
| 260 | done | |
| 261 | } | |
| 262 | flush_rules_ipv6() {
| |
| 263 | for chain in INPUT FORWARD OUTPUT; do | |
| 264 | ip6tables -P ${chain} ACCEPT
| |
| 265 | done | |
| 266 | for table in $(cat /proc/net/ip6_tables_names); do | |
| 267 | ip6tables -t ${table} -F
| |
| 268 | ip6tables -t ${table} -X
| |
| 269 | ip6tables -t ${table} -Z
| |
| 270 | done | |
| 271 | } | |
| 272 | ||
| 273 | ||
| 274 | act=$1; shift | |
| 275 | case "${act}" in
| |
| 276 | start|reload) | |
| 277 | init_avail | |
| 278 | load_rules "$@" | |
| 279 | ;; | |
| 280 | save) | |
| 281 | init_avail | |
| 282 | save_rules "$@" | |
| 283 | ;; | |
| 284 | flush) | |
| 285 | init_avail | |
| 286 | flush_rules "$@" | |
| 287 | ;; | |
| 288 | restart|force-reload) | |
| 289 | init_avail | |
| 290 | flush_rules "$@" | |
| 291 | load_rules "$@" | |
| 292 | ;; | |
| 293 | stop) | |
| 294 | # Why? because if stop is used, the firewall gets flushed for a variable | |
| 295 | # amount of time during package upgrades, leaving the machine vulnerable | |
| 296 | # It's also not always desirable to flush during purge | |
| 297 | echo 'Automatic flushing disabled, use "flush" instead of "stop"' >&2 | |
| 298 | ;; | |
| 299 | *) | |
| 300 | echo "Usage: $0 {start|restart|reload|force-reload|save|flush}" >&2
| |
| 301 | exit 1 | |
| 302 | ;; | |
| 303 | esac | |
| 304 | ||
| 305 | exit 0 |