View difference between Paste ID: VGy4gmRB and gjLUDVEQ
SHOW: | | - or go back to the newest paste.
1
#!/bin/sh
2-
#   Written by Simon Richter <sjr@debian.org>
2+
#    Written by Simon Richter <sjr@debian.org>
3-
#   Modified by Jonathan Wiltshire <jmw@debian.org>
3+
#    Modified by Jonathan Wiltshire <jmw@debian.org>
4-
#       with help from Christoph Anton Mitterer
4+
#        with help from Christoph Anton Mitterer
5-
#   Modified by Konstantin Demin <rockdrilla@gmail.com>
5+
#    Modified by Konstantin Demin <rockdrilla@gmail.com>
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