diff --git a/net/libreswan/Makefile b/net/libreswan/Makefile index b05b29e59e062d..419904a025a0d5 100644 --- a/net/libreswan/Makefile +++ b/net/libreswan/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libreswan PKG_VERSION:=4.7 -PKG_RELEASE:=1 +PKG_RELEASE:=$(AUTO_RELEASE) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://download.libreswan.org/ @@ -60,10 +60,10 @@ $(call Package/libreswan/Default/description) endef define Package/libreswan/conffiles -/etc/ipsec.d -/etc/ipsec.conf -/etc/ipsec.secrets +/etc/config/libreswan +/etc/ipsec.user endef + TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed TARGET_CFLAGS += -flto @@ -115,6 +115,8 @@ define Package/libreswan/install $(1)/etc/ipsec.d/policies/ $(CP) $(PKG_INSTALL_DIR)/usr/libexec/ipsec/* \ $(1)/usr/libexec/ipsec/ + $(INSTALL_DIR) $(1)/etc/hotplug.d/ipsec + $(CP) ./files/etc/hotplug.d/ipsec/01-user $(1)/etc/hotplug.d/ipsec/01-user endef $(eval $(call BuildPackage,libreswan)) diff --git a/net/libreswan/files/etc/hotplug.d/ipsec/01-user b/net/libreswan/files/etc/hotplug.d/ipsec/01-user new file mode 100644 index 00000000000000..120260957a21bd --- /dev/null +++ b/net/libreswan/files/etc/hotplug.d/ipsec/01-user @@ -0,0 +1,7 @@ +#!/bin/sh + +[ -e "/etc/ipsec.user" ] && { + . /etc/ipsec.user +} + +exit 0 diff --git a/net/libreswan/files/ipsec.init b/net/libreswan/files/ipsec.init index f33d41292420a8..49ef0517e1089a 100755 --- a/net/libreswan/files/ipsec.init +++ b/net/libreswan/files/ipsec.init @@ -1,36 +1,240 @@ #!/bin/sh /etc/rc.common +. /lib/functions/network.sh + START=90 STOP=10 USE_PROCD=1 + PROG="/usr/libexec/ipsec/pluto" -IPSEC_SECRETS=/etc/ipsec.secrets -IPSEC_CONF=/etc/ipsec.conf -IPSEC_BIN=/usr/sbin/ipsec +IPSEC_BIN="/usr/sbin/ipsec" + +IPSEC_DIR="/var/run/ipsec" +IPSEC_CONF="$IPSEC_DIR/ipsec.conf" +IPSEC_CONF_DIR="$IPSEC_DIR/ipsec/conf.d" checkconfig() { - ${IPSEC_BIN} addconn --checkconfig || return 1 - mkdir -p /var/run/pluto + ${IPSEC_BIN} addconn --checkconfig || return 1 + mkdir -p /var/run/pluto +} + +expand_ike() { + local id="$1" + local encryption_algorithm hash_algorithm dh_group proposal + + config_get encryption_algorithm "${id}" encryption_algorithm + config_get hash_algorithm "${id}" hash_algorithm + config_get dh_group "${id}" dh_group + + proposal="${encryption_algorithm:+${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}${dh_group:+;${dh_group%% *}}}}" + append ike_proposal "$proposal" "," +} + +expand_phase2alg() { + local id="$1" + local encryption_algorithm hash_algorithm dh_group + + config_get encryption_algorithm "${id}" encryption_algorithm + config_get hash_algorithm "${id}" hash_algorithm + config_get dh_group "${id}" dh_group + + phase2alg_proposal="${encryption_algorithm:+${encryption_algorithm// /+}${hash_algorithm:+-${hash_algorithm// /+}${dh_group:+-${dh_group// /+}}}}" +} + +generate_tunnel_config() { + local id=$1 + local config_file="$IPSEC_CONF_DIR/$id.conf" + local secret_file="$IPSEC_CONF_DIR/$id.secret" + + config_get auto "$id" auto + config_get left "$id" left + config_get right "$id" right + config_get leftid "$id" leftid "$left" + config_get rightid "$id" rightid "$right" + config_get leftsourceip "$id" leftsourceip + config_get rightsourceip "$id" rightsourceip + config_get leftsubnets "$id" leftsubnets + config_get rightsubnets "$id" rightsubnets + config_get_bool ikev2 "$id" ikev2 + [ "$ikev2" = "1" ] && ikev2=yes || ikev2=no + config_get_bool rekey "$id" rekey + [ "$rekey" = "1" ] && rekey=yes || rekey=no + config_get ikelifetime "$id" ikelifetime + config_get rekeymargin "$id" rekeymargin + config_get dpdaction "$id" dpdaction + config_get dpdtimeout "$id" dpdtimeout + config_get dpddelay "$id" dpddelay + config_get phase2 "$id" phase2 + config_get phase2alg "$id" phase2alg + config_get vti_interface "$id" vti_interface + + if [ -n "$vti_interface" ]; then + config_get leftvti "$id" leftvti + config_get mark "$id" mark + fi + + config_list_foreach "$id" ike expand_ike + config_list_foreach "$id" phase2alg expand_phase2alg + + config_get authby "$id" authby + config_get psk "$id" psk + + if [ -n "$leftsubnets" ]; then + [[ "$leftsubnets" =~ 0.0.0.0* ]] && leftsubnets="0.0.0.0/0" + leftsubnets="{${leftsubnets// /,}}" + fi + + if [ -n "$rightsubnets" ]; then + [[ "$rightsubnets" =~ 0.0.0.0* ]] && rightsubnets="0.0.0.0/0" + rightsubnets="{${rightsubnets// /,}}" + fi + + cat << EOF > "$config_file" +conn $id + auto=${auto} + authby=${authby} + ikev2=${ikev2} + left=${left%% *} + ${leftid:+leftid=${leftid}} + ${leftsourceip:+leftsourceip=${leftsourceip}} + ${leftsubnets:+leftsubnets=${leftsubnets}} + right=${right%% *} + ${rightid:+rightid=${rightid}} + ${rightsourceip:+rightsourceip=${rightsourceip}} + ${rightsubnets:+rightsubnets=${rightsubnets}} + ${dpdaction:+dpdaction=${dpdaction}} + ${dpdtimeout:+dpdtimeout=${dpdtimeout}} + ${dpddelay:+dpddelay=${dpddelay}} + ${ikelifetime:+ikelifetime=${ikelifetime}s} + ${rekey:+rekey=${rekey}} + ${rekeymargin:+rekeymargin=${rekeymargin}s} + ${rekeyfuzz:+rekeyfuzz=${rekeyfuzz}} + ${phase2:+phase2=${phase2}} + ${ike_proposal:+ike=${ike_proposal}} + ${phase2alg_proposal:+phase2alg=${phase2alg_proposal}} + ${vti_interface:+vti-interface=${vti_interface}} + ${leftvti:+leftvti=${leftvti}} + ${mark:+mark=${mark}} +EOF + +cat << EOF > "$secret_file" +$leftid $rightid : PSK "$psk" +EOF + + unset ike_proposal phase2alg_proposal +} + +generate_daemon_config() { + config_get_bool debug globals debug 0 + [ "$debug" = "0" ] && debug=none || debug=all + config_get_bool uniqueids globals uniqueids 0 + [ "$uniqueids" = "0" ] && uniqueids=no || uniqueids=yes + config_get listen globals listen + config_get listen_interface globals listen_interface + [ -n "$listen_interface" ] && network_get_ipaddr listen "$listen_interface" + config_get virtual_private globals virtual_private + [ -z "$virtual_private" ] && virtual_private='10.0.0.0/8 192.168.0.0/16 172.16.0.0/12 25.0.0.0/8 100.64.0.0/10 !100.64.0.0/24' + + [ ! -d $IPSEC_DIR ] && mkdir -p $IPSEC_DIR + [ ! -d $IPSEC_CONF_DIR ] && mkdir -p $IPSEC_CONF_DIR + + cat << EOF > "$IPSEC_CONF" +config setup + ${debug:+plutodebug=${debug}} + ${uniqueids:+uniqueids=${uniqueids}} + ${listen:+listen=${listen}} + ${virtual_private:+virtual-private=%v4:${virtual_private// /,%v4:}} + +include $IPSEC_CONF_DIR/*.conf +EOF +} + +clean_config() { + rm -f $IPSEC_CONF_DIR/*.conf $IPSEC_CONF_DIR/*.secret +} + +config_cb() { + local var="CONFIG_${1}_SECTIONS" + export $var + append "$var" "$2" +} + +generate_config() { + config_load libreswan + generate_daemon_config + config_foreach generate_tunnel_config tunnel +} + +regenerate_config() { + clean_config + generate_config +} + +active_conns() { + local active_conns file _file + + active_conns=$(${IPSEC_BIN} --trafficstatus | awk -F'[":/]' '{print $3}' | sort -u) + + for file in $IPSEC_CONF_DIR/*.conf; do + _file="${file##*/}" + list_contains active_conns "$_file" || append active_conns "${_file%%.*}" + done + + echo "$active_conns" } start_service() { + generate_config checkconfig || return 1 - ipsec _stackmanager start + ${IPSEC_BIN} _stackmanager start # Enable nflog if configured - ipsec --checknflog > /dev/null + ${IPSEC_BIN} --checknflog > /dev/null procd_open_instance - procd_set_param command $PROG --config ${IPSEC_CONF} --nofork --secretsfile ${IPSEC_SECRETS} + procd_set_param command $PROG --config ${IPSEC_CONF} --nofork procd_set_param respawn procd_close_instance } stop_service() { - ipsec whack --shutdown - ipsec _stackmanager stop - ipsec --stopnflog > /dev/null + ${IPSEC_BIN} whack --shutdown + ${IPSEC_BIN} _stackmanager stop + ${IPSEC_BIN} --stopnflog > /dev/null +} + +delete_tunnel() { + ${IPSEC_BIN} auto --delete "$1" > /dev/null 2>&1 + rm -f ${IPSEC_CONF_DIR}/$1.* +} + +add_tunnel() { + generate_tunnel_config "$1" + ${IPSEC_BIN} auto --add "$1" > /dev/null 2>&1 + ${IPSEC_BIN} auto --rereadsecrets + ${IPSEC_BIN} auto --up "$1" > /dev/null 2>&1 & +} +reload_service() { + local active_tunnels uci_tunnels + + config_load libreswan + config_get uci_tunnels tunnel SECTIONS + + active_tunnels="$(active_conns)" + + for tunnel in $active_tunnels; do + list_contains uci_tunnels "$tunnel" || delete_tunnel "$tunnel" + done + + for tunnel in $uci_tunnels; do + list_contains active_tunnels "$tunnel" || add_tunnel "$tunnel" + done + + ${IPSEC_BIN} auto --rereadall } +service_triggers() { + procd_add_reload_trigger 'libreswan' +} diff --git a/net/libreswan/patches/050-updown-hotplug.patch b/net/libreswan/patches/050-updown-hotplug.patch new file mode 100644 index 00000000000000..9516ce2ce8f532 --- /dev/null +++ b/net/libreswan/patches/050-updown-hotplug.patch @@ -0,0 +1,8 @@ +--- a/programs/_updown.xfrm/_updown.xfrm.in ++++ b/programs/_updown.xfrm/_updown.xfrm.in +@@ -1025,3 +1025,5 @@ case "${PLUTO_VERB}" in + exit 1 + ;; + esac ++ ++/sbin/hotplug-call ipsec