2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2017 IPFire Network Development Team #
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. #
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. #
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/>. #
20 ###############################################################################
22 IPSEC_CONNECTION_CONFIG_SETTINGS
="\
42 IPSEC_POOL_CONFIG_SETTINGS
="\
48 IPSEC_DEFAULT_AUTH_MODE
="PSK"
49 IPSEC_DEFAULT_DPD_ACTION
="restart"
50 IPSEC_DEFAULT_DPD_DELAY
="30"
51 IPSEC_DEFAULT_DPD_TIMEOUT
="120"
52 IPSEC_DEFAULT_ENABLED
="true"
53 IPSEC_DEFAULT_INACTIVITY_TIMEOUT
="0"
54 IPSEC_DEFAULT_MODE
="tunnel"
55 IPSEC_DEFAULT_SECURITY_POLICY
="system"
56 IPSEC_DEFAULT_START_ACTION
="on-demand"
57 IPSEC_DEFAULT_TYPE
="net-to-net"
59 IPSEC_VALID_MODES
="gre-transport tunnel vti"
60 IPSEC_VALID_AUTH_MODES
="PSK"
68 cli_ipsec_connection $@
74 error
"Unrecognized argument: ${action}"
80 cli_ipsec_connection
() {
81 if ipsec_connection_exists
${1}; then
88 authentication|down|disable|dpd|
enable|inactivity_timeout|
local|mode|peer|pool|remote|security_policy|start_action|up
)
89 ipsec_connection_
${key} ${connection} $@
92 cli_ipsec_connection_show
"${connection}"
96 error
"Unrecognized argument: ${key}"
106 ipsec_connection_new $@
109 cli_ipsec_connection_destroy $@
112 if [ -n "${action}" ]; then
113 error
"Unrecognized argument: '${action}'"
122 if ipsec_pool_exists
${1}; then
130 ipsec_pool_
${key} ${pool} $@
133 cli_ipsec_pool_show
"${pool}"
137 error
"Unrecognized argument: ${key}"
150 ipsec_pool_destroy $@
153 if [ -n "${action}" ]; then
154 error
"Unrecognized argument: '${action}'"
162 cli_ipsec_connection_destroy
() {
163 local connection
="${1}"
165 if ! ipsec_connection_destroy
"${connection}"; then
169 # Inform strongswan about the changes
170 ipsec_strongswan_load
172 # Configure strongswan autostart
173 ipsec_strongswan_autostart
176 cli_ipsec_connection_show
() {
177 local connection
="${1}"
179 # Read the config settings
180 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
181 if ! ipsec_connection_read_config
"${connection}"; then
182 error
"Could not read the connection configuration"
186 cli_headline
0 "IPsec VPN Connection: ${connection}"
191 cli_print_fmt1
1 "Peer" "${PEER}"
195 cli_print_fmt1
1 "Security Policy" "${SECURITY_POLICY-${IPSEC_DEFAULT_SECURITY_POLICY}}"
198 cli_headline
2 "Authentication"
199 case "${AUTH_MODE^^}" in
201 cli_print_fmt1
2 "Mode" "Pre-Shared-Key"
204 cli_print_fmt1
2 "Pre-Shared-Key" "****"
206 cli_print_fmt1
2 "Pre-Shared-Key" "- is not set -"
216 for i
in LOCAL REMOTE
; do
219 cli_headline
2 "Local"
222 cli_headline
2 "Remote"
226 local id_var
="${i}_ID"
227 if [ -n "${!id_var}" ]; then
228 cli_print_fmt1
2 "ID" "${!id_var}"
231 local prefix_var
="${i}_PREFIX"
232 if isset
${prefix_var}; then
233 cli_headline
3 "Prefix(es)"
236 for prefix
in ${!prefix_var}; do
237 cli_print_fmt1
3 "${prefix}"
244 cli_headline
2 "Misc."
248 cli_print_fmt1
2 "Transport Mode" "GRE Transport"
251 cli_print_fmt1
2 "Transport Mode" "Tunnel"
254 cli_print_fmt1
2 "Transport Mode" "Virtual Tunnel Interface"
257 cli_print_fmt1
2 "Transport Mode" "- Unknown -"
262 if isset INACTIVITY_TIMEOUT
&& [ ${INACTIVITY_TIMEOUT} -gt 0 ]; then
263 cli_print_fmt1
2 "Inactivity Timeout" "$(format_time ${INACTIVITY_TIMEOUT})"
270 ipsec_connection_disable
() {
271 local connection
=${1}
273 if ! ipsec_connection_write_config_key
"${connection}" "ENABLED" "false"; then
274 log ERROR
"Could not write configuration settings"
278 # Configure strongswan autostart
279 ipsec_strongswan_autostart
282 ipsec_connection_enable
() {
283 local connection
=${1}
285 if ! ipsec_connection_write_config_key
"${connection}" "ENABLED" "true"; then
286 log ERROR
"Could not write configuration settings"
290 # Configure strongswan autostart
291 ipsec_strongswan_autostart
294 # This function writes all values to a via ${connection} specificated VPN IPsec configuration file
295 ipsec_connection_write_config
() {
298 local connection
="${1}"
300 if ! ipsec_connection_exists
"${connection}"; then
301 log ERROR
"No such VPN IPsec connection: ${connection}"
305 local path
="${NETWORK_IPSEC_CONNS_DIR}/${connection}/settings"
307 if ! settings_write
"${path}" ${IPSEC_CONNECTION_CONFIG_SETTINGS}; then
308 log ERROR
"Could not write configuration settings for VPN IPsec connection ${connection}"
312 ipsec_reload
${connection}
315 # This funtion writes the value for one key to a via ${connection} specificated VPN IPsec connection configuration file
316 ipsec_connection_write_config_key
() {
319 local connection
=${1}
325 if ! ipsec_connection_exists
"${connection}"; then
326 log ERROR
"No such VPN ipsec connection: ${connection}"
330 log DEBUG
"Set '${key}' to new value '${value}' in VPN ipsec connection '${connection}'"
332 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
334 # Read the config settings
335 if ! ipsec_connection_read_config
"${connection}"; then
339 # Set the key to a new value
340 assign
"${key}" "${value}"
342 if ! ipsec_connection_write_config
"${connection}"; then
349 # Reads one or more keys out of a settings file or all if no key is provided.
350 ipsec_connection_read_config
() {
353 local connection
="${1}"
356 if ! ipsec_connection_exists
"${connection}"; then
357 log ERROR
"No such VPN IPsec connection : ${connection}"
363 if [ $# -eq 0 ] && [ -n "${IPSEC_CONNECTION_CONFIG_SETTINGS}" ]; then
364 list_append args
${IPSEC_CONNECTION_CONFIG_SETTINGS}
369 local path
="${NETWORK_IPSEC_CONNS_DIR}/${connection}/settings"
371 if ! settings_read
"${path}" ${args}; then
372 log ERROR
"Could not read settings for VPN IPsec connection ${connection}"
377 # This function checks if a vpn ipsec connection exists
378 # Returns True when yes and false when not
379 ipsec_connection_exists
() {
382 local connection
=${1}
384 local path
="${NETWORK_IPSEC_CONNS_DIR}/${connection}"
386 [ -d "${path}" ] && return ${EXIT_TRUE} || return ${EXIT_FALSE}
389 # Determines if strongswan should be automatically started
390 # when the system boots up.
391 ipsec_strongswan_autostart() {
392 local autostart_needed="false
"
395 for connection in $(ipsec_list_connections); do
398 if ! ipsec_connection_read_config "${connection}" "ENABLED
"; then
399 log WARNING "Could not
read configuation
"
403 if enabled ENABLED; then
404 autostart_needed="true
"
409 # Start strongswan when we need it and when it is not yet enabled
410 if ${autostart_needed}; then
411 if ! service_is_enabled "strongswan
"; then
412 service_enable "strongswan
"
415 if ! service_is_active "strongswan
"; then
416 service_start "strongswan
"
419 # Disable strongswan when we do not need it but it is enabled
420 elif ! ${autostart_needed}; then
421 if service_is_enabled "strongswan
"; then
422 service_disable "strongswan
"
425 if service_is_active "strongswan
"; then
426 service_stop "strongswan
"
431 ipsec_strongswan_load() {
432 # Do nothing if strongswan is not running
433 if ! service_is_active "strongswan
"; then
437 if ! cmd swanctl --load-all; then
438 log ERROR "Could not reload strongswan config
"
443 # Reloads the connection after config changes
445 local connection=${1}
449 if ! ipsec_connection_read_config "${connection}" "ENABLED
"; then
450 log ERROR "Could not
read configuration
for IPsec connection
${connection}"
454 if enabled ENABLED; then
455 if ! ipsec_connection_to_strongswan ${connection}; then
456 log ERROR "Could not generate strongswan config
for ${connnection}"
460 log DEBUG "Deleting strongswan config
${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
"
461 unlink "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
"
464 ipsec_strongswan_load
467 # Handle the cli after authentification
468 ipsec_connection_authentication() {
469 if [ ! $# -gt 1 ]; then
470 log ERROR "Not enough arguments
"
474 local connection=${1}
480 ipsec_connection_authentication_mode "${connection}" $@
483 ipsec_connection_authentication_psk "${connection}" $@
486 log ERROR "Unrecognized argument
: ${cmd}"
492 # Set the authentification mode
493 ipsec_connection_authentication_mode() {
494 if [ ! $# -eq 2 ]; then
495 log ERROR "Not enough arguments
"
498 local connection=${1}
501 if ! isoneof mode ${IPSEC_VALID_AUTH_MODES}; then
502 log ERROR "Auth mode
'${mode}' is invalid
"
506 if ! ipsec_connection_write_config_key "${connection}" "AUTH_MODE
" ${mode^^}; then
507 log ERROR "Could not
write configuration settings
"
513 ipsec_connection_authentication_psk() {
514 if [ ! $# -eq 2 ]; then
515 log ERROR "Not enough arguments
"
519 local connection=${1}
524 if [ ${length} -lt 4 ]; then
525 error "The PSK must be longer than four characters
"
529 if [ ${length} -gt 128 ]; then
530 error "The PSK cannot be longer than
128 characters
"
534 if ! ipsec_connection_write_config_key "${connection}" "PSK
" "${psk}"; then
535 log ERROR "Could not
write configuration settings
"
542 ipsec_connection_up() {
543 local connection="${1}"
545 if ! ipsec_connection_exists "${connection}"; then
546 error "No such VPN IPsec connection
: ${connection}"
550 cmd swanctl --initiate --child "${connection}"
553 ipsec_connection_down() {
554 local connection="${1}"
556 if ! ipsec_connection_exists "${connection}"; then
557 error "No such VPN IPsec connection
: ${connection}"
561 cmd swanctl --terminate --ike "${connection}"
564 # Handle the cli after authentification
565 ipsec_connection_dpd() {
566 if [ ! $# -gt 1 ]; then
567 log ERROR "Not enough arguments
"
571 local connection=${1}
577 ipsec_connection_dpd_action "${connection}" $@
580 ipsec_connection_dpd_delay "${connection}" $@
583 ipsec_connection_dpd_timeout "${connection}" $@
586 log ERROR "Unrecognized argument
: ${cmd}"
592 # Set the default dpd action
593 ipsec_connection_dpd_action() {
594 if [ ! $# -eq 2 ]; then
595 log ERROR "Not enough arguments
"
598 local connection=${1}
601 if ! isoneof action "restart
" "clear"; then
602 log ERROR "dpd action
'${action}' is invalid
"
606 if ! ipsec_connection_write_config_key "${connection}" "DPD_ACTION
" ${action}; then
607 log ERROR "Could not
write configuration settings
"
613 ipsec_connection_dpd_delay() {
614 if [ ! $# -ge 2 ]; then
615 log ERROR "Not enough arguments
"
619 local connection=${1}
623 if ! isinteger value; then
624 value=$(parse_time $@)
625 if [ ! $? -eq 0 ]; then
626 log ERROR "Parsing the passed
time was not sucessful please check the passed values.
"
631 if [ ${value} -lt 0 ]; then
632 log ERROR "The passed
time value must be
in the
sum greater or equal zero seconds.
"
636 if ! ipsec_connection_write_config_key "${connection}" "DPD_DELAY
" ${value}; then
637 log ERROR "Could not
write configuration settings
"
644 # Set the dpd timeout
645 ipsec_connection_dpd_timeout() {
646 if [ ! $# -ge 2 ]; then
647 log ERROR "Not enough arguments
"
651 local connection=${1}
655 if ! isinteger value; then
656 value=$(parse_time $@)
657 if [ ! $? -eq 0 ]; then
658 log ERROR "Parsing the passed
time was not sucessful please check the passed values.
"
663 if [ ${value} -le 0 ]; then
664 log ERROR "The passed
time value must be
in the
sum greater or equal zero seconds.
"
668 if ! ipsec_connection_write_config_key "${connection}" "DPD_TIMEOUT
" ${value}; then
669 log ERROR "Could not
write configuration settings
"
676 # Handle the cli after local
677 ipsec_connection_local() {
678 if [ ! $# -ge 2 ]; then
679 log ERROR "Not enough arguments
"
683 local connection=${1}
689 ipsec_connection_local_address "${connection}" $@
692 ipsec_connection_id "${connection}" "LOCAL
" $@
695 ipsec_connection_prefix "${connection}" "LOCAL
" $@
698 log ERROR "Unrecognized argument
: ${cmd}"
706 # Set the connection mode
707 ipsec_connection_mode() {
708 if [ ! $# -eq 2 ]; then
709 log ERROR "Not enough arguments
"
712 local connection=${1}
715 if ! isoneof mode ${IPSEC_VALID_MODES}; then
716 log ERROR "Mode
'${mode}' is invalid
"
720 if ! ipsec_connection_write_config_key "${connection}" "MODE
" ${mode}; then
721 log ERROR "Could not
write configuration settings
"
728 # Set the local address
729 ipsec_connection_local_address() {
730 if [ ! $# -eq 2 ]; then
731 log ERROR "Not enough arguments
"
734 local connection=${1}
735 local local_address=${2}
737 if ! ipsec_connection_check_peer ${local_address}; then
738 log ERROR "Local address
'${local_address}' is invalid
"
742 if ! ipsec_connection_write_config_key "${connection}" "LOCAL_ADDRESS
" ${local_address}; then
743 log ERROR "Could not
write configuration settings
"
750 # Set the peer to connect to
751 ipsec_connection_peer() {
752 if [ ! $# -eq 2 ]; then
753 log ERROR "Not enough arguments
"
756 local connection=${1}
759 if ! ipsec_connection_check_peer ${peer}; then
760 log ERROR "Peer
'${peer}' is invalid
"
764 if ! ipsec_connection_write_config_key "${connection}" "PEER
" ${peer}; then
765 log ERROR "Could not
write configuration settings
"
772 #Set the local or remote id
773 ipsec_connection_id() {
774 if [ ! $# -eq 3 ]; then
775 log ERROR "Not enough arguments
"
778 local connection=${1}
782 if ! ipsec_connection_check_id ${id}; then
783 log ERROR "Id
'${id}' is invalid
"
787 if ! ipsec_connection_write_config_key "${connection}" "${type}_ID" ${id}; then
788 log ERROR
"Could not write configuration settings"
795 # Set the local or remote prefix
796 ipsec_connection_prefix
() {
797 if [ ! $# -ge 3 ]; then
798 log ERROR
"Not enough arguments"
801 local connection
=${1}
805 local _prefix
="${type}_PREFIX"
807 if ! ipsec_connection_read_config
"${connection}" "${_prefix}"; then
811 # Remove duplicated entries to proceed the list safely
812 assign
"${_prefix}" "$(list_unique ${!_prefix} )"
815 local prefixes_removed
818 while [ $# -gt 0 ]; do
823 list_append prefixes_added
"${arg:1}"
826 list_append prefixes_removed
"${arg:1}"
829 list_append prefixes_set
"${arg}"
832 error
"Invalid argument: ${arg}"
839 # Check if the user is trying a mixed operation
840 if ! list_is_empty prefixes_set
&& (! list_is_empty prefixes_added ||
! list_is_empty prefixes_removed
); then
841 error
"You cannot reset the prefix list and add or remove prefixes at the same time"
845 # Set new prefix list
846 if ! list_is_empty prefixes_set
; then
847 # Check if all prefixes are valid
849 for prefix
in ${prefixes_set}; do
850 if ! ip_net_is_valid
${prefix}; then
851 error
"Unsupported prefix: ${prefix}"
856 assign
"${_prefix}" "${prefixes_set}"
858 # Perform incremental updates
862 # Perform all removals
863 for prefix
in ${prefixes_removed}; do
864 if ! list_remove
"${_prefix}" ${prefix}; then
865 warning
"${prefix} was not on the list and could not be removed"
870 for prefix
in ${prefixes_added}; do
871 if ip_net_is_valid
${prefix}; then
872 if ! list_append_unique
"${_prefix}" ${prefix}; then
873 warning
"${prefix} is already on the prefix list"
876 warning
"${prefix} is not a valid IP network and could not be added"
881 # Check if the list contain at least one valid prefix
882 if list_is_empty
${_prefix}; then
883 error
"Cannot save an empty prefix list"
888 if ! ipsec_connection_write_config_key
"${connection}" "${_prefix}" ${!_prefix}; then
889 log ERROR "Could not
write configuration settings
"
895 # Set the pools to use
896 ipsec_connection_pool() {
897 if [ ! $# -ge 2 ]; then
898 log ERROR "Not enough arguments
"
901 local connection=${1}
905 if ! ipsec_connection_read_config "${connection}" "POOLS
"; then
909 # Remove duplicated entries to proceed the list safely
910 assign "POOLS
" "$
(list_unique
${POOLS})"
916 while [ $# -gt 0 ]; do
921 list_append pools_added "${arg:1}"
924 list_append pools_removed "${arg:1}"
927 list_append pools_set "${arg}"
930 error "Invalid argument
: ${arg}"
937 # Check if the user is trying a mixed operation
938 if ! list_is_empty pools_set && (! list_is_empty pools_added || ! list_is_empty pools_removed); then
939 error "You cannot
reset the pools list and add or remove pools
at the same
time"
944 if ! list_is_empty pools_set; then
945 # Check if all pools are valid
947 for pool in ${pools_set}; do
948 if ! ipsec_pool_exists ${pool} || ! ipsec_pool_check_config ${pool}; then
949 error "Pool
${pool} is not valid
"
954 assign "POOLS
" "${pools_set}"
956 # Perform incremental updates
960 # Perform all removals
961 for pool in ${pools_removed}; do
962 if ! list_remove "POOLS
" ${pool}; then
963 warning "${pool} was not on the list and could not be removed
"
968 for pool in ${pools_added}; do
969 if ! ipsec_pool_exists ${pool} && ! ipsec_pool_check_config ${pool}; then
970 if ! list_append_unique "POOLS
" ${pool}; then
971 warning "${pool} is already on the prefix list
"
974 warning "${pool} is not a valid pool
"
979 # Check if the list contain at least one valid pool
980 if list_is_empty POOLS; then
981 error "Cannot save an empty pool list
"
986 if ! ipsec_connection_write_config_key "${connection}" "POOLS
" ${POOLS}; then
987 log ERROR "Could not
write configuration settings
"
993 # Handle the cli after remote
994 ipsec_connection_remote() {
995 if [ ! $# -ge 2 ]; then
996 log ERROR "Not enough arguments
"
1000 local connection=${1}
1006 ipsec_connection_id "${connection}" "REMOTE
" $@
1010 ipsec_connection_prefix "${connection}" "REMOTE
" $@
1013 log ERROR "Unrecognized argument
: ${cmd}"
1014 return ${EXIT_ERROR}
1021 # Set the inactivity timeout
1022 ipsec_connection_inactivity_timeout() {
1023 if [ ! $# -ge 2 ]; then
1024 log ERROR "Not enough arguments
"
1025 return ${EXIT_ERROR}
1028 local connection=${1}
1032 if ! isinteger value; then
1033 value=$(parse_time $@)
1034 if [ ! $? -eq 0 ]; then
1035 log ERROR "Parsing the passed
time was not sucessful please check the passed values.
"
1036 return ${EXIT_ERROR}
1040 if [ ${value} -le 0 ]; then
1041 log ERROR "The passed
time value must be
in the
sum greater zero seconds.
"
1042 return ${EXIT_ERROR}
1045 if ! ipsec_connection_write_config_key "${connection}" "INACTIVITY_TIMEOUT
" ${value}; then
1046 log ERROR "Could not
write configuration settings
"
1047 return ${EXIT_ERROR}
1053 # Set the default start action
1054 ipsec_connection_start_action() {
1055 if [ ! $# -eq 2 ]; then
1056 log ERROR "Not enough arguments
"
1057 return ${EXIT_ERROR}
1059 local connection=${1}
1062 if ! isoneof action "on-demand
" "always-on
"; then
1063 log ERROR "Start action
'${action}' is invalid
"
1064 return ${EXIT_ERROR}
1067 if ! ipsec_connection_write_config_key "${connection}" "START_ACTION
" ${action}; then
1068 log ERROR "Could not
write configuration settings
"
1069 return ${EXIT_ERROR}
1073 # Set the security policy to use
1074 ipsec_connection_security_policy() {
1075 if [ ! $# -eq 2 ]; then
1076 log ERROR "Not enough arguments
"
1077 return ${EXIT_ERROR}
1079 local connection=${1}
1080 local security_policy=${2}
1082 if ! vpn_security_policy_exists ${security_policy}; then
1083 log ERROR "No such vpn security policy
'${security_policy}'"
1084 return ${EXIT_ERROR}
1087 if ! ipsec_connection_write_config_key "${connection}" "SECURITY_POLICY
" ${security_policy}; then
1088 log ERROR "Could not
write configuration settings
"
1089 return ${EXIT_ERROR}
1093 # Check if a id is valid
1094 ipsec_connection_check_id() {
1098 if [[ ${id} =~ ^@[[:alnum:]]+$ ]] || ip_is_valid ${id}; then
1101 return ${EXIT_FALSE}
1105 # Checks if a peer is valid
1106 ipsec_connection_check_peer() {
1110 # TODO Accept also FQDNs
1111 if ip_is_valid ${peer}; then
1114 return ${EXIT_FALSE}
1118 # This function checks if a VPN IPsec connection name is valid
1119 # Allowed are only A-Za-z0-9
1120 ipsec_connection_check_name() {
1123 local connection=${1}
1125 [[ "${connection}" =~ [^[:alnum:]$] ]]
1128 # Function that creates one VPN IPsec connection
1129 ipsec_connection_new() {
1130 if [ $# -gt 2 ]; then
1131 error "Too many arguments
"
1132 return ${EXIT_ERROR}
1135 local connection="${1}"
1138 if ! isset connection; then
1139 error "Please provide a connection name
"
1140 return ${EXIT_ERROR}
1143 # Check for duplicates
1144 if ipsec_connection_exists "${connection}"; then
1145 error "The VPN IPsec connection
${connection} already exists
"
1146 return ${EXIT_ERROR}
1149 # Check if the name of the connection is valid
1150 if ipsec_connection_check_name "${connection}"; then
1151 error "'${connection}' contains illegal characters
"
1152 return ${EXIT_ERROR}
1155 # Set TYPE to default if not set by the user
1156 if ! isset type; then
1157 type="${IPSEC_DEFAULT_TYPE}"
1160 if ! isoneof "type" "net-to-net
" "host-to-net
"; then
1161 error "Type is invalid
"
1162 return ${EXIT_ERROR}
1165 log DEBUG "Creating VPN IPsec connection
${connection}"
1167 if ! mkdir -p "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
1168 log ERROR "Could not create config directory
for ${connection}"
1169 return ${EXIT_ERROR}
1172 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
1174 AUTH_MODE=${IPSEC_DEFAULT_AUTH_MODE}
1175 DPD_ACTION=${IPSEC_DEFAULT_DPD_ACTION}
1176 DPD_DELAY=${IPSEC_DEFAULT_DPD_DELAY}
1177 DPD_TIMEOUT=${IPSEC_DEFAULT_DPD_TIMEOUT}
1178 ENABLED=${IPSEC_DEFAULT_ENABLED}
1179 MODE=${IPSEC_DEFAULT_MODE}
1180 START_ACTION=${IPSEC_DEFAULT_START_ACTION}
1183 INACTIVITY_TIMEOUT=${IPSEC_DEFAULT_INACTIVITY_TIMEOUT}
1184 SECURITY_POLICY=${IPSEC_DEFAULT_SECURITY_POLICY}
1186 if ! ipsec_connection_write_config "${connection}"; then
1187 log ERROR "Could not
write new config
file"
1188 return ${EXIT_ERROR}
1191 # Configure strongswan autostart
1192 ipsec_strongswan_autostart
1195 # Function that deletes based on the passed parameters one ore more vpn security policies
1196 ipsec_connection_destroy() {
1198 for connection in $@; do
1199 if ! ipsec_connection_exists "${connection}"; then
1200 log ERROR "The VPN IPsec connection
${connection} does not exist.
"
1204 log DEBUG "Deleting VPN IPsec connection
${connection}"
1206 # Delete strongswan configuration file
1207 file_delete "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
"
1209 if ! rm -rf "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
1210 log ERROR "Deleting the VPN IPsec connection
${connection} was not sucessful
"
1211 return ${EXIT_ERROR}
1217 # List all ipsec connections
1218 ipsec_list_connections() {
1220 for connection in ${NETWORK_IPSEC_CONNS_DIR}/*; do
1221 [ -d ${connection} ] || continue
1222 basename ${connection}
1226 ipsec_connection_to_strongswan() {
1227 local connection="${1}"
1228 log DEBUG "Generating IPsec configuration
for ${connection}"
1230 # Read the config settings
1231 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
1232 if ! ipsec_connection_read_config "${connection}"; then
1233 error "Could not
read the connection
${connection}"
1234 return ${EXIT_ERROR}
1237 local path="${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
"
1240 # Write the connection section
1241 _ipsec_connection_to_strongswan_connection "${connection}"
1243 # Write the secrets section
1244 _ipsec_connection_to_strongswan_secrets "${connection}"
1249 _ipsec_connection_to_strongswan_connection() {
1250 local connection="${1}"
1252 # Read the security policy
1253 local ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}
1254 if ! vpn_security_policies_read_config "${SECURITY_POLICY}"; then
1255 return ${EXIT_ERROR}
1260 if isset DPD_DELAY && isinteger DPD_DELAY && [ ${DPD_DELAY} -gt 0 ]; then
1264 # Write configuration header
1265 config_header "strongSwan configuration
for ${connection}"
1267 print_indent 0 "connections
{"
1268 print_indent 1 "${connection} {"
1271 print_indent 2 "# IKE Version"
1272 case "${KEY_EXCHANGE^^}" in
1274 print_indent
2 "version = 1"
1277 # Fall back to IKEv2 for any random values
1279 print_indent
2 "version = 2"
1284 # Always only keep one connection open at a time
1285 print_indent
2 "# Unique IDs"
1286 print_indent
2 "unique = replace"
1290 print_indent
2 "# Local Address"
1291 if isset LOCAL_ADDRESS
; then
1292 print_indent
2 "local_addrs = ${LOCAL_ADDRESS}"
1294 print_indent
2 "local_addrs = %any"
1299 print_indent
2 "# Remote Address"
1301 print_indent
2 "remote_addrs = ${PEER}"
1303 print_indent
2 "remote_addrs = %any"
1308 print_indent
2 "# IKE Proposals"
1309 print_indent
2 "proposals = $(vpn_security_policies_make_ike_proposal ${SECURITY_POLICY})"
1313 if enabled dpd
; then
1314 print_indent
2 "# Dead Peer Detection"
1315 print_indent
2 "dpd_delay = ${DPD_DELAY}"
1317 if isset DPD_TIMEOUT
; then
1318 print_indent
2 "dpd_timeout = ${DPD_TIMEOUT}"
1325 print_indent
2 "# Fragmentation"
1326 print_indent
2 "fragmentation = yes"
1330 if isset POOLS
; then
1331 print_indent
2 "# Pools"
1332 print_indent
2 "pools = $(list_join POOLS ", ")"
1337 print_indent
2 "local {"
1340 if isset LOCAL_ID
; then
1341 print_indent
3 "id = ${LOCAL_ID}"
1345 case "${AUTH_MODE}" in
1347 print_indent
3 "auth = psk"
1355 print_indent
2 "remote {"
1358 if isset REMOTE_ID
; then
1359 print_indent
3 "id = ${REMOTE_ID}"
1363 case "${AUTH_MODE}" in
1365 print_indent
3 "auth = psk"
1374 print_indent
2 "children {"
1375 print_indent
3 "${connection} {"
1377 print_indent
4 "# ESP Proposals"
1378 print_indent
4 "esp_proposals = $(vpn_security_policies_make_esp_proposal ${SECURITY_POLICY})"
1385 print_indent
4 "local_ts = dynamic[gre]"
1386 print_indent
4 "remote_ts = dynamic[gre]"
1390 if isset LOCAL_PREFIX
; then
1391 print_indent
4 "local_ts = $(list_join LOCAL_PREFIX ,)"
1393 print_indent
4 "local_ts = dynamic"
1397 if isset REMOTE_PREFIX
; then
1398 print_indent
4 "remote_ts = $(list_join REMOTE_PREFIX ,)"
1400 print_indent
4 "remote_ts = dynamic"
1409 print_indent
4 "# Netfilter Marks"
1410 print_indent
4 "mark_in = %unique"
1411 print_indent
4 "mark_out = %unique"
1416 # Dead Peer Detection
1417 if enabled dpd
; then
1418 print_indent
4 "# Dead Peer Detection"
1419 print_indent
4 "dpd_action = ${DPD_ACTION}"
1424 if isset LIFETIME
; then
1425 print_indent
4 "# Rekey Time"
1426 print_indent
4 "rekey_time = ${LIFETIME}"
1431 print_indent
4 "updown = ${NETWORK_HELPERS_DIR}/ipsec-updown"
1435 print_indent
4 "# Mode"
1438 print_indent
4 "mode = transport"
1441 print_indent
4 "mode = tunnel"
1447 print_indent
4 "# Compression"
1448 if enabled COMPRESSION
; then
1449 print_indent
4 "ipcomp = yes"
1451 print_indent
4 "ipcomp = no"
1455 # Inactivity Timeout
1456 if isset INACTIVITY_TIMEOUT
; then
1457 print_indent
4 "# Inactivity Timeout"
1458 print_indent
4 "inactivity = ${INACTIVITY_TIMEOUT}"
1463 print_indent
4 "# Start Action"
1464 case "${START_ACTION}" in
1466 print_indent
4 "start_action = trap"
1467 print_indent
4 "close_action = trap"
1470 print_indent
4 "start_action = none"
1471 print_indent
4 "close_action = none"
1474 print_indent
4 "start_action = start"
1475 print_indent
4 "close_action = start"
1489 _ipsec_connection_to_strongswan_secrets
() {
1490 local connection
="${1}"
1492 print_indent
0 "secrets {"
1494 case "${AUTH_MODE}" in
1496 print_indent
1 "ike {"
1499 print_indent
2 "secret = ${PSK}"
1502 if isset REMOTE_ID
; then
1503 print_indent
2 "id = ${REMOTE_ID}"
1513 # This function writes all values to a via ${pool} specificated VPN IPsec pool configuration file
1514 ipsec_pool_write_config
() {
1519 if ! ipsec_pool_exists
"${pool}"; then
1520 log ERROR
"No such VPN IPsec pool: ${pool}"
1521 return ${EXIT_ERROR}
1524 local path
="${NETWORK_IPSEC_POOLS_DIR}/${pool}/settings"
1526 if ! settings_write
"${path}" ${IPSEC_POOL_CONFIG_SETTINGS}; then
1527 log ERROR
"Could not write configuration settings for VPN IPsec pool ${pool}"
1528 return ${EXIT_ERROR}
1531 if ! ipsec_pool_reload
${pool}; then
1532 log WARNING
"Could not reload IPsec pool ${pool}"
1535 # When we get here the writing of the config file was successful
1539 # This funtion writes the value for one key to a via ${connection} specificated
1540 # VPN IPsec pool configuration file
1541 ipsec_pool_write_config_key
() {
1550 if ! ipsec_pool_exists
"${pool}"; then
1551 log ERROR
"No such VPN IPsec pool: ${pool}"
1552 return ${EXIT_ERROR}
1555 log DEBUG
"Set '${key}' to new value '${value}' in VPN IPsec pool '${pool}'"
1557 local ${IPSEC_POOL_CONFIG_SETTINGS}
1559 # Read the config settings
1560 if ! ipsec_pool_read_config
"${pool}"; then
1561 return ${EXIT_ERROR}
1564 # Set the key to a new value
1565 assign
"${key}" "${value}"
1567 if ! ipsec_pool_write_config
"${pool}"; then
1568 return ${EXIT_ERROR}
1574 # Reads one or more keys out of a settings file or all if no key is provided.
1575 ipsec_pool_read_config
() {
1581 if ! ipsec_pool_exists
"${pool}"; then
1582 log ERROR
"No such VPN IPsec pool : ${pool}"
1583 return ${EXIT_ERROR}
1587 if [ $# -eq 0 ] && [ -n "${IPSEC_POOL_CONFIG_SETTINGS}" ]; then
1588 list_append args
${IPSEC_POOL_CONFIG_SETTINGS}
1593 local path
="${NETWORK_IPSEC_POOLS_DIR}/${pool}/settings"
1595 if ! settings_read
"${path}" ${args}; then
1596 log ERROR
"Could not read settings for VPN IPsec pool ${pool}"
1597 return ${EXIT_ERROR}
1601 # This function checks if a vpn IPsec pool exists
1602 # Returns True when yes and false when not
1603 ipsec_pool_exists
() {
1608 local path
="${NETWORK_IPSEC_POOLS_DIR}/${pool}"
1610 [ -d "${path}" ] && return ${EXIT_TRUE} || return ${EXIT_FALSE}
1613 # This function checks if a VPN IPsec pool name is valid
1614 # Allowed are only A-Za-z0-9
1615 ipsec_pool_check_name() {
1620 # These are special words in strongswan
1621 if isoneof pool dhcp radius; then
1622 return ${EXIT_ERROR}
1625 [[ "${pool}" =~ [^[:alnum:]$] ]]
1629 if [ $# -gt 1 ]; then
1630 error "Too many arguments
"
1631 return ${EXIT_ERROR}
1635 if ! isset pool; then
1636 error "Please provide a pool name
"
1637 return ${EXIT_ERROR}
1640 # Check for duplicates
1641 if ipsec_pool_exists "${pool}"; then
1642 error "The VPN IPsec pool
${pool} already exists
"
1643 return ${EXIT_ERROR}
1646 # Check if the name of the connection is valid
1647 if ipsec_pool_check_name "${pool}"; then
1648 error "'${pool}' contains illegal characters
"
1649 return ${EXIT_ERROR}
1652 log DEBUG "Creating VPN IPsec pool
${pool}"
1654 if ! mkdir -p "${NETWORK_IPSEC_POOLS_DIR}/${pool}"; then
1655 log ERROR "Could not create config directory
for ${pool}"
1656 return ${EXIT_ERROR}
1659 local ${IPSEC_POOL_CONFIG_SETTINGS}
1661 if ! ipsec_pool_write_config "${pool}"; then
1662 log ERROR "Could not
write new config
file"
1663 return ${EXIT_ERROR}
1667 # Function that deletes based on the passed parameters
1668 # one ore more vpn ipsec pools
1669 ipsec_pool_destroy() {
1672 if ! ipsec_pool_exists "${pool}"; then
1673 log ERROR "The VPN IPsec pool
${pool} does not exist.
"
1677 log DEBUG "Deleting VPN IPsec pool
${pool}"
1679 if ! rm -rf "${NETWORK_IPSEC_POOLS_DIR}/${pool}"; then
1680 log ERROR "Deleting the VPN IPsec pool
${pool} was not sucessful
"
1681 return ${EXIT_ERROR}
1686 ipsec_pool_set_type() {
1692 local type=$(ip_detect_protocol ${ip})
1694 if ! isset type; then
1695 error "Cannot detect IP protocol of
${ip}"
1696 return ${EXIT_ERROR}
1698 log DEBUG "IP protocol of
${ip} is
${type}"
1699 if ! ipsec_pool_write_config_key "${pool}" "TYPE
" ${type}; then
1700 log ERROR "Could not
write configuration settings
"
1701 return ${EXIT_ERROR}
1706 ipsec_pool_network() {
1707 if [ ! $# -eq 2 ]; then
1708 log ERROR "Not enough arguments
"
1709 return ${EXIT_ERROR}
1715 if ! ipsec_pool_read_config ${pool} "TYPE
"; then
1716 error "Failed to
read configuration settings
for pool
'${pool}'"
1717 return ${EXIT_ERROR}
1720 if ! isset TYPE; then
1721 if ! ip_net_is_valid ${network}; then
1722 log ERROR "Network
'${network}' is invalid
"
1723 return ${EXIT_ERROR}
1726 if ! ipsec_pool_set_type ${pool} ${network}; then
1727 log ERROR "Could not
set type for IPsec pool
${pool}"
1728 return ${EXIT_ERROR}
1731 if ! ${TYPE}_net_is_valid ${network}; then
1732 log ERROR "Network
'${network}' is invalid
"
1733 return ${EXIT_ERROR}
1737 if ! ipsec_pool_write_config_key "${pool}" "NETWORK
" ${network}; then
1738 log ERROR "Could not
write configuration settings
"
1739 return ${EXIT_ERROR}
1743 ipsec_pool_dns_server() {
1744 if [ ! $# -eq 2 ]; then
1745 log ERROR "Not enough arguments
"
1746 return ${EXIT_ERROR}
1749 local dns_server=${2}
1752 if ! ipsec_pool_read_config ${pool} "TYPE
"; then
1753 error "Failed to
read configuration settings
for pool
'${pool}'"
1754 return ${EXIT_ERROR}
1757 if ! isset TYPE; then
1758 if ! ip_is_valid ${dns_server}; then
1759 log ERROR "DNS server
'${dns_server}' is invalid
"
1760 return ${EXIT_ERROR}
1763 if ! ipsec_pool_set_type ${pool} ${dns_server}; then
1764 log ERROR "Could not
set type for IPsec pool
${pool}"
1765 return ${EXIT_ERROR}
1768 if ! ${TYPE}_is_valid ${dns_server}; then
1769 log ERROR "DNS server
'${dns_server}' is invalid
"
1770 return ${EXIT_ERROR}
1774 if ! ipsec_pool_write_config_key "${pool}" "DNS_SERVER
" ${dns_server}; then
1775 log ERROR "Could not
write configuration settings
"
1776 return ${EXIT_ERROR}
1780 ipsec_pool_check_config() {
1784 local ${IPSEC_POOL_CONFIG_SETTINGS}
1785 if ! ipsec_pool_read_config "${pool}"; then
1786 log ERROR "Could not
read configuration settings
"
1787 return ${EXIT_ERROR}
1790 if ! isset NETWORK; then
1791 log ERROR "Network
for IPSec pool
${pool} is not
set"
1792 return ${EXIT_ERROR}
1795 if ! isset TYPE; then
1796 TYPE=$(ip_detect_protocol ${NETWORK})
1797 log DEBUG "IP protocol of
${NETWORK} is
${TYPE}"
1798 if ! isset TYPE; then
1799 error "Cannot detect IP protocol of
${NETWORK}"
1800 return ${EXIT_ERROR}
1802 if ! ipsec_pool_write_config_key "${pool}" "TYPE
" ${TYPE}; then
1803 log ERROR "Could not
write configuration settings
"
1804 return ${EXIT_ERROR}
1808 if ! ${TYPE}_net_is_valid ${NETWORK}; then
1809 log ERROR "NETWORK
'${NETWORK}' is invalid
"
1810 return ${EXIT_ERROR}
1813 if isset DNS_SERVER && ! ${TYPE}_is_valid ${DNS_SERVER}; then
1814 log ERROR "DNS server
'${DNS_SERVER}' is invalid
"
1815 return ${EXIT_ERROR}
1822 ipsec_pool_reload() {
1825 if ! ipsec_pool_to_strongswan ${pool}; then
1826 log ERROR "Could not generate strongswan config
for ${pool}"
1827 return ${EXIT_ERROR}
1830 ipsec_strongswan_load
1833 ipsec_pool_to_strongswan() {
1836 log DEBUG "Generating IPsec pool config
for ${pool}"
1838 local ${IPSEC_POOL_CONFIG_SETTINGS}
1839 if ! ipsec_pool_read_config "${pool}"; then
1840 return ${EXIT_ERROR}
1843 if isset NETWORK && ! ipsec_pool_check_config "${pool}"; then
1844 log ERROR "Configuration of
${pool} seems to be invalid
"
1845 return ${EXIT_ERROR}
1848 local path="${NETWORK_IPSEC_SWANCTL_POOLS_DIR}/${pool}.conf
"
1851 config_header "strongSwan pool configuration
"
1853 if isset NETWORK; then
1854 print_indent 0 "pools
{"
1856 print_indent 1 "${pool} {"
1857 print_indent 2 "addrs
= ${NETWORK}"
1859 if isset DNS_SERVER; then
1860 print_indent 2 "dns
= ${DNS_SERVER}"