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
="\
44 IPSEC_DEFAULT_AUTH_MODE
="PSK"
45 IPSEC_DEFAULT_DPD_ACTION
="restart"
46 IPSEC_DEFAULT_DPD_DELAY
="30"
47 IPSEC_DEFAULT_DPD_TIMEOUT
="120"
48 IPSEC_DEFAULT_ENABLED
="true"
49 IPSEC_DEFAULT_INACTIVITY_TIMEOUT
="0"
50 IPSEC_DEFAULT_MODE
="tunnel"
51 IPSEC_DEFAULT_SECURITY_POLICY
="system"
52 IPSEC_DEFAULT_START_ACTION
="on-demand"
53 IPSEC_DEFAULT_TYPE
="net-to-net"
55 IPSEC_VALID_MODES
="gre-transport tunnel vti"
56 IPSEC_VALID_AUTH_MODES
="PSK"
64 cli_ipsec_connection
"$@"
70 error
"Unrecognized argument: ${action}"
76 cli_ipsec_connection
() {
77 if ipsec_connection_exists
${1}; then
84 authentication|down|disable|dpd|
enable|inactivity_timeout|
local|mode|peer|pool|remote|security_policy|start_action|up|zone
)
85 ipsec_connection_
${key} ${connection} "$@"
88 color_cli
"ipsec-connection" "${connection}" "$@"
91 description_cli
"ipsec-connection" ${connection} $@
94 cli_ipsec_connection_show
"${connection}"
98 error
"Unrecognized argument: ${key}"
108 ipsec_connection_new
"$@"
111 cli_ipsec_connection_destroy
"$@"
114 if [ -n "${action}" ]; then
115 error
"Unrecognized argument: '${action}'"
123 cli_ipsec_connection_destroy
() {
124 local connection
="${1}"
126 if ! ipsec_connection_destroy
"${connection}"; then
130 # Inform strongswan about the changes
131 ipsec_strongswan_load
133 # Configure strongswan autostart
134 ipsec_strongswan_autostart
137 ipsec_connection_get_color
() {
138 # This function return the color of a zone
142 color_read
"ipsec-connection" ${name}
145 ipsec_connection_get_description_title
() {
149 description_title_read $
(description_format_filename
"ipsec-connection" "${name}")
152 cli_ipsec_connection_show
() {
153 local connection
="${1}"
155 # Read the config settings
156 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
157 if ! ipsec_connection_read_config
"${connection}"; then
158 error
"Could not read the connection configuration"
162 cli_headline
0 "IPsec VPN Connection: ${connection}"
165 cli_print_fmt1
1 "Color" "$(cli_color_bar $(ipsec_connection_get_color ${connection}))"
166 cli_print_fmt1
1 "Description" "$(ipsec_connection_get_description_title ${connection})"
171 cli_print_fmt1
1 "Peer" "${PEER}"
175 cli_print_fmt1
1 "Security Policy" "${SECURITY_POLICY-${IPSEC_DEFAULT_SECURITY_POLICY}}"
178 cli_headline
2 "Authentication"
179 case "${AUTH_MODE^^}" in
181 cli_print_fmt1
2 "Mode" "Pre-Shared-Key"
184 cli_print_fmt1
2 "Pre-Shared-Key" "****"
186 cli_print_fmt1
2 "Pre-Shared-Key" "- is not set -"
196 for i
in LOCAL REMOTE
; do
199 cli_headline
2 "Local"
202 cli_headline
2 "Remote"
206 local id_var
="${i}_ID"
207 if [ -n "${!id_var}" ]; then
208 cli_print_fmt1
2 "ID" "${!id_var}"
211 local prefix_var
="${i}_PREFIX"
212 if isset
${prefix_var}; then
213 cli_headline
3 "Prefix(es)"
216 for prefix
in ${!prefix_var}; do
217 cli_print_fmt1
3 "${prefix}"
224 cli_headline
2 "Misc."
228 cli_print_fmt1
2 "Transport Mode" "GRE Transport"
231 cli_print_fmt1
2 "Transport Mode" "Tunnel"
234 cli_print_fmt1
2 "Transport Mode" "Virtual Tunnel Interface"
237 cli_print_fmt1
2 "Transport Mode" "- Unknown -"
242 if isset INACTIVITY_TIMEOUT
&& [ ${INACTIVITY_TIMEOUT} -gt 0 ]; then
243 cli_print_fmt1
2 "Inactivity Timeout" "$(format_time ${INACTIVITY_TIMEOUT})"
250 ipsec_connection_disable
() {
251 local connection
=${1}
253 if ! ipsec_connection_write_config_key
"${connection}" "ENABLED" "false"; then
254 log ERROR
"Could not write configuration settings"
258 # Configure strongswan autostart
259 ipsec_strongswan_autostart
262 ipsec_connection_enable
() {
263 local connection
=${1}
265 if ! ipsec_connection_write_config_key
"${connection}" "ENABLED" "true"; then
266 log ERROR
"Could not write configuration settings"
270 # Configure strongswan autostart
271 ipsec_strongswan_autostart
274 # This function writes all values to a via ${connection} specificated VPN IPsec configuration file
275 ipsec_connection_write_config
() {
278 local connection
="${1}"
280 if ! ipsec_connection_exists
"${connection}"; then
281 log ERROR
"No such VPN IPsec connection: ${connection}"
285 local path
="${NETWORK_IPSEC_CONNS_DIR}/${connection}/settings"
287 if ! settings_write
"${path}" ${IPSEC_CONNECTION_CONFIG_SETTINGS}; then
288 log ERROR
"Could not write configuration settings for VPN IPsec connection ${connection}"
292 ipsec_reload
${connection}
295 # This funtion writes the value for one key to a via ${connection} specificated VPN IPsec connection configuration file
296 ipsec_connection_write_config_key
() {
299 local connection
=${1}
305 if ! ipsec_connection_exists
"${connection}"; then
306 log ERROR
"No such VPN ipsec connection: ${connection}"
310 log DEBUG
"Set '${key}' to new value '${value}' in VPN ipsec connection '${connection}'"
312 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
314 # Read the config settings
315 if ! ipsec_connection_read_config
"${connection}"; then
319 # Set the key to a new value
320 assign
"${key}" "${value}"
322 if ! ipsec_connection_write_config
"${connection}"; then
329 # Reads one or more keys out of a settings file or all if no key is provided.
330 ipsec_connection_read_config
() {
333 local connection
="${1}"
336 if ! ipsec_connection_exists
"${connection}"; then
337 log ERROR
"No such VPN IPsec connection : ${connection}"
343 if [ $# -eq 0 ] && [ -n "${IPSEC_CONNECTION_CONFIG_SETTINGS}" ]; then
344 list_append args
${IPSEC_CONNECTION_CONFIG_SETTINGS}
346 list_append args
"$@"
349 local path
="${NETWORK_IPSEC_CONNS_DIR}/${connection}/settings"
351 if ! settings_read
"${path}" ${args}; then
352 log ERROR
"Could not read settings for VPN IPsec connection ${connection}"
357 # This function checks if a vpn ipsec connection exists
358 # Returns True when yes and false when not
359 ipsec_connection_exists
() {
362 local connection
=${1}
364 local path
="${NETWORK_IPSEC_CONNS_DIR}/${connection}"
366 [ -d "${path}" ] && return ${EXIT_TRUE} || return ${EXIT_FALSE}
369 # Determines if strongswan should be automatically started
370 # when the system boots up.
371 ipsec_strongswan_autostart() {
372 local autostart_needed="false
"
375 for connection in $(ipsec_list_connections); do
378 if ! ipsec_connection_read_config "${connection}" "ENABLED
"; then
379 log WARNING "Could not
read configuation
"
383 if enabled ENABLED; then
384 autostart_needed="true
"
389 # Start strongswan when we need it and when it is not yet enabled
390 if ${autostart_needed}; then
391 if ! service_is_enabled "strongswan
"; then
392 service_enable "strongswan
"
395 if ! service_is_active "strongswan
"; then
396 service_start "strongswan
"
399 # Disable strongswan when we do not need it but it is enabled
400 elif ! ${autostart_needed}; then
401 if service_is_enabled "strongswan
"; then
402 service_disable "strongswan
"
405 if service_is_active "strongswan
"; then
406 service_stop "strongswan
"
411 ipsec_strongswan_load() {
412 # Do nothing if strongswan is not running
413 if ! service_is_active "strongswan
"; then
417 if ! cmd swanctl --load-all; then
418 log ERROR "Could not reload strongswan config
"
423 # Reloads the connection after config changes
425 local connection=${1}
429 if ! ipsec_connection_read_config "${connection}" "ENABLED
"; then
430 log ERROR "Could not
read configuration
for IPsec connection
${connection}"
434 if enabled ENABLED; then
435 if ! ipsec_connection_to_strongswan ${connection}; then
436 log ERROR "Could not generate strongswan config
for ${connnection}"
440 log DEBUG "Deleting strongswan config
${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
"
441 unlink "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
"
444 ipsec_strongswan_load
447 # Handle the cli after authentification
448 ipsec_connection_authentication() {
449 if [ ! $# -gt 1 ]; then
450 log ERROR "Not enough arguments
"
454 local connection=${1}
460 ipsec_connection_authentication_mode "${connection}" "$@
"
463 ipsec_connection_authentication_psk "${connection}" "$@
"
466 log ERROR "Unrecognized argument
: ${cmd}"
472 # Set the authentification mode
473 ipsec_connection_authentication_mode() {
474 if [ ! $# -eq 2 ]; then
475 log ERROR "Not enough arguments
"
478 local connection=${1}
481 if ! isoneof mode ${IPSEC_VALID_AUTH_MODES}; then
482 log ERROR "Auth mode
'${mode}' is invalid
"
486 if ! ipsec_connection_write_config_key "${connection}" "AUTH_MODE
" ${mode^^}; then
487 log ERROR "Could not
write configuration settings
"
493 ipsec_connection_authentication_psk() {
494 if [ ! $# -eq 2 ]; then
495 log ERROR "Not enough arguments
"
499 local connection=${1}
504 if [ ${length} -lt 4 ]; then
505 error "The PSK must be longer than four characters
"
509 if [ ${length} -gt 128 ]; then
510 error "The PSK cannot be longer than
128 characters
"
514 if ! ipsec_connection_write_config_key "${connection}" "PSK
" "${psk}"; then
515 log ERROR "Could not
write configuration settings
"
522 ipsec_connection_up() {
523 local connection="${1}"
525 if ! ipsec_connection_exists "${connection}"; then
526 error "No such VPN IPsec connection
: ${connection}"
530 if ! [ -f "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
" ]; then
531 log DEBUG "Could not
find a swanctl config
, generating swanctl config
"
532 ipsec_connection_to_strongswan "${connection}"
533 ipsec_strongswan_load
536 cmd swanctl --initiate --child "${connection}"
539 ipsec_connection_down() {
540 local connection="${1}"
542 if ! ipsec_connection_exists "${connection}"; then
543 error "No such VPN IPsec connection
: ${connection}"
547 cmd swanctl --terminate --ike "${connection}"
550 # Handle the cli after authentification
551 ipsec_connection_dpd() {
552 if [ ! $# -gt 1 ]; then
553 log ERROR "Not enough arguments
"
557 local connection=${1}
563 ipsec_connection_dpd_action "${connection}" "$@
"
566 ipsec_connection_dpd_delay "${connection}" "$@
"
569 ipsec_connection_dpd_timeout "${connection}" "$@
"
572 log ERROR "Unrecognized argument
: ${cmd}"
578 # Set the default dpd action
579 ipsec_connection_dpd_action() {
580 if [ ! $# -eq 2 ]; then
581 log ERROR "Not enough arguments
"
584 local connection=${1}
587 if ! isoneof action "restart
" "clear"; then
588 log ERROR "dpd action
'${action}' is invalid
"
592 if ! ipsec_connection_write_config_key "${connection}" "DPD_ACTION
" ${action}; then
593 log ERROR "Could not
write configuration settings
"
599 ipsec_connection_dpd_delay() {
600 if [ ! $# -ge 2 ]; then
601 log ERROR "Not enough arguments
"
605 local connection=${1}
609 if ! isinteger value; then
610 value=$(parse_time "$@
")
611 if [ ! $? -eq 0 ]; then
612 log ERROR "Parsing the passed
time was not sucessful please check the passed values.
"
617 if [ ${value} -lt 0 ]; then
618 log ERROR "The passed
time value must be
in the
sum greater or equal zero seconds.
"
622 if ! ipsec_connection_write_config_key "${connection}" "DPD_DELAY
" ${value}; then
623 log ERROR "Could not
write configuration settings
"
630 # Set the dpd timeout
631 ipsec_connection_dpd_timeout() {
632 if [ ! $# -ge 2 ]; then
633 log ERROR "Not enough arguments
"
637 local connection=${1}
641 if ! isinteger value; then
642 value=$(parse_time "$@
")
643 if [ ! $? -eq 0 ]; then
644 log ERROR "Parsing the passed
time was not sucessful please check the passed values.
"
649 if [ ${value} -le 0 ]; then
650 log ERROR "The passed
time value must be
in the
sum greater or equal zero seconds.
"
654 if ! ipsec_connection_write_config_key "${connection}" "DPD_TIMEOUT
" ${value}; then
655 log ERROR "Could not
write configuration settings
"
662 # Handle the cli after local
663 ipsec_connection_local() {
664 if [ ! $# -ge 2 ]; then
665 log ERROR "Not enough arguments
"
669 local connection=${1}
675 ipsec_connection_local_address "${connection}" "$@
"
678 ipsec_connection_id "${connection}" "LOCAL
" "$@
"
681 ipsec_connection_prefix "${connection}" "LOCAL
" "$@
"
684 log ERROR "Unrecognized argument
: ${cmd}"
692 # Set the connection mode
693 ipsec_connection_mode() {
694 if [ ! $# -eq 2 ]; then
695 log ERROR "Not enough arguments
"
698 local connection=${1}
701 if ! isoneof mode ${IPSEC_VALID_MODES}; then
702 log ERROR "Mode
'${mode}' is invalid
"
706 if ! ipsec_connection_write_config_key "${connection}" "MODE
" ${mode}; then
707 log ERROR "Could not
write configuration settings
"
714 ipsec_connection_zone() {
715 local connection="${1}"
719 # Check if we got an argument
720 if ! isset zone; then
721 error "Zone is not
set"
728 if ! ipsec_connection_read_config "${connection}" "ZONE
"; then
729 log ERROR "Could not
read configuration
for IPsec connection
${connection}"
733 # Removes zone setting
737 log INFO "Removing zone
${ZONE} from IPsec connection
'${connection}'"
742 # Check if the zone exists
743 if ! zone_exists "${zone}"; then
744 error "Zone
${zone} does not exist
"
748 # Zone must be of type tunnel
749 local hook="$
(zone_get_hook
"${zone}")"
753 # We support ip-tunnels
757 error "Zones of
type ${hook} are not supported
"
762 # Check if this zone is alreadz attached to another IPsec connection
765 log INFO "Adding zone
${zone} to IPsec connection
'${connection}'"
770 if ! ipsec_connection_write_config_key "${connection}" "ZONE
" "${zone}"; then
771 error "Could not
write configuration settings
"
778 # Set the local address
779 ipsec_connection_local_address() {
780 if [ ! $# -eq 2 ]; then
781 log ERROR "Not enough arguments
"
784 local connection=${1}
785 local local_address=${2}
787 if ! ipsec_connection_check_peer ${local_address}; then
788 log ERROR "Local address
'${local_address}' is invalid
"
792 if ! ipsec_connection_write_config_key "${connection}" "LOCAL_ADDRESS
" ${local_address}; then
793 log ERROR "Could not
write configuration settings
"
800 # Set the peer to connect to
801 ipsec_connection_peer() {
802 if [ ! $# -eq 2 ]; then
803 log ERROR "Not enough arguments
"
806 local connection=${1}
809 if ! ipsec_connection_check_peer ${peer}; then
810 log ERROR "Peer
'${peer}' is invalid
"
814 if ! ipsec_connection_write_config_key "${connection}" "PEER
" ${peer}; then
815 log ERROR "Could not
write configuration settings
"
822 #Set the local or remote id
823 ipsec_connection_id() {
824 if [ ! $# -eq 3 ]; then
825 log ERROR "Not enough arguments
"
828 local connection=${1}
832 if ! ipsec_connection_check_id ${id}; then
833 log ERROR "Id
'${id}' is invalid
"
837 if ! ipsec_connection_write_config_key "${connection}" "${type}_ID" ${id}; then
838 log ERROR
"Could not write configuration settings"
845 # Set the local or remote prefix
846 ipsec_connection_prefix
() {
847 if [ ! $# -ge 3 ]; then
848 log ERROR
"Not enough arguments"
851 local connection
=${1}
855 local _prefix
="${type}_PREFIX"
857 if ! ipsec_connection_read_config
"${connection}" "${_prefix}"; then
861 # Remove duplicated entries to proceed the list safely
862 assign
"${_prefix}" "$(list_unique ${!_prefix} )"
865 local prefixes_removed
868 while [ $# -gt 0 ]; do
873 list_append prefixes_added
"${arg:1}"
876 list_append prefixes_removed
"${arg:1}"
879 list_append prefixes_set
"${arg}"
882 error
"Invalid argument: ${arg}"
889 # Check if the user is trying a mixed operation
890 if ! list_is_empty prefixes_set
&& (! list_is_empty prefixes_added ||
! list_is_empty prefixes_removed
); then
891 error
"You cannot reset the prefix list and add or remove prefixes at the same time"
895 # Set new prefix list
896 if ! list_is_empty prefixes_set
; then
897 # Check if all prefixes are valid
899 for prefix
in ${prefixes_set}; do
900 if ! ip_net_is_valid
${prefix}; then
901 error
"Unsupported prefix: ${prefix}"
906 assign
"${_prefix}" "${prefixes_set}"
908 # Perform incremental updates
912 # Perform all removals
913 for prefix
in ${prefixes_removed}; do
914 if ! list_remove
"${_prefix}" ${prefix}; then
915 warning
"${prefix} was not on the list and could not be removed"
920 for prefix
in ${prefixes_added}; do
921 if ip_net_is_valid
${prefix}; then
922 if ! list_append_unique
"${_prefix}" ${prefix}; then
923 warning
"${prefix} is already on the prefix list"
926 warning
"${prefix} is not a valid IP network and could not be added"
931 # Check if the list contain at least one valid prefix
932 if list_is_empty
${_prefix}; then
933 error
"Cannot save an empty prefix list"
938 if ! ipsec_connection_write_config_key
"${connection}" "${_prefix}" ${!_prefix}; then
939 log ERROR "Could not
write configuration settings
"
945 # Set the pools to use
946 ipsec_connection_pool() {
947 if [ ! $# -ge 2 ]; then
948 log ERROR "Not enough arguments
"
951 local connection=${1}
955 if ! ipsec_connection_read_config "${connection}" "POOLS
"; then
959 # Remove duplicated entries to proceed the list safely
960 assign "POOLS
" "$
(list_unique
${POOLS})"
966 while [ $# -gt 0 ]; do
971 list_append pools_added "${arg:1}"
974 list_append pools_removed "${arg:1}"
977 list_append pools_set "${arg}"
980 error "Invalid argument
: ${arg}"
987 # Check if the user is trying a mixed operation
988 if ! list_is_empty pools_set && (! list_is_empty pools_added || ! list_is_empty pools_removed); then
989 error "You cannot
reset the pools list and add or remove pools
at the same
time"
994 if ! list_is_empty pools_set; then
995 # Check if all pools are valid
997 for pool in ${pools_set}; do
998 if ! ipsec_pool_exists ${pool} || ! ipsec_pool_check_config ${pool}; then
999 error "Pool
${pool} is not valid
"
1000 return ${EXIT_ERROR}
1004 assign "POOLS
" "${pools_set}"
1006 # Perform incremental updates
1010 # Perform all removals
1011 for pool in ${pools_removed}; do
1012 if ! list_remove "POOLS
" ${pool}; then
1013 warning "${pool} was not on the list and could not be removed
"
1018 for pool in ${pools_added}; do
1019 if ipsec_pool_exists ${pool} && ipsec_pool_check_config ${pool}; then
1020 if ! list_append_unique "POOLS
" ${pool}; then
1021 warning "${pool} is already on the prefix list
"
1024 warning "${pool} is not a valid pool
"
1029 # Check if the list contain at least one valid pool
1030 if list_is_empty POOLS; then
1031 error "Cannot save an empty pool list
"
1032 return ${EXIT_ERROR}
1036 if ! ipsec_connection_write_config_key "${connection}" "POOLS
" ${POOLS}; then
1037 log ERROR "Could not
write configuration settings
"
1043 # Handle the cli after remote
1044 ipsec_connection_remote() {
1045 if [ ! $# -ge 2 ]; then
1046 log ERROR "Not enough arguments
"
1047 return ${EXIT_ERROR}
1050 local connection=${1}
1056 ipsec_connection_id "${connection}" "REMOTE
" "$@
"
1060 ipsec_connection_prefix "${connection}" "REMOTE
" "$@
"
1063 log ERROR "Unrecognized argument
: ${cmd}"
1064 return ${EXIT_ERROR}
1071 # Set the inactivity timeout
1072 ipsec_connection_inactivity_timeout() {
1073 if [ ! $# -ge 2 ]; then
1074 log ERROR "Not enough arguments
"
1075 return ${EXIT_ERROR}
1078 local connection=${1}
1082 if ! isinteger value; then
1083 value=$(parse_time "$@
")
1084 if [ ! $? -eq 0 ]; then
1085 log ERROR "Parsing the passed
time was not sucessful please check the passed values.
"
1086 return ${EXIT_ERROR}
1090 if [ ${value} -le 0 ]; then
1091 log ERROR "The passed
time value must be
in the
sum greater zero seconds.
"
1092 return ${EXIT_ERROR}
1095 if ! ipsec_connection_write_config_key "${connection}" "INACTIVITY_TIMEOUT
" ${value}; then
1096 log ERROR "Could not
write configuration settings
"
1097 return ${EXIT_ERROR}
1103 # Set the default start action
1104 ipsec_connection_start_action() {
1105 if [ ! $# -eq 2 ]; then
1106 log ERROR "Not enough arguments
"
1107 return ${EXIT_ERROR}
1109 local connection=${1}
1112 if ! isoneof action "on-demand
" "always-on
"; then
1113 log ERROR "Start action
'${action}' is invalid
"
1114 return ${EXIT_ERROR}
1117 if ! ipsec_connection_write_config_key "${connection}" "START_ACTION
" ${action}; then
1118 log ERROR "Could not
write configuration settings
"
1119 return ${EXIT_ERROR}
1123 # Set the security policy to use
1124 ipsec_connection_security_policy() {
1125 if [ ! $# -eq 2 ]; then
1126 log ERROR "Not enough arguments
"
1127 return ${EXIT_ERROR}
1129 local connection=${1}
1130 local security_policy=${2}
1132 if ! vpn_security_policy_exists ${security_policy}; then
1133 log ERROR "No such vpn security policy
'${security_policy}'"
1134 return ${EXIT_ERROR}
1137 if ! ipsec_connection_write_config_key "${connection}" "SECURITY_POLICY
" ${security_policy}; then
1138 log ERROR "Could not
write configuration settings
"
1139 return ${EXIT_ERROR}
1143 # Check if a id is valid
1144 ipsec_connection_check_id() {
1148 if [[ ${id} =~ ^@[[:alnum:]]+$ ]] || ip_is_valid ${id}; then
1151 return ${EXIT_FALSE}
1155 # Checks if a peer is valid
1156 ipsec_connection_check_peer() {
1160 # IP addresses are accepted
1161 if ip_is_valid ${peer}; then
1165 # FQDNs are okay, too
1166 if fqdn_is_valid "${peer}"; then
1170 # We cannot use anything else
1171 return ${EXIT_FALSE}
1174 # This function checks if a VPN IPsec connection name is valid
1175 # Allowed are only A-Za-z0-9
1176 ipsec_connection_check_name() {
1179 local connection=${1}
1181 [[ "${connection}" =~ [^[:alnum:]$] ]]
1184 # Function that creates one VPN IPsec connection
1185 ipsec_connection_new() {
1186 if [ $# -gt 2 ]; then
1187 error "Too many arguments
"
1188 return ${EXIT_ERROR}
1191 local connection="${1}"
1194 if ! isset connection; then
1195 error "Please provide a connection name
"
1196 return ${EXIT_ERROR}
1199 # Check for duplicates
1200 if ipsec_connection_exists "${connection}"; then
1201 error "The VPN IPsec connection
${connection} already exists
"
1202 return ${EXIT_ERROR}
1205 # Check if the name of the connection is valid
1206 if ipsec_connection_check_name "${connection}"; then
1207 error "'${connection}' contains illegal characters
"
1208 return ${EXIT_ERROR}
1211 # Set TYPE to default if not set by the user
1212 if ! isset type; then
1213 type="${IPSEC_DEFAULT_TYPE}"
1216 if ! isoneof "type" "net-to-net
" "host-to-net
"; then
1217 error "Type is invalid
"
1218 return ${EXIT_ERROR}
1221 log DEBUG "Creating VPN IPsec connection
${connection}"
1223 if ! mkdir -p "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
1224 log ERROR "Could not create config directory
for ${connection}"
1225 return ${EXIT_ERROR}
1228 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
1230 AUTH_MODE=${IPSEC_DEFAULT_AUTH_MODE}
1231 DPD_ACTION=${IPSEC_DEFAULT_DPD_ACTION}
1232 DPD_DELAY=${IPSEC_DEFAULT_DPD_DELAY}
1233 DPD_TIMEOUT=${IPSEC_DEFAULT_DPD_TIMEOUT}
1234 ENABLED=${IPSEC_DEFAULT_ENABLED}
1235 MODE=${IPSEC_DEFAULT_MODE}
1236 START_ACTION=${IPSEC_DEFAULT_START_ACTION}
1239 INACTIVITY_TIMEOUT=${IPSEC_DEFAULT_INACTIVITY_TIMEOUT}
1240 SECURITY_POLICY=${IPSEC_DEFAULT_SECURITY_POLICY}
1242 if ! ipsec_connection_write_config "${connection}"; then
1243 log ERROR "Could not
write new config
file"
1244 return ${EXIT_ERROR}
1247 # Configure strongswan autostart
1248 ipsec_strongswan_autostart
1251 # Function that deletes based on the passed parameters one ore more vpn security policies
1252 ipsec_connection_destroy() {
1254 for connection in "$@
"; do
1255 if ! ipsec_connection_exists "${connection}"; then
1256 log ERROR "The VPN IPsec connection
${connection} does not exist.
"
1260 log DEBUG "Deleting VPN IPsec connection
${connection}"
1262 # Delete strongswan configuration file
1263 file_delete "${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
"
1265 if ! rm -rf "${NETWORK_IPSEC_CONNS_DIR}/${connection}"; then
1266 log ERROR "Deleting the VPN IPsec connection
${connection} was not sucessful
"
1267 return ${EXIT_ERROR}
1273 # List all ipsec connections
1274 ipsec_list_connections() {
1275 list_directory "${NETWORK_IPSEC_CONNS_DIR}"
1278 ipsec_connection_to_strongswan() {
1279 local connection="${1}"
1280 log DEBUG "Generating IPsec configuration
for ${connection}"
1282 # Read the config settings
1283 local ${IPSEC_CONNECTION_CONFIG_SETTINGS}
1284 if ! ipsec_connection_read_config "${connection}"; then
1285 error "Could not
read the connection
${connection}"
1286 return ${EXIT_ERROR}
1289 local path="${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf
"
1292 # Write the connection section
1293 _ipsec_connection_to_strongswan_connection "${connection}"
1295 # Write the secrets section
1296 _ipsec_connection_to_strongswan_secrets "${connection}"
1301 _ipsec_connection_to_strongswan_connection() {
1302 local connection="${1}"
1304 # Read the security policy
1305 local ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS}
1306 if ! vpn_security_policies_read_config "${SECURITY_POLICY}"; then
1307 return ${EXIT_ERROR}
1312 if isset DPD_DELAY && isinteger DPD_DELAY && [ ${DPD_DELAY} -gt 0 ]; then
1316 # Write configuration header
1317 config_header "strongSwan configuration
for ${connection}"
1319 print_indent 0 "connections
{"
1320 print_indent 1 "${connection} {"
1323 print_indent 2 "# IKE Version"
1324 case "${KEY_EXCHANGE^^}" in
1326 print_indent
2 "version = 1"
1329 # Fall back to IKEv2 for any random values
1331 print_indent
2 "version = 2"
1336 # Always only keep one connection open at a time
1337 print_indent
2 "# Unique IDs"
1338 print_indent
2 "unique = replace"
1342 print_indent
2 "# Local Address"
1343 if isset LOCAL_ADDRESS
; then
1344 print_indent
2 "local_addrs = ${LOCAL_ADDRESS}"
1346 print_indent
2 "local_addrs = %any"
1351 print_indent
2 "# Remote Address"
1353 print_indent
2 "remote_addrs = ${PEER}"
1355 print_indent
2 "remote_addrs = %any"
1360 print_indent
2 "# IKE Proposals"
1361 print_indent
2 "proposals = $(vpn_security_policies_make_ike_proposal ${SECURITY_POLICY})"
1365 if enabled dpd
; then
1366 print_indent
2 "# Dead Peer Detection"
1367 print_indent
2 "dpd_delay = ${DPD_DELAY}"
1369 if isset DPD_TIMEOUT
; then
1370 print_indent
2 "dpd_timeout = ${DPD_TIMEOUT}"
1377 print_indent
2 "# Fragmentation"
1378 print_indent
2 "fragmentation = yes"
1382 # Host-to-Net specific settings
1386 if isset POOLS
; then
1387 print_indent
2 "# Pools"
1388 print_indent
2 "pools = $(list_join POOLS ", ")"
1395 print_indent
2 "local {"
1398 if isset LOCAL_ID
; then
1399 print_indent
3 "id = ${LOCAL_ID}"
1403 case "${AUTH_MODE}" in
1405 print_indent
3 "auth = psk"
1413 print_indent
2 "remote {"
1416 if isset REMOTE_ID
; then
1417 print_indent
3 "id = ${REMOTE_ID}"
1421 case "${AUTH_MODE}" in
1423 print_indent
3 "auth = psk"
1432 print_indent
2 "children {"
1433 print_indent
3 "${connection} {"
1435 print_indent
4 "# ESP Proposals"
1436 print_indent
4 "esp_proposals = $(vpn_security_policies_make_esp_proposal ${SECURITY_POLICY})"
1443 print_indent
4 "local_ts = dynamic[gre]"
1444 print_indent
4 "remote_ts = dynamic[gre]"
1448 if isset LOCAL_PREFIX
; then
1449 print_indent
4 "local_ts = $(list_join LOCAL_PREFIX ,)"
1451 print_indent
4 "local_ts = dynamic"
1455 if isset REMOTE_PREFIX
; then
1456 print_indent
4 "remote_ts = $(list_join REMOTE_PREFIX ,)"
1458 print_indent
4 "remote_ts = dynamic"
1467 print_indent
4 "# Netfilter Marks"
1468 print_indent
4 "mark_in = %unique"
1469 print_indent
4 "mark_out = %unique"
1474 # Dead Peer Detection
1475 if enabled dpd
; then
1476 print_indent
4 "# Dead Peer Detection"
1477 print_indent
4 "dpd_action = ${DPD_ACTION}"
1482 if isset LIFETIME
; then
1483 print_indent
4 "# Rekey Time"
1484 print_indent
4 "rekey_time = ${LIFETIME}"
1489 print_indent
4 "updown = ${NETWORK_HELPERS_DIR}/ipsec-updown"
1493 print_indent
4 "# Mode"
1496 print_indent
4 "mode = transport"
1499 print_indent
4 "mode = tunnel"
1505 print_indent
4 "# Compression"
1506 if enabled COMPRESSION
; then
1507 print_indent
4 "ipcomp = yes"
1509 print_indent
4 "ipcomp = no"
1513 # Inactivity Timeout
1514 if isset INACTIVITY_TIMEOUT
; then
1515 print_indent
4 "# Inactivity Timeout"
1516 print_indent
4 "inactivity = ${INACTIVITY_TIMEOUT}"
1520 # Net-to-Net specific settings
1524 print_indent
4 "# Start Action"
1525 case "${START_ACTION}" in
1527 print_indent
4 "start_action = trap"
1528 print_indent
4 "close_action = trap"
1531 print_indent
4 "start_action = none"
1532 print_indent
4 "close_action = none"
1535 print_indent
4 "start_action = start"
1536 print_indent
4 "close_action = start"
1552 _ipsec_connection_to_strongswan_secrets
() {
1553 local connection
="${1}"
1555 print_indent
0 "secrets {"
1557 case "${AUTH_MODE}" in
1559 print_indent
1 "ike {"
1562 print_indent
2 "secret = ${PSK}"
1565 if isset REMOTE_ID
; then
1566 print_indent
2 "id = ${REMOTE_ID}"