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 |