From: Hans Dedecker Date: Fri, 6 Jan 2017 11:10:32 +0000 (+0100) Subject: strongswan: uci config support X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=36e073d8201fe7cf133ef3eea41f8855c3344c71;p=feed%2Fpackages.git strongswan: uci config support Add support to configure strongswan via uci. uci support is based on the following sections -ipsec : Global config items belonging in the strongswan.conf file -remote : Defines the remote peer(s) -tunnel : Defines the IPSec connections in tunnel mode -transport : Defines the IPSec connections in transport mode -crypto_proposal : Defines the different crypto proposals Signed-off-by: Pierre Lebleu Signed-off-by: Gino Peeters Signed-off-by: Hans Dedecker --- diff --git a/net/strongswan/Makefile b/net/strongswan/Makefile index 029b8bff76..075414b0c6 100644 --- a/net/strongswan/Makefile +++ b/net/strongswan/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=strongswan PKG_VERSION:=5.5.1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=http://download.strongswan.org/ http://download2.strongswan.org/ diff --git a/net/strongswan/files/ipsec.init b/net/strongswan/files/ipsec.init index 391a2ae8c7..4635eae9cf 100644 --- a/net/strongswan/files/ipsec.init +++ b/net/strongswan/files/ipsec.init @@ -3,8 +3,327 @@ START=90 STOP=10 +. $IPKG_INSTROOT/lib/functions.sh + +UCI_IPSEC_CONFIG=/etc/config/ipsec + +IPSEC_SECRETS_FILE=/etc/ipsec.secrets +IPSEC_CONN_FILE=/etc/ipsec.conf +STRONGSWAN_CONF_FILE=/etc/strongswan.conf + +IPSEC_VAR_SECRETS_FILE=/var/ipsec/ipsec.secrets +IPSEC_VAR_CONN_FILE=/var/ipsec/ipsec.conf +STRONGSWAN_VAR_CONF_FILE=/var/ipsec/strongswan.conf + +ENABLED_REMOTE_PEERS=0 + +file_reset() { + : > "$1" +} + +xappend() { + local file="$1" + shift + + echo "${@}" >> "${file}" +} + +remove_include() { + local file="$1" + local include="$2" + + sed -i "\_${include}_d" "${file}" +} + +remove_includes() { + remove_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}" + remove_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}" + remove_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}" +} + +do_include() { + local conf="$1" + local uciconf="$2" + local backup=`mktemp -t -p /tmp/ ipsec-init-XXXXXX` + + [ ! -f "${conf}" ] && rm -rf "${conf}" + touch "${conf}" + + cat "${conf}" | grep -v "${uciconf}" > "${backup}" + mv "${backup}" "${conf}" + xappend "${conf}" "include ${uciconf}" + file_reset "${uciconf}" +} + +ipsec_reset() { + do_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}" +} + +ipsec_xappend() { + xappend "${IPSEC_VAR_CONN_FILE}" "$@" +} + +swan_reset() { + do_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}" +} + +swan_xappend() { + xappend "${STRONGSWAN_VAR_CONF_FILE}" "$@" +} + +secret_reset() { + do_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}" +} + +secret_xappend() { + xappend "${IPSEC_VAR_SECRETS_FILE}" "$@" +} + +warning() { + echo "WARNING: $@" >&2 +} + +add_crypto_proposal() { + local encryption_algorithm + local hash_algorithm + local dh_group + + config_get encryption_algorithm "$1" encryption_algorithm + config_get hash_algorithm "$1" hash_algorithm + config_get dh_group "$1" dh_group + + [ -n "${encryption_algorithm}" ] && \ + crypto="${crypto:+${crypto},}${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}}${dh_group:+-${dh_group}}" +} + +set_crypto_proposal() { + local conf="$1" + local proposal + + crypto="" + + config_get crypto_proposal "$conf" crypto_proposal "" + for proposal in $crypto_proposal; do + add_crypto_proposal "$proposal" + done + + [ -n "${crypto}" ] && { + local force_crypto_proposal + + config_get_bool force_crypto_proposal "$conf" force_crypto_proposal + + [ "${force_crypto_proposal}" = "1" ] && crypto="${crypto}!" + } + + crypto_proposal="${crypto}" +} + +config_conn() { + # Generic ipsec conn section shared by tunnel and transport + local mode + local local_subnet + local local_nat + local local_sourceip + local local_updown + local local_firewall + local remote_subnet + local remote_sourceip + local remote_updown + local remote_firewall + local ikelifetime + local lifetime + local margintime + local keyingtries + local dpdaction + local dpddelay + local inactivity + local keyexchange + + config_get mode "$1" mode "route" + config_get local_subnet "$1" local_subnet "" + config_get local_nat "$1" local_nat "" + config_get local_sourceip "$1" local_sourceip "" + config_get local_updown "$1" local_updown "" + config_get local_firewall "$1" local_firewall "" + config_get remote_subnet "$1" remote_subnet "" + config_get remote_sourceip "$1" remote_sourceip "" + config_get remote_updown "$1" remote_updown "" + config_get remote_firewall "$1" remote_firewall "" + config_get ikelifetime "$1" ikelifetime "3h" + config_get lifetime "$1" lifetime "1h" + config_get margintime "$1" margintime "9m" + config_get keyingtries "$1" keyingtries "3" + config_get dpdaction "$1" dpdaction "none" + config_get dpddelay "$1" dpddelay "30s" + config_get inactivity "$1" inactivity + config_get keyexchange "$1" keyexchange "ikev2" + + [ -n "$local_nat" ] && local_subnet=$local_nat + + ipsec_xappend "conn $config_name-$1" + ipsec_xappend " left=%any" + ipsec_xappend " right=$remote_gateway" + + [ -n "$local_sourceip" ] && ipsec_xappend " leftsourceip=$local_sourceip" + [ -n "$local_subnet" ] && ipsec_xappend " leftsubnet=$local_subnet" + + [ -n "$local_firewall" ] && ipsec_xappend " leftfirewall=$local_firewall" + [ -n "$remote_firewall" ] && ipsec_xappend " rightfirewall=$remote_firewall" + + ipsec_xappend " ikelifetime=$ikelifetime" + ipsec_xappend " lifetime=$lifetime" + ipsec_xappend " margintime=$margintime" + ipsec_xappend " keyingtries=$keyingtries" + ipsec_xappend " dpdaction=$dpdaction" + ipsec_xappend " dpddelay=$dpddelay" + + [ -n "$inactivity" ] && ipsec_xappend " inactivity=$inactivity" + + if [ "$auth_method" = "psk" ]; then + ipsec_xappend " leftauth=psk" + ipsec_xappend " rightauth=psk" + + [ "$remote_sourceip" != "" ] && ipsec_xappend " rightsourceip=$remote_sourceip" + [ "$remote_subnet" != "" ] && ipsec_xappend " rightsubnet=$remote_subnet" + + ipsec_xappend " auto=$mode" + else + warning "AuthenticationMethod $auth_method not supported" + fi + + [ -n "$local_identifier" ] && ipsec_xappend " leftid=$local_identifier" + [ -n "$remote_identifier" ] && ipsec_xappend " rightid=$remote_identifier" + [ -n "$local_updown" ] && ipsec_xappend " leftupdown=$local_updown" + [ -n "$remote_updown" ] && ipsec_xappend " rightupdown=$remote_updown" + ipsec_xappend " keyexchange=$keyexchange" + + set_crypto_proposal "$1" + [ -n "${crypto_proposal}" ] && ipsec_xappend " esp=$crypto_proposal" + [ -n "${ike_proposal}" ] && ipsec_xappend " ike=$ike_proposal" +} + +config_tunnel() { + config_conn "$1" + + # Specific for the tunnel part + ipsec_xappend " type=tunnel" +} + +config_transport() { + config_conn "$1" + + # Specific for the transport part + ipsec_xappend " type=transport" +} + +config_remote() { + local enabled + local gateway + local pre_shared_key + local auth_method + + config_name=$1 + + config_get_bool enabled "$1" enabled 0 + [ "$enabled" = "0" ] && return + + ENABLED_REMOTE_PEERS=$((ENABLED_REMOTE_PEERS + 1)) + + config_get gateway "$1" gateway + config_get pre_shared_key "$1" pre_shared_key + config_get auth_method "$1" authentication_method + config_get local_identifier "$1" local_identifier "" + config_get remote_identifier "$1" remote_identifier "" + + [ "$gateway" = "any" ] && remote_gateway="%any" || remote_gateway="$gateway" + + [ -z "$local_identifier" ] && { + local ipdest + + [ "$remote_gateway" = "%any" ] && ipdest="1.1.1.1" || ipdest="$remote_gateway" + local_gateway=`ip route get $ipdest | awk -F"src" '/src/{gsub(/ /,"");print $2}'` + } + + [ -n "$local_identifier" ] && secret_xappend -n "$local_identifier " || secret_xappend -n "$local_gateway " + [ -n "$remote_identifier" ] && secret_xappend -n "$remote_identifier " || secret_xappend -n "$remote_gateway " + + secret_xappend ": PSK \"$pre_shared_key\"" + + set_crypto_proposal "$1" + ike_proposal="$crypto_proposal" + + config_list_foreach "$1" tunnel config_tunnel + + config_list_foreach "$1" transport config_transport + + ipsec_xappend "" +} + +config_ipsec() { + local debug + local rtinstall_enabled + local routing_tables_ignored + local routing_table + local routing_table_id + local interface + local device_list + + ipsec_reset + secret_reset + swan_reset + + ipsec_xappend "# generated by /etc/init.d/ipsec" + ipsec_xappend "version 2" + ipsec_xappend "" + + secret_xappend "# generated by /etc/init.d/ipsec" + + config_get debug "$1" debug 0 + config_get_bool rtinstall_enabled "$1" rtinstall_enabled 1 + [ $rtinstall_enabled = "1" ] && install_routes=yes || install_routes=no + + # prepare extra charon config option ignore_routing_tables + for routing_table in $(config_get "$1" "ignore_routing_tables"); do + if [ "$routing_table" -ge 0 ] 2>/dev/null; then + routing_table_id=$routing_table + else + routing_table_id=$(sed -n '/[ \t]*[0-9]\+[ \t]\+'$routing_table'[ \t]*$/s/[ \t]*\([0-9]\+\).*/\1/p' /etc/iproute2/rt_tables) + fi + + [ -n "$routing_table_id" ] && append routing_tables_ignored "$routing_table_id" + done + + swan_xappend "# generated by /etc/init.d/ipsec" + swan_xappend "charon {" + swan_xappend " load_modular = yes" + swan_xappend " install_routes = $install_routes" + [ -n "$routing_tables_ignored" ] && swan_xappend " ignore_routing_tables = $routing_tables_ignored" + swan_xappend " plugins {" + swan_xappend " include /etc/strongswan.d/charon/*.conf" + swan_xappend " }" + swan_xappend " syslog {" + swan_xappend " identifier = ipsec" + swan_xappend " daemon {" + swan_xappend " default = $debug" + swan_xappend " }" + swan_xappend " auth {" + swan_xappend " default = $debug" + swan_xappend " }" + swan_xappend " }" + swan_xappend "}" +} + +prepare_env() { + mkdir -p /var/ipsec + remove_includes + config_load ipsec + config_foreach config_ipsec ipsec + config_foreach config_remote remote +} + start() { - ipsec start + prepare_env + [ $ENABLED_REMOTE_PEERS != 0 -o ! -f $UCI_IPSEC_CONFIG ] && ipsec start } stop() { @@ -12,9 +331,18 @@ stop() { } restart() { - ipsec restart + prepare_env + [ $ENABLED_REMOTE_PEERS != 0 -o ! -f $UCI_IPSEC_CONFIG ] && ipsec restart || ipsec stop } reload() { - ipsec update + prepare_env + [ $ENABLED_REMOTE_PEERS != 0 -o ! -f $UCI_IPSEC_CONFIG ] && { + ipsec secrets + if [[ ! -z "$(ipsec status)" ]]; then + ipsec reload + else + ipsec start + fi + } || ipsec stop }