From: Michael Tremer Date: Thu, 3 Aug 2017 14:53:03 +0000 (+0000) Subject: ipsec: Write functions to generate strongSwan configuration X-Git-Url: http://git.ipfire.org/?p=people%2Fstevee%2Fnetwork.git;a=commitdiff_plain;h=67baa452212c95f9f6bda7e73ef950d7769e5497 ipsec: Write functions to generate strongSwan configuration Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 6ac11873..ce9b9e2a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -179,6 +179,7 @@ dist_helpers_SCRIPTS = \ src/helpers/dhcpd-config-helper \ src/helpers/firewall-kernel-init \ src/helpers/hostapd-config-helper \ + src/helpers/ipsec-updown \ src/helpers/pppd-angel \ src/helpers/wpa_supplicant \ src/helpers/wpa_supplicant-config-helper diff --git a/src/functions/functions.constants b/src/functions/functions.constants index aa7c3eba..c56b1be6 100644 --- a/src/functions/functions.constants +++ b/src/functions/functions.constants @@ -34,10 +34,12 @@ NETWORK_CONFIG_DIR="/etc/network" NETWORK_DB_DIR="${RUN_DIR}/db" NETWORK_ZONE_DIR="${NETWORK_CONFIG_DIR}" NETWORK_HOOKS_DIR=/usr/lib/network/hooks +NETWORK_HELPERS_DIR=/usr/lib/network/helpers NETWORK_TRIGGERS_DIR=/usr/lib/network/triggers NETWORK_SHARE_DIR=/usr/share/network NETWORK_IPSEC_CONNS_DIR="${NETWORK_CONFIG_DIR}/vpn/ipsec/connections" +NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR="/etc/swanctl/connections" # Network file configuration. NETWORK_SETTINGS_FILE=${NETWORK_CONFIG_DIR}/config diff --git a/src/functions/functions.ipsec b/src/functions/functions.ipsec index b91381f6..f92f72ba 100644 --- a/src/functions/functions.ipsec +++ b/src/functions/functions.ipsec @@ -738,3 +738,212 @@ ipsec_list_connections() { basename ${connection} done } + +ipsec_connection_to_strongswan() { + local connection="${1}" + + # Read the config settings + local ${IPSEC_CONNECTION_CONFIG_SETTINGS} + if ! ipsec_connection_read_config "${connection}"; then + error "Could not read the connection ${connection}" + return ${EXIT_ERROR} + fi + + local path="${NETWORK_IPSEC_SWANCTL_CONNECTIONS_DIR}/${connection}.conf" + + ( + # Write the connection section + _ipsec_connection_to_strongswan_connection "${connection}" + + # Write the secrets section + _ipsec_connection_to_strongswan_secrets "${connection}" + + ) > ${path} +} + +_ipsec_connection_to_strongswan_connection() { + local connection="${1}" + + # Read the security policy + local ${VPN_SECURITY_POLICIES_CONFIG_SETTINGS} + if ! vpn_security_policies_read_config "${SECURITY_POLICY}"; then + return ${EXIT_ERROR} + fi + + print_indent 0 "connections {" + print_indent 1 "${connection} {" + + # IKE Version + print_indent 2 "# IKE Version" + case "${KEY_EXCHANGE^^}" in + IKEV1) + print_indent 2 "version = 1" + ;; + + # Fall back to IKEv2 for any random values + IKEV2|*) + print_indent 2 "version = 2" + ;; + esac + print # empty line + + # XXX Local Address + + # Remote Address + print_indent 2 "# Remote Address" + if isset PEER; then + print_indent 2 "remote_addrs = ${PEER}" + else + print_indent 2 "remote_addrs = %any" + fi + print + + # IKE Proposals + print_indent 2 "# IKE Proposals" + print_indent 2 "proposals = $(vpn_security_policies_make_ah_proposal ${SECURITY_POLICY})" + print + + # XXX DPD Settings + + # Fragmentation + print_indent 2 "# Fragmentation" + print_indent 2 "fragmentation = yes" + print + + # Local + print_indent 2 "local {" + + # Local ID + if isset LOCAL_ID; then + print_indent 3 "id = ${LOCAL_ID}" + fi + + # Authentication + case "${AUTH_MODE}" in + PSK) + print_indent 3 "auth = psk" + ;; + esac + + print_indent 2 "}" + print + + # Remote + print_indent 2 "remote {" + + # Remote ID + if isset REMOTE_ID; then + print_indent 3 "id = ${REMOTE_ID}" + fi + + # Authentication + case "${AUTH_MODE}" in + PSK) + print_indent 3 "auth = psk" + ;; + esac + + print_indent 2 "}" + print + + # Children + + print_indent 2 "children {" + print_indent 3 "${connection} {" + + print_indent 4 "# ESP Proposals" + print_indent 4 "esp_proposals = $(vpn_security_policies_make_esp_proposal ${SECURITY_POLICY})" + print + + # Traffic Selectors + + # Local Prefixes + if isset LOCAL_PREFIX; then + print_indent 4 "local_ts = $(list_join LOCAL_PREFIX ,)" + else + print_indent 4 "local_ts = dynamic" + fi + + # Remote Prefixes + if isset REMOTE_PREFIX; then + print_indent 4 "remote_ts = $(list_join REMOTE_PREFIX ,)" + else + print_indent 4 "remote_ts = dynamic" + fi + print + + # Rekeying + if isset LIFETIME; then + print_indent 4 "# Rekey Time" + print_indent 4 "rekey_time = ${LIFETIME}" + print + fi + + # Updown Script + print_indent 4 "updown = ${NETWORK_HELPERS_DIR}/ipsec-updown" + print + + # Mode + print_indent 4 "# Mode" + case "${MODE}" in + gre-transport) + print_indent 4 "mode = transport" + ;; + tunnel|vti|*) + print_indent 4 "mode = tunnel" + ;; + esac + print + + # Compression + print_indent 4 "# Compression" + if enabled COMPRESSION; then + print_indent 4 "ipcomp = yes" + else + print_indent 4 "ipcomp = no" + fi + print + + # Inactivity Timeout + if isset INACTIVITY_TIMEOUT; then + print_indent 4 "# Inactivity Timeout" + print_indent 4 "inactivity = ${INACTIVITY_TIMEOUT}" + print + fi + + # XXX Always-On + print_indent 4 "start_action = start" + print_indent 4 "close_action = start" + + print_indent 3 "}" + print_indent 2 "}" + print + + print_indent 1 "}" + print_indent 0 "}" + print +} + +_ipsec_connection_to_strongswan_secrets() { + local connection="${1}" + + print_indent 0 "secrets {" + + case "${AUTH_MODE}" in + PSK) + print_indent 1 "ike {" + + # Secret + print_indent 2 "secret = ${PSK}" + + # ID + if isset REMOTE_ID; then + print_indent 2 "id = ${REMOTE_ID}" + fi + + print_indent 1 "}" + ;; + esac + + print_indent 0 "}" +} diff --git a/src/functions/functions.util b/src/functions/functions.util index eb2b863f..4b032b04 100644 --- a/src/functions/functions.util +++ b/src/functions/functions.util @@ -26,6 +26,17 @@ print() { printf -- "${fmt}\n" "$@" } +print_indent() { + local i=${1} + shift + + while (( i-- )); do + printf "\t" + done + + print "%s" "$@" +} + # The args() function takes a number of arguments like # var1="abc d" var2="abc" var3="abcd e" # and splits them into several arguments, devided by newline diff --git a/src/helpers/ipsec-updown b/src/helpers/ipsec-updown new file mode 100644 index 00000000..8541d2a0 --- /dev/null +++ b/src/helpers/ipsec-updown @@ -0,0 +1,49 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2017 IPFire Network Development Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +LOG_DISABLE_STDOUT="true" + +. /usr/lib/network/functions + +# Read network settings +network_settings_read + +# Make sure we are called by strongSwan +assert isset PLUTO_VERSION + +CONNECTION="${PLUTO_CONNECTION}" + +if ! ipsec_connection_read_config "${CONNECTION}"; then + log ERROR "Could not read configuration for ${CONNECTION}" + exit ${EXIT_ERROR} +fi + +log DEBUG "${0} called for ${CONNECTION}: ${PLUTO_VERB}" + +case "${PLUTO_VERB}" in + up-client) + ;; + + down-client) + ;; +esac + +exit ${EXIT_OK}