]> git.ipfire.org Git - people/ms/network.git/blame - src/functions/functions.ipsec-pool
man: Convert network-zone(8) to asciidoc
[people/ms/network.git] / src / functions / functions.ipsec-pool
CommitLineData
4e78b7ad
JS
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2017 IPFire Network Development Team #
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
22IPSEC_POOL_CONFIG_SETTINGS="\
23 DNS_SERVER \
24 NETWORK \
25 TYPE"
26
27cli_ipsec_pool() {
28 if ipsec_pool_exists ${1}; then
29 local pool=${1}
30 local key=${2}
31 key=${key//-/_}
32 shift 2
33
34 case "${key}" in
35 dns_server|network)
36 ipsec_pool_${key} ${pool} "$@"
37 ;;
38 show)
39 cli_ipsec_pool_show "${pool}"
40 exit $?
41 ;;
42 *)
43 error "Unrecognized argument: ${key}"
44 exit ${EXIT_ERROR}
45 ;;
46 esac
47 else
48 local action=${1}
49 shift
50
51 case "${action}" in
52 new)
53 ipsec_pool_new "$@"
54 ;;
55 destroy)
56 ipsec_pool_destroy "$@"
57 ;;
58 ""|*)
59 if [ -n "${action}" ]; then
60 error "Unrecognized argument: '${action}'"
61 fi
62 exit ${EXIT_ERROR}
63 ;;
64 esac
65 fi
66}
67
68# This function writes all values to a via ${pool} specificated VPN IPsec pool configuration file
69ipsec_pool_write_config() {
70 assert [ $# -ge 1 ]
71
72 local pool="${1}"
73
74 if ! ipsec_pool_exists "${pool}"; then
75 log ERROR "No such VPN IPsec pool: ${pool}"
76 return ${EXIT_ERROR}
77 fi
78
79 local path="${NETWORK_IPSEC_POOLS_DIR}/${pool}/settings"
80
81 if ! settings_write "${path}" ${IPSEC_POOL_CONFIG_SETTINGS}; then
82 log ERROR "Could not write configuration settings for VPN IPsec pool ${pool}"
83 return ${EXIT_ERROR}
84 fi
85
86 if ! ipsec_pool_reload ${pool}; then
87 log WARNING "Could not reload IPsec pool ${pool}"
88 fi
89
90 # When we get here the writing of the config file was successful
91 return ${EXIT_OK}
92}
93
94# This funtion writes the value for one key to a via ${connection} specificated
95# VPN IPsec pool configuration file
96ipsec_pool_write_config_key() {
97 assert [ $# -ge 3 ]
98
99 local pool=${1}
100 local key=${2}
101 shift 2
102
103 local value="$@"
104
105 if ! ipsec_pool_exists "${pool}"; then
106 log ERROR "No such VPN IPsec pool: ${pool}"
107 return ${EXIT_ERROR}
108 fi
109
110 log DEBUG "Set '${key}' to new value '${value}' in VPN IPsec pool '${pool}'"
111
112 local ${IPSEC_POOL_CONFIG_SETTINGS}
113
114 # Read the config settings
115 if ! ipsec_pool_read_config "${pool}"; then
116 return ${EXIT_ERROR}
117 fi
118
119 # Set the key to a new value
120 assign "${key}" "${value}"
121
122 if ! ipsec_pool_write_config "${pool}"; then
123 return ${EXIT_ERROR}
124 fi
125
126 return ${EXIT_TRUE}
127}
128
129# Reads one or more keys out of a settings file or all if no key is provided.
130ipsec_pool_read_config() {
131 assert [ $# -ge 1 ]
132
133 local pool="${1}"
134 shift 1
135
136 if ! ipsec_pool_exists "${pool}"; then
137 log ERROR "No such VPN IPsec pool : ${pool}"
138 return ${EXIT_ERROR}
139 fi
140
141 local args
142 if [ $# -eq 0 ] && [ -n "${IPSEC_POOL_CONFIG_SETTINGS}" ]; then
143 list_append args ${IPSEC_POOL_CONFIG_SETTINGS}
144 else
145 list_append args $@
146 fi
147
148 local path="${NETWORK_IPSEC_POOLS_DIR}/${pool}/settings"
149
150 if ! settings_read "${path}" ${args}; then
151 log ERROR "Could not read settings for VPN IPsec pool ${pool}"
152 return ${EXIT_ERROR}
153 fi
154}
155
156# This function checks if a vpn IPsec pool exists
157# Returns True when yes and false when not
158ipsec_pool_exists() {
159 assert [ $# -eq 1 ]
160
161 local pool=${1}
162
163 local path="${NETWORK_IPSEC_POOLS_DIR}/${pool}"
164
165 [ -d "${path}" ] && return ${EXIT_TRUE} || return ${EXIT_FALSE}
166}
167
168# This function checks if a VPN IPsec pool name is valid
169# Allowed are only A-Za-z0-9
170ipsec_pool_check_name() {
171 assert [ $# -eq 1 ]
172
173 local pool=${1}
174
175 # These are special words in strongswan
176 if isoneof pool dhcp radius; then
177 return ${EXIT_ERROR}
178 fi
179
180 [[ "${pool}" =~ [^[:alnum:]$] ]]
181}
182
183ipsec_pool_new() {
184 if [ $# -gt 1 ]; then
185 error "Too many arguments"
186 return ${EXIT_ERROR}
187 fi
188
189 local pool="${1}"
190 if ! isset pool; then
191 error "Please provide a pool name"
192 return ${EXIT_ERROR}
193 fi
194
195 # Check for duplicates
196 if ipsec_pool_exists "${pool}"; then
197 error "The VPN IPsec pool ${pool} already exists"
198 return ${EXIT_ERROR}
199 fi
200
201 # Check if the name of the connection is valid
202 if ipsec_pool_check_name "${pool}"; then
203 error "'${pool}' contains illegal characters"
204 return ${EXIT_ERROR}
205 fi
206
207 log DEBUG "Creating VPN IPsec pool ${pool}"
208
209 if ! mkdir -p "${NETWORK_IPSEC_POOLS_DIR}/${pool}"; then
210 log ERROR "Could not create config directory for ${pool}"
211 return ${EXIT_ERROR}
212 fi
213
214 local ${IPSEC_POOL_CONFIG_SETTINGS}
215
216 if ! ipsec_pool_write_config "${pool}"; then
217 log ERROR "Could not write new config file"
218 return ${EXIT_ERROR}
219 fi
220}
221
222# Function that deletes based on the passed parameters
223# one ore more vpn ipsec pools
224ipsec_pool_destroy() {
225 local pool
226 for pool in $@; do
227 if ! ipsec_pool_exists "${pool}"; then
228 log ERROR "The VPN IPsec pool ${pool} does not exist."
229 continue
230 fi
231
ca0527dd
JS
232 if [ -f "${NETWORK_IPSEC_SWANCTL_POOLS_DIR}/${pool}.conf" ]; then
233 if ! file_delete "${NETWORK_IPSEC_SWANCTL_POOLS_DIR}/${pool}.conf"; then
234 # We going on here to delete at least the configuration directory
235 log ERROR "Could not delete ${NETWORK_IPSEC_SWANCTL_POOLS_DIR}/${pool}.conf"
236 fi
237 fi
238
4e78b7ad
JS
239 log DEBUG "Deleting VPN IPsec pool ${pool}"
240
241 if ! rm -rf "${NETWORK_IPSEC_POOLS_DIR}/${pool}"; then
242 log ERROR "Deleting the VPN IPsec pool ${pool} was not sucessful"
243 return ${EXIT_ERROR}
244 fi
245 done
f5135fb7
JS
246
247 ipsec_strongswan_load_pools
4e78b7ad
JS
248}
249
250ipsec_pool_set_type() {
251 local pool=${1}
252 local ip=${2}
253 assert isset pool
254 assert isset ip
255
256 local type=$(ip_detect_protocol ${ip})
257
258 if ! isset type; then
259 error "Cannot detect IP protocol of ${ip}"
260 return ${EXIT_ERROR}
261 else
262 log DEBUG "IP protocol of ${ip} is ${type}"
263 if ! ipsec_pool_write_config_key "${pool}" "TYPE" ${type}; then
264 log ERROR "Could not write configuration settings"
265 return ${EXIT_ERROR}
266 fi
267 fi
268}
269
270ipsec_pool_network() {
271 if [ ! $# -eq 2 ]; then
272 log ERROR "Not enough arguments"
273 return ${EXIT_ERROR}
274 fi
275 local pool=${1}
276 local network=${2}
277
278 local TYPE
279 if ! ipsec_pool_read_config ${pool} "TYPE"; then
280 error "Failed to read configuration settings for pool '${pool}'"
281 return ${EXIT_ERROR}
282 fi
283
284 if ! isset TYPE; then
285 if ! ip_net_is_valid ${network}; then
286 log ERROR "Network '${network}' is invalid"
287 return ${EXIT_ERROR}
288 fi
289
290 if ! ipsec_pool_set_type ${pool} ${network}; then
291 log ERROR "Could not set type for IPsec pool ${pool}"
292 return ${EXIT_ERROR}
293 fi
294 else
295 if ! ${TYPE}_net_is_valid ${network}; then
296 log ERROR "Network '${network}' is invalid"
297 return ${EXIT_ERROR}
298 fi
299 fi
300
301 if ! ipsec_pool_write_config_key "${pool}" "NETWORK" ${network}; then
302 log ERROR "Could not write configuration settings"
303 return ${EXIT_ERROR}
304 fi
305}
306
307ipsec_pool_dns_server() {
308 if [ ! $# -eq 2 ]; then
309 log ERROR "Not enough arguments"
310 return ${EXIT_ERROR}
311 fi
312 local pool=${1}
313 local dns_server=${2}
314
315 local TYPE
316 if ! ipsec_pool_read_config ${pool} "TYPE"; then
317 error "Failed to read configuration settings for pool '${pool}'"
318 return ${EXIT_ERROR}
319 fi
320
321 if ! isset TYPE; then
322 if ! ip_is_valid ${dns_server}; then
323 log ERROR "DNS server '${dns_server}' is invalid"
324 return ${EXIT_ERROR}
325 fi
326
327 if ! ipsec_pool_set_type ${pool} ${dns_server}; then
328 log ERROR "Could not set type for IPsec pool ${pool}"
329 return ${EXIT_ERROR}
330 fi
331 else
332 if ! ${TYPE}_is_valid ${dns_server}; then
333 log ERROR "DNS server '${dns_server}' is invalid"
334 return ${EXIT_ERROR}
335 fi
336 fi
337
338 if ! ipsec_pool_write_config_key "${pool}" "DNS_SERVER" ${dns_server}; then
339 log ERROR "Could not write configuration settings"
340 return ${EXIT_ERROR}
341 fi
342}
343
344ipsec_pool_check_config() {
345 local pool=${1}
346 assert isset pool
347
348 local ${IPSEC_POOL_CONFIG_SETTINGS}
349 if ! ipsec_pool_read_config "${pool}"; then
350 log ERROR "Could not read configuration settings"
351 return ${EXIT_ERROR}
352 fi
353
354 if ! isset NETWORK; then
355 log ERROR "Network for IPSec pool ${pool} is not set"
356 return ${EXIT_ERROR}
357 fi
358
359 if ! isset TYPE; then
360 TYPE=$(ip_detect_protocol ${NETWORK})
361 log DEBUG "IP protocol of ${NETWORK} is ${TYPE}"
362 if ! isset TYPE; then
363 error "Cannot detect IP protocol of ${NETWORK}"
364 return ${EXIT_ERROR}
365 else
366 if ! ipsec_pool_write_config_key "${pool}" "TYPE" ${TYPE}; then
367 log ERROR "Could not write configuration settings"
368 return ${EXIT_ERROR}
369 fi
370 fi
371 else
372 if ! ${TYPE}_net_is_valid ${NETWORK}; then
373 log ERROR "NETWORK '${NETWORK}' is invalid"
374 return ${EXIT_ERROR}
375 fi
376
377 if isset DNS_SERVER && ! ${TYPE}_is_valid ${DNS_SERVER}; then
378 log ERROR "DNS server '${DNS_SERVER}' is invalid"
379 return ${EXIT_ERROR}
380 fi
381 fi
382
383 return ${EXIT_OK}
384}
385
386ipsec_pool_reload() {
387 local pool=${1}
388
389 if ! ipsec_pool_to_strongswan ${pool}; then
390 log ERROR "Could not generate strongswan config for ${pool}"
391 return ${EXIT_ERROR}
392 fi
393
394 ipsec_strongswan_load
395}
396
397ipsec_pool_to_strongswan() {
398 local pool=${1}
399
400 log DEBUG "Generating IPsec pool config for ${pool}"
401
402 local ${IPSEC_POOL_CONFIG_SETTINGS}
403 if ! ipsec_pool_read_config "${pool}"; then
404 return ${EXIT_ERROR}
405 fi
406
407 if isset NETWORK && ! ipsec_pool_check_config "${pool}"; then
408 log ERROR "Configuration of ${pool} seems to be invalid"
409 return ${EXIT_ERROR}
410 fi
411
412 local path="${NETWORK_IPSEC_SWANCTL_POOLS_DIR}/${pool}.conf"
413
414 (
415 config_header "strongSwan pool configuration"
416
417 if isset NETWORK; then
418 print_indent 0 "pools {"
419
420 print_indent 1 "${pool} {"
421 print_indent 2 "addrs = ${NETWORK}"
422
423 if isset DNS_SERVER; then
424 print_indent 2 "dns = ${DNS_SERVER}"
425 fi
426
427 print_indent 1 "}"
428 print_indent 0 "}"
429 fi
430 ) > ${path}
431}
ecac9e2b
JS
432
433# List all IPsec pools
434ipsec_list_pools() {
435 local pool
436 for pool in ${NETWORK_IPSEC_POOLS_DIR}/*; do
437 [ -d "${pool}" ] || continue
438 basename "${pool}"
439 done
440}
f5135fb7
JS
441
442# Reload all strongswan pools
443ipsec_strongswan_load_pools() {
444 # Do nothing if strongswan is not running
445 if ! service_is_active "strongswan"; then
446 return ${EXIT_OK}
447 fi
448
449 if ! cmd swanctl --load-pools; then
450 log ERROR "Could not reload strongswan pools"
451 return ${EXIT_ERROR}
452 fi
453}