diff --git a/net/libreswan/Makefile b/net/libreswan/Makefile index b05b29e59e062d..554fcac819d5e7 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,10 @@ 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 + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/etc/config/libreswan $(1)/etc/config/libreswan endef $(eval $(call BuildPackage,libreswan)) diff --git a/net/libreswan/files/etc/config/libreswan b/net/libreswan/files/etc/config/libreswan new file mode 100644 index 00000000000000..2e3718a1936c52 --- /dev/null +++ b/net/libreswan/files/etc/config/libreswan @@ -0,0 +1,37 @@ +config libreswan 'globals' + option debug '0' # set debug mode none/all + list virtual_private '10.0.0.0/8' + list virtual_private '192.168.0.0/16' + list virtual_private '172.16.0.0/12' + list virtual_private '25.0.0.0/8' + list virtual_private '100.64.0.0/10' + list virtual_private '!100.64.0.0/24' # the address ranges that may live behind a NAT router through which a client connects + # option listen '192.168.2.100' # listening address, if set listen_interface would not be used + # option listen_interface 'wan' # listening interface + # option uniqueids 'yes' # yes/no + +# config crypto_proposal 'p1' +# option encryption_algorithm '3des' # possible values: 3des, aes, aes_ctr, aes_cbc, aes128, aes192, aes256, camellia_cbc +# option hash_algorithm 'md5' # possible values: md5, sha1, sha256, sha384, sha512 +# list dh_group 'modp1536' # possible values: modp1536, modp2048, modp3072, modp4096, modp6144, modp8192, dh19, dh20, dh21, dh22, dh31 + +# config tunnel 'vti2_1_5' +# option left '%wan' # left can be interface of ipaddress +# option leftid '@left' # local id +# option right '192.168.2.201' # remote endpoint public ip +# option rightid '@62dd3e3f82339b002405245b' # rightid +# option auto 'start' # what operation, should be done automatically at IPsec startup +# option authby 'secret' # how the two security gateways should authenticate each other +# option psk 'AyG9RlTtQJIUxgxG' # preshare key +# option ikev2 '1' # ike version +# option ikelifetime '10800' +# option rekey '1' +# option rekeymargin '540' +# option dpdaction 'restart' +# option dpddelay '30' +# option dpdtimeout '150' +# option vti_interface 'vti2_1_5' # only for route based tunnels +# option leftvti '172.16.31.2/30' # only for route based tunnels +# option mark '0x5' # only if vti interface is set +# list leftsubnets '0.0.0.0/0' +# list rightsubnets '0.0.0.0/0' 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 old mode 100755 new mode 100644 index f33d41292420a8..b5d0432b0b69ee --- 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/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