]> git.ipfire.org Git - ipfire-2.x.git/blame - src/scripts/ipsec-interfaces
suricata: Change midstream policy to "pass-flow"
[ipfire-2.x.git] / src / scripts / ipsec-interfaces
CommitLineData
b8c153bc
MT
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
66c36198 5# Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> #
b8c153bc
MT
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
22shopt -s nullglob
23
24VPN_CONFIG="/var/ipfire/vpn/config"
25
918ee4a4
MT
26ROUTE_TABLE="220"
27ROUTE_TABLE_PRIO="128"
28
54bac014 29eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
b8c153bc
MT
30eval $(/usr/local/bin/readhash /var/ipfire/vpn/settings)
31
918ee4a4
MT
32# Get RED interface name
33if [ -r "/var/ipfire/red/iface" ]; then
34 RED_INTF="$(</var/ipfire/red/iface)"
35else
36 RED_INTF="red0"
37fi
38
b8c153bc 39VARS=(
68263645
MT
40 id status name lefthost type ctype psk local local_id leftsubnets
41 remote_id remote rightsubnets x3 x4 x5 x6 x7 x8 x9 x10 x11 x12
1ca2f88a
MT
42 x13 x14 x15 x16 x17 x18 x19 proto x20 x21 x22
43 route x23 mode interface_mode interface_address interface_mtu rest
b8c153bc
MT
44)
45
46log() {
47 logger -t ipsec "$@"
48}
49
f9dd1346
MT
50resolve_hostname() {
51 local hostname="${1}"
52
53 dig +short A "${hostname}" | tail -n1
54}
55
918ee4a4
MT
56ip_encode() {
57 local address="${1}"
58
59 local int=0
60 for field in ${address//./ }; do
61 int=$(( $(( ${int} << 8 )) | ${field} ))
62 done
63
64 echo ${int}
65}
66
67function ip_in_subnet() {
68 local address="${1}"
69 local subnet="${2}"
70
71 local netmask="${subnet#*/}"
72
73 # Convert netmask to prefix if necessary
74 case "${netmask}" in
75 [0-9]+)
76 ;;
77 *)
78 netmask="$(netmask2prefix "${netmask}")"
79 ;;
80 esac
81
82 local vlsm=$(( -1 << $(( 32 - ${netmask} )) ))
83
84 [ "$(( $(ip_encode "${address}") & ${vlsm} ))" -eq "$(( $(ip_encode "${subnet%/*}") & ${vlsm} ))" ]
85}
86
87netmask2prefix() {
88 local netmask="${1}"
89 local mask="$(ip_encode "${netmask}")"
90
91 local cidr=0
92 local x="$(( 128 << 24 ))" # 0x80000000
93
94 while [ $(( ${x} & ${mask} )) -ne 0 ]; do
95 [ ${mask} -eq ${x} ] && mask=0 || mask=$(( ${mask} << 1 ))
96 cidr=$(( ${cidr} + 1 ))
97 done
98
99 echo "${cidr}"
100}
101
b8c153bc 102main() {
b8c153bc
MT
103 # Register local variables
104 local "${VARS[@]}"
105 local action
106
107 local interfaces=()
1ca2f88a 108
918ee4a4
MT
109 # Flush IPsec routes
110 ip route flush table "${ROUTE_TABLE}"
111
112 # Remove lookups
113 ip rule del lookup "${ROUTE_TABLE}"
114
1a45f9a7
MT
115 # We are done when IPsec is not enabled
116 if [ "${ENABLED}" = "on" ]; then
918ee4a4
MT
117 # Enable route table lookup
118 ip rule add lookup "${ROUTE_TABLE}" prio "${ROUTE_TABLE_PRIO}"
119
1a45f9a7
MT
120 while IFS="," read -r "${VARS[@]}"; do
121 # Check if the connection is enabled
122 [ "${status}" = "on" ] || continue
123
124 # Check if this a net-to-net connection
125 [ "${type}" = "net" ] || continue
126
127 # Determine the interface name
128 case "${interface_mode}" in
129 gre|vti)
130 local intf="${interface_mode}${id}"
131 ;;
132 *)
918ee4a4
MT
133 # Install routes
134 local address
135
136 local _address
137 for _address in ${GREEN_ADDRESS} ${BLUE_ADDRESS} ${ORANGE_ADDRESS}; do
138 local leftsubnet
139 for leftsubnet in ${leftsubnets//\|/ }; do
140 if ip_in_subnet "${_address}" "${leftsubnet}"; then
141 address="${_address}"
142 break
143 fi
144 done
145
146 # End loop when address is set
147 [ -n "${address}" ] && break
148 done
149
150 local rightsubnet
151 for rightsubnet in ${rightsubnets//\|/ }; do
152 # Ignore default
153 case "${rightsubnet}" in
154 0.0.0.0/*)
155 continue
156 ;;
157 esac
158
159 log "Creating route to ${rightsubnet} (via ${address} and ${RED_INTF})"
160 ip route add table "${ROUTE_TABLE}" "${rightsubnet}" proto static \
161 dev "${RED_INTF}" src "${address}"
162 done
163
164 # No interface processing required
1a45f9a7
MT
165 continue
166 ;;
167 esac
168
169 # Add the interface to the list of all interfaces
170 interfaces+=( "${intf}" )
171
d985ce5a
MT
172 # Compat for older connections
173 if [ "${local}" = "off" ]; then
174 if [ "${VPN_IP}" = "%defaultroute" ]; then
175 local=""
176 else
177 local="${VPN_IP}"
178 fi
179 fi
180
181 # Handle %defaultroute
182 if [ -z "${local}" ]; then
183 if [ -r "/var/ipfire/red/local-ipaddress" ]; then
184 local="$(</var/ipfire/red/local-ipaddress)"
185
186 elif [ "${RED_TYPE}" = "STATIC" -a -n "${RED_ADDRESS}" ]; then
187 local="${RED_ADDRESS}"
188 fi
189 fi
190
f9dd1346
MT
191 # Resolve any hostnames
192 if [[ ! ${remote} =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
193 remote="$(resolve_hostname "${remote}")"
194 fi
195
1a45f9a7 196 local args=(
1ca2f88a
MT
197 "local" "${local}"
198 "remote" "${remote}"
1a45f9a7
MT
199 )
200
6a45a1f1
MT
201 case "${interface_mode}" in
202 gre)
203 # Add TTL
204 args+=( "ttl" "255" )
205 ;;
206
207 vti)
208 # Add key for VTI
209 args+=( "key" "${id}" )
210 ;;
211 esac
b8c153bc 212
1a45f9a7
MT
213 # Update the settings when the interface already exists
214 if [ -d "/sys/class/net/${intf}" ]; then
215 ip link change dev "${intf}" \
216 type "${interface_mode}" "${args[@]}" &>/dev/null
b8c153bc 217
1a45f9a7
MT
218 # Create a new interface and bring it up
219 else
220 log "Creating interface ${intf}"
3dc21d43
MT
221 if ! ip link add name "${intf}" type "${interface_mode}" "${args[@]}"; then
222 log "Could not create interface ${intf}"
223 continue
224 fi
1a45f9a7
MT
225 fi
226
227 # Add an IP address
228 ip addr flush dev "${intf}"
229 ip addr add "${interface_address}" dev "${intf}"
230
0de7cc50
MT
231 # Disable IPsec policy lookup for VTI
232 if [ "${interface_mode}" = "vti" ]; then
233 sysctl -qw "net.ipv4.conf.${intf}.disable_policy=1"
234 fi
235
1a45f9a7
MT
236 # Set MTU
237 ip link set dev "${intf}" mtu "${interface_mtu}"
b8c153bc 238
1a45f9a7
MT
239 # Bring up the interface
240 ip link set dev "${intf}" up
241 done < "${VPN_CONFIG}"
242 fi
b8c153bc
MT
243
244 # Delete all other interfaces
245 local intf
c821440c 246 for intf in /sys/class/net/gre[0-9]* /sys/class/net/vti[0-9]*; do
b8c153bc
MT
247 intf="$(basename "${intf}")"
248
249 # Ignore a couple of interfaces that cannot be deleted
250 case "${intf}" in
251 gre0|gretap0)
252 continue
253 ;;
254 esac
255
256 # Check if interface is on the list
257 local i found="false"
258 for i in ${interfaces[@]}; do
259 if [ "${intf}" = "${i}" ]; then
260 found="true"
261 break
262 fi
263 done
264
265 # Nothing to do if interface was found
266 ${found} && continue
267
268 # Delete the interface
269 log "Deleting interface ${intf}"
270 ip link del "${intf}" &>/dev/null
271 done
3b521c72
MT
272
273 # (Re-)Apply all static routes
274 /etc/init.d/static-routes start
b8c153bc
MT
275}
276
277main || exit $?