]> git.enpas.org Git - openwrt.git/blob - package/firewall/files/lib/core_interface.sh
[PATCH] firewall: provide examples of ssh port relocation on firewall and IPsec passt...
[openwrt.git] / package / firewall / files / lib / core_interface.sh
1 # Copyright (C) 2009-2011 OpenWrt.org
2
3 fw__uci_state_add() {
4         local var="$1"
5         local item="$2"
6
7         local list="$(uci_get_state firewall core $var)"
8               list=" ${list:+$list }"
9
10         for item in $item; do
11                 case "$list" in
12                         "* $item *") continue;;
13                         *) list="$list$item ";;
14                 esac
15         done
16
17         list="${list% }"
18         list="${list# }"
19
20         uci_revert_state firewall core $var
21         uci_set_state firewall core $var "$list"
22 }
23
24 fw__uci_state_del() {
25         local var="$1"
26         local item="$2"
27
28         echo "del[$item]"
29
30         local list val
31         for val in $(uci_get_state firewall core "$var" | sort -u); do
32                 list="${list:+$list }$val"
33         done
34
35         echo "list[$list]"
36
37         uci_revert_state firewall core $var
38
39         [ -n "$list" ] && {
40                 list=" $list "
41
42                 for item in $item; do
43                         list="${list// $item / }"
44                 done
45
46                 list="${list# }"
47                 list="${list% }"
48
49                 echo "list2[$list]"
50
51                 uci_set_state firewall core $var "$list"
52         }
53 }
54
55 fw_configure_interface() {
56         local iface=$1
57         local action=$2
58         local ifname=$3
59         local aliasnet=$4
60
61         [ "$action" == "add" ] && {
62                 local status=$(uci_get_state network "$iface" up 0)
63                 [ "$status" == 1 ] || [ -n "$aliasnet" ] || return 0
64         }
65
66         [ -n "$ifname" ] || {
67                 ifname=$(uci_get_state network "$iface" ifname)
68                 ifname="${ifname%%:*}"
69                 [ -z "$ifname" ] && return 0
70         }
71
72         [ "$ifname" == "lo" ] && return 0
73
74         fw_callback pre interface
75
76         fw__do_rules() {
77                 local action=$1
78                 local zone=$2
79                 local chain=zone_${zone}
80                 local ifname=$3
81                 local subnet=$4
82
83                 local inet onet mode
84                 fw_get_family_mode mode x $zone i
85
86                 case "$mode/$subnet" in
87                         # Zone supports v6 only or dual, need v6
88                         G6/*:*|i/*:*)
89                                 inet="-s $subnet -d ::/0"
90                                 onet="-s ::/0 -d $subnet"
91                                 mode=6
92                         ;;
93
94                         # Zone supports v4 only or dual, need v4
95                         G4/*.*.*.*|i/*.*.*.*)
96                                 inet="-s $subnet -d 0.0.0.0/0"
97                                 onet="-s 0.0.0.0/0 -d $subnet"
98                                 mode=4
99                         ;;
100
101                         # Need v6 while zone is v4
102                         */*:*) fw_log info "zone $zone does not support IPv6 address family, skipping"; return ;;
103
104                         # Need v4 while zone is v6
105                         */*.*) fw_log info "zone $zone does not support IPv4 address family, skipping"; return ;;
106
107                         # Strip prefix
108                         *) mode="${mode#G}" ;;
109                 esac
110
111                 lock /var/run/firewall-interface.lock
112
113                 fw $action $mode f ${chain}_ACCEPT ACCEPT $ { -o "$ifname" $onet }
114                 fw $action $mode f ${chain}_ACCEPT ACCEPT $ { -i "$ifname" $inet }
115                 fw $action $mode f ${chain}_DROP   DROP   $ { -o "$ifname" $onet }
116                 fw $action $mode f ${chain}_DROP   DROP   $ { -i "$ifname" $inet }
117                 fw $action $mode f ${chain}_REJECT reject $ { -o "$ifname" $onet }
118                 fw $action $mode f ${chain}_REJECT reject $ { -i "$ifname" $inet }
119
120                 fw $action $mode f ${chain}_MSSFIX TCPMSS  $ { -o "$ifname" -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu $onet }
121
122                 fw $action $mode f input   ${chain}         $ { -i "$ifname" $inet }
123                 fw $action $mode f forward ${chain}_forward $ { -i "$ifname" $inet }
124                 fw $action $mode n PREROUTING ${chain}_prerouting $ { -i "$ifname" $inet }
125                 fw $action $mode r PREROUTING ${chain}_notrack    $ { -i "$ifname" $inet }
126                 fw $action $mode n POSTROUTING ${chain}_nat       $ { -o "$ifname" $onet }
127
128                 lock -u /var/run/firewall-interface.lock
129         }
130
131         local old_zones old_ifname old_subnets
132         config_get old_zones core "${iface}_zone"
133         [ -n "$old_zones" ] && {
134                 config_get old_ifname core "${iface}_ifname"
135                 config_get old_subnets core "${iface}_subnets"
136
137                 local z
138                 for z in $old_zones; do
139                         local n
140                         for n in ${old_subnets:-""}; do
141                                 fw_log info "removing $iface ($old_ifname${n:+ alias $n}) from zone $z"
142                                 fw__do_rules del $z $old_ifname $n
143                         done
144
145                         [ -n "$old_subnets" ] || {
146                                 fw__uci_state_del "${z}_networks" "$iface"
147                                 env -i ACTION=remove ZONE="$z" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall
148                         }
149                 done
150
151                 local old_aliases
152                 config_get old_aliases core "${iface}_aliases"
153
154                 local a
155                 for a in $old_aliases; do
156                         fw_configure_interface "$a" del "$old_ifname"
157                 done
158
159                 uci_revert_state firewall core "${iface}_zone"
160                 uci_revert_state firewall core "${iface}_ifname"
161                 uci_revert_state firewall core "${iface}_subnets"
162                 uci_revert_state firewall core "${iface}_aliases"
163         }
164
165         [ "$action" == del ] && return
166
167         [ -z "$aliasnet" ] && {
168                 local aliases
169                 config_get aliases "$iface" aliases
170
171                 local a
172                 for a in $aliases; do
173                         local ipaddr netmask ip6addr
174                         config_get ipaddr "$a" ipaddr
175                         config_get netmask "$a" netmask
176                         config_get ip6addr "$a" ip6addr
177
178                         [ -n "$ipaddr" ] && fw_configure_interface "$a" add "" "$ipaddr${netmask:+/$netmask}"
179                         [ -n "$ip6addr" ] && fw_configure_interface "$a" add "" "$ip6addr"
180                 done
181
182                 fw_sysctl_interface $ifname
183                 fw_callback post interface
184
185                 uci_set_state firewall core "${iface}_aliases" "$aliases"
186         } || {
187                 local subnets=
188                 config_get subnets core "${iface}_subnets"
189                 append subnets "$aliasnet"
190
191                 config_set core "${iface}_subnets" "$subnets"
192                 uci_set_state firewall core "${iface}_subnets" "$subnets"
193         }
194
195         local new_zones=
196         load_zone() {
197                 fw_config_get_zone "$1"
198                 list_contains zone_network "$iface" || return
199
200                 fw_log info "adding $iface ($ifname${aliasnet:+ alias $aliasnet}) to zone $zone_name"
201                 fw__do_rules add ${zone_name} "$ifname" "$aliasnet"
202                 append new_zones $zone_name
203
204                 [ -n "$aliasnet" ] || {
205                         fw__uci_state_add "${zone_name}_networks" "${zone_network}"
206                         env -i ACTION=add ZONE="$zone_name" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall
207                 }
208         }
209         config_foreach load_zone zone
210
211         uci_set_state firewall core "${iface}_zone" "$new_zones"
212         uci_set_state firewall core "${iface}_ifname" "$ifname"
213 }
214
215 fw_sysctl_interface() {
216         local ifname=$1
217         {
218                 sysctl -w net.ipv4.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS
219                 sysctl -w net.ipv6.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS
220                 sysctl -w net.ipv4.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE
221                 sysctl -w net.ipv6.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE
222         } >/dev/null 2>/dev/null
223 }
224