blob: 035647998ef9cec48af43b583b05473c5a3b03a2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
|
# Copyright (C) 2009-2011 OpenWrt.org
# Copyright (C) 2008 John Crispin <blogic@openwrt.org>
FW_INITIALIZED=
FW_ZONES=
FW_ZONES4=
FW_ZONES6=
FW_CONNTRACK_ZONES=
FW_NOTRACK_DISABLED=
FW_DEFAULTS_APPLIED=
FW_ADD_CUSTOM_CHAINS=
FW_ACCEPT_REDIRECTS=
FW_ACCEPT_SRC_ROUTE=
FW_DEFAULT_INPUT_POLICY=REJECT
FW_DEFAULT_OUTPUT_POLICY=REJECT
FW_DEFAULT_FORWARD_POLICY=REJECT
FW_DISABLE_IPV4=0
FW_DISABLE_IPV6=0
fw_load_defaults() {
fw_config_get_section "$1" defaults { \
string input $FW_DEFAULT_INPUT_POLICY \
string output $FW_DEFAULT_OUTPUT_POLICY \
string forward $FW_DEFAULT_FORWARD_POLICY \
boolean drop_invalid 0 \
boolean syn_flood 0 \
boolean synflood_protect 0 \
string synflood_rate 25 \
string synflood_burst 50 \
boolean tcp_syncookies 1 \
boolean tcp_ecn 0 \
boolean tcp_westwood 0 \
boolean tcp_window_scaling 1 \
boolean accept_redirects 0 \
boolean accept_source_route 0 \
boolean custom_chains 1 \
boolean disable_ipv6 0 \
} || return
[ -n "$FW_DEFAULTS_APPLIED" ] && {
fw_log error "duplicate defaults section detected, skipping"
return 1
}
FW_DEFAULTS_APPLIED=1
FW_DEFAULT_INPUT_POLICY=$defaults_input
FW_DEFAULT_OUTPUT_POLICY=$defaults_output
FW_DEFAULT_FORWARD_POLICY=$defaults_forward
FW_ADD_CUSTOM_CHAINS=$defaults_custom_chains
FW_ACCEPT_REDIRECTS=$defaults_accept_redirects
FW_ACCEPT_SRC_ROUTE=$defaults_accept_source_route
FW_DISABLE_IPV6=$defaults_disable_ipv6
fw_callback pre defaults
# Seems like there are only one sysctl for both IP versions.
for s in syncookies ecn westwood window_scaling; do
eval "sysctl -e -w net.ipv4.tcp_${s}=\$defaults_tcp_${s}" >/dev/null
done
fw_sysctl_interface all
fw add i f INPUT ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED }
fw add i f OUTPUT ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED }
fw add i f FORWARD ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED }
[ $defaults_drop_invalid == 1 ] && {
fw add i f INPUT DROP { -m conntrack --ctstate INVALID }
fw add i f OUTPUT DROP { -m conntrack --ctstate INVALID }
fw add i f FORWARD DROP { -m conntrack --ctstate INVALID }
FW_NOTRACK_DISABLED=1
}
fw add i f INPUT ACCEPT { -i lo }
fw add i f OUTPUT ACCEPT { -o lo }
# Compatibility to old 'syn_flood' parameter
[ $defaults_syn_flood == 1 ] && \
defaults_synflood_protect=1
[ "${defaults_synflood_rate%/*}" == "$defaults_synflood_rate" ] && \
defaults_synflood_rate="$defaults_synflood_rate/second"
[ $defaults_synflood_protect == 1 ] && {
echo "Loading synflood protection"
fw_callback pre synflood
fw add i f syn_flood
fw add i f syn_flood RETURN { \
-p tcp --syn \
-m limit --limit "${defaults_synflood_rate}" --limit-burst "${defaults_synflood_burst}" \
}
fw add i f syn_flood DROP
fw add i f INPUT syn_flood { -p tcp --syn }
fw_callback post synflood
}
[ $defaults_custom_chains == 1 ] && {
echo "Adding custom chains"
fw add i f input_rule
fw add i f output_rule
fw add i f forwarding_rule
fw add i n prerouting_rule
fw add i n postrouting_rule
fw add i f INPUT input_rule
fw add i f OUTPUT output_rule
fw add i f FORWARD forwarding_rule
fw add i n PREROUTING prerouting_rule
fw add i n POSTROUTING postrouting_rule
}
fw add i f input
fw add i f output
fw add i f forward
fw add i f INPUT input
fw add i f OUTPUT output
fw add i f FORWARD forward
fw add i f reject
fw add i f reject REJECT { --reject-with tcp-reset -p tcp }
fw add i f reject REJECT { --reject-with port-unreach }
fw_set_filter_policy
fw_callback post defaults
}
fw_config_get_zone() {
[ "${zone_NAME}" != "$1" ] || return
fw_config_get_section "$1" zone { \
string name "$1" \
string network "" \
string input "$FW_DEFAULT_INPUT_POLICY" \
string output "$FW_DEFAULT_OUTPUT_POLICY" \
string forward "$FW_DEFAULT_FORWARD_POLICY" \
boolean masq 0 \
string masq_src "" \
string masq_dest "" \
boolean conntrack 0 \
boolean mtu_fix 0 \
boolean custom_chains "$FW_ADD_CUSTOM_CHAINS" \
boolean log 0 \
string log_limit 10 \
string family "" \
} || return
[ -n "$zone_name" ] || zone_name=$zone_NAME
[ -n "$zone_network" ] || zone_network=$zone_name
}
fw_load_zone() {
fw_config_get_zone "$1"
list_contains FW_ZONES $zone_name && {
fw_log error "zone ${zone_name}: duplicated zone, skipping"
return 0
}
append FW_ZONES $zone_name
fw_callback pre zone
[ $zone_conntrack = 1 -o $zone_masq = 1 ] && \
append FW_CONNTRACK_ZONES "$zone_name"
local mode
case "$zone_family" in
*4)
mode=4
append FW_ZONES4 $zone_name
uci_set_state firewall core ${zone_name}_ipv4 1
;;
*6)
mode=6
append FW_ZONES6 $zone_name
uci_set_state firewall core ${zone_name}_ipv6 1
;;
*)
mode=i
append FW_ZONES4 $zone_name
append FW_ZONES6 $zone_name
uci_set_state firewall core ${zone_name}_ipv4 1
uci_set_state firewall core ${zone_name}_ipv6 1
;;
esac
local chain=zone_${zone_name}
fw add $mode f ${chain}_ACCEPT
fw add $mode f ${chain}_DROP
fw add $mode f ${chain}_REJECT
# TODO: Rename to ${chain}_input
fw add $mode f ${chain}
fw add $mode f ${chain} ${chain}_${zone_input} $
fw add $mode f ${chain}_forward
fw add $mode f ${chain}_forward ${chain}_${zone_forward} $
# TODO: add ${chain}_output
fw add $mode f output ${chain}_${zone_output} $
# TODO: Rename to ${chain}_MASQUERADE
fw add $mode n ${chain}_nat
fw add $mode n ${chain}_prerouting
fw add $mode r ${chain}_notrack
[ $zone_mtu_fix == 1 ] && {
fw add $mode m ${chain}_MSSFIX
fw add $mode m FORWARD ${chain}_MSSFIX ^
uci_set_state firewall core ${zone_name}_tcpmss 1
}
[ $zone_custom_chains == 1 ] && {
[ $FW_ADD_CUSTOM_CHAINS == 1 ] || \
fw_die "zone ${zone_name}: custom_chains globally disabled"
fw add $mode f input_${zone_name}
fw add $mode f ${chain} input_${zone_name} ^
fw add $mode f forwarding_${zone_name}
fw add $mode f ${chain}_forward forwarding_${zone_name} ^
fw add $mode n prerouting_${zone_name}
fw add $mode n ${chain}_prerouting prerouting_${zone_name} ^
}
[ "$zone_log" == 1 ] && {
[ "${zone_log_limit%/*}" == "$zone_log_limit" ] && \
zone_log_limit="$zone_log_limit/minute"
local t
for t in REJECT DROP; do
fw add $mode f ${chain}_${t} LOG ^ \
{ -m limit --limit $zone_log_limit --log-prefix "$t($zone_name): " }
done
[ $zone_mtu_fix == 1 ] && \
fw add $mode m ${chain}_MSSFIX LOG ^ \
{ -m limit --limit $zone_log_limit --log-prefix "MSSFIX($zone_name): " }
}
# NB: if MASQUERADING for IPv6 becomes available we'll need a family check here
if [ "$zone_masq" == 1 ]; then
local msrc mdst
for msrc in ${zone_masq_src:-0.0.0.0/0}; do
case "$msrc" in
*.*) fw_get_negation msrc '-s' "$msrc" ;;
*) fw_get_subnet4 msrc '-s' "$msrc" || break ;;
esac
for mdst in ${zone_masq_dest:-0.0.0.0/0}; do
case "$mdst" in
*.*) fw_get_negation mdst '-d' "$mdst" ;;
*) fw_get_subnet4 mdst '-d' "$mdst" || break ;;
esac
fw add $mode n ${chain}_nat MASQUERADE $ { $msrc $mdst }
done
done
fi
fw_callback post zone
}
fw_load_notrack_zone() {
fw_config_get_zone "$1"
list_contains FW_CONNTRACK_ZONES "${zone_name}" && return
fw_callback pre notrack
fw add i r zone_${zone_name}_notrack NOTRACK $
fw_callback post notrack
}
fw_load_include() {
local name="$1"
local path
config_get path ${name} path
[ -e $path ] && (
config() {
fw_log error "You cannot use UCI in firewall includes!" >&2
exit 1
}
. $path
)
}
fw_clear() {
local policy=$1
fw_set_filter_policy $policy
local tab
for tab in f n r; do
fw del i $tab
done
}
fw_set_filter_policy() {
local policy=$1
local chn tgt
for chn in INPUT OUTPUT FORWARD; do
eval "tgt=\${policy:-\${FW_DEFAULT_${chn}_POLICY}}"
[ $tgt == "REJECT" ] && tgt=reject
[ $tgt == "ACCEPT" -o $tgt == "DROP" ] || {
fw add i f $chn $tgt $
tgt=DROP
}
fw policy i f $chn $tgt
done
}
fw_callback() {
local pp=$1
local hk=$2
local libs lib
eval "libs=\$FW_CB_${pp}_${hk}"
[ -n "$libs" ] || return
for lib in $libs; do
${lib}_${pp}_${hk}_cb
done
}
|