packages/net/strongswan/files/ipsec.init
Hans Dedecker 74dbf6bcbe strongswan: add interface uci list
The interface config option allows users to configure logical OpenWRT
interface names in the ipsec section; it allows StrongSwan to listen
and send traffic on specified interface(s). It translates to interfaces_use
StrongSwan option which is a comma sepearted list of network devices
that should be used by charon.
Since StrongSwan can only be started when one of the specified logical
OpenWRT interface is up procd interface triggers are installed to
trigger the reload script.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
2017-12-13 18:46:37 +01:00

385 lines
10 KiB
Bash

#!/bin/sh /etc/rc.common
START=90
STOP=10
USE_PROCD=1
PROG=/usr/lib/ipsec/starter
. $IPKG_INSTROOT/lib/functions.sh
. $IPKG_INSTROOT/lib/functions/network.sh
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
WAIT_FOR_INTF=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 -eq 0 ] && return
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 -eq 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
local interface_list=$(config_get "$1" "interface")
if [ -z "$interface_list" ]; then
WAIT_FOR_INTF=0
else
for interface in $interface_list; do
network_get_device device $interface
[ -n "$device" ] && append device_list "$device" ","
done
[ -n "$device_list" ] && WAIT_FOR_INTF=0 || WAIT_FOR_INTF=1
fi
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"
[ -n "$device_list" ] && swan_xappend " interfaces_use = $device_list"
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
}
service_running() {
ipsec status > /dev/null 2>&1
}
reload_service() {
running && {
prepare_env
[ $WAIT_FOR_INTF -eq 0 ] && {
ipsec rereadall
ipsec reload
return
}
}
start
}
check_ipsec_interface() {
local intf
for intf in $(config_get "$1" interface); do
procd_add_interface_trigger "interface.*" "$intf" /etc/init.d/ipsec reload
done
}
service_triggers() {
procd_add_reload_trigger "ipsec"
config load "ipsec"
config_foreach check_ipsec_interface ipsec
}
start_service() {
prepare_env
[ $WAIT_FOR_INTF -eq 1 ] && return
procd_open_instance
procd_set_param command $PROG --daemon charon --nofork
procd_set_param file $IPSEC_CONN_FILE
procd_append_param file $IPSEC_SECRETS_FILE
procd_append_param file $STRONGSWAN_CONF_FILE
procd_append_param file /etc/strongswan.d/*.conf
procd_append_param file /etc/strongswan.d/charon/*.conf
procd_set_param respawn
procd_close_instance
}