From: Mathieu Baudier Date: Tue, 7 Mar 2023 05:40:06 +0000 (+0100) Subject: Separate subpackages X-Git-Tag: v2.3.0~12 X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-freed.git;a=commitdiff_plain;h=70efba4c4a7203706d432dee44fa02949929804d Separate subpackages --- diff --git a/libreswan/usr/lib/systemd/system/freed-ipsec-roaming@.service b/libreswan/usr/lib/systemd/system/freed-ipsec-roaming@.service new file mode 100644 index 0000000..374004b --- /dev/null +++ b/libreswan/usr/lib/systemd/system/freed-ipsec-roaming@.service @@ -0,0 +1,27 @@ +[Unit] +Description=Roaming IPSec to '%i' +After=network-online.target +Wants=network-online.target + +After=unbound.service +Requires=unbound.service + +After=ipsec.service +PartOf=ipsec.service +Requires=ipsec.service + +StartLimitIntervalSec=60 +StartLimitBurst=20 + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=ipsec auto --start %i +ExecStop=ipsec auto --delete %i + +Restart=on-failure +RestartSec=3 + +[Install] +WantedBy=multi-user.target +RequiredBy=ipsec.service diff --git a/libreswan/usr/lib/systemd/system/freed-onresume.service b/libreswan/usr/lib/systemd/system/freed-onresume.service new file mode 100644 index 0000000..7b7dc54 --- /dev/null +++ b/libreswan/usr/lib/systemd/system/freed-onresume.service @@ -0,0 +1,14 @@ +[Unit] +Description=On resume actions +After=sleep.target +After=network-online.target +Wants=network-online.target + +[Service] +Type=oneshot +ExecStartPre=sleep 3 +ExecStart=/usr/bin/systemctl restart ipsec + +[Install] +WantedBy=sleep.target + diff --git a/libreswan/usr/lib/systemd/system/freed-onsuspend.service b/libreswan/usr/lib/systemd/system/freed-onsuspend.service new file mode 100644 index 0000000..47afcc2 --- /dev/null +++ b/libreswan/usr/lib/systemd/system/freed-onsuspend.service @@ -0,0 +1,11 @@ +[Unit] +Description=On suspend actions +Before=sleep.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/systemctl stop ipsec +ExecStartPost=/usr/bin/sleep 5 + +[Install] +WantedBy=sleep.target diff --git a/libreswan/usr/libexec/ipsec/_updown.host4client6 b/libreswan/usr/libexec/ipsec/_updown.host4client6 new file mode 100755 index 0000000..2f748a6 --- /dev/null +++ b/libreswan/usr/libexec/ipsec/_updown.host4client6 @@ -0,0 +1,977 @@ +#!/bin/sh +# +# default updown script for use with NETKEY(XFRM) +# +# Copyright (C) 2003-2004 Nigel Metheringham +# Copyright (C) 2002-2007 Michael Richardson +# Copyright (C) 2007-2008 Paul Wouters +# Copyright (C) 2003-2020 Tuomo Soini +# Copyright (C) 2011-2016 Paul Wouters +# Copyright (C) 2016 Antony Antony +# +# 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 2 of the License, or (at your +# option) any later version. See . +# +# 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. + +# CAUTION: Installing a new version of Libreswan will install a new +# copy of this script, wiping out any custom changes you make. If +# you need changes, make a copy of this under another name, and customize +# that, and use the (left/right)updown= parameters in ipsec.conf to make +# Libreswan use your modified updown script instead of this default one. + +test ${IPSEC_INIT_SCRIPT_DEBUG} && set -v -x + +LC_ALL=C +export LC_ALL + +# Things that this script gets (from ipsec_pluto(8) man page) +# +# +# PLUTO_VERSION +# indicates what version of this interface is being +# used. This document describes version 1.1. This +# is upwardly compatible with version 1.0. +# +# PLUTO_VERB +# specifies the name of the operation to be performed +# (prepare-host, prepare-client, up-host, up-client, +# down-host, or down-client). If the address family +# for security gateway to security gateway +# communications is IPv6, then a suffix of -v6 is added +# to the verb. +# +# PLUTO_CONNECTION +# is the name of the connection for which we are +# routing. +# +# PLUTO_CONN_POLICY +# the policy of the connection, as in: +# RSASIG+ENCRYPT+TUNNEL+PFS+DONTREKEY+OPPORTUNISTIC +# +failureDROP+lKOD+rKOD +# +# PLUTO_NEXT_HOP +# is the next hop to which packets bound for the peer +# must be sent. +# +# PLUTO_INTERFACE +# is the name of the real interface used by encrypted traffic and IKE traffic +# +# PLUTO_ME +# is the IP address of our host. +# +# PLUTO_METRIC +# is the metric to set for the route +# +# PLUTO_MTU +# is the mtu to set for the route +# +# PLUTO_MY_CLIENT +# is the IP address / count of our client subnet. If +# the client is just the host, this will be the +# host's own IP address / mask (where max is 32 for +# IPv4 and 128 for IPv6). +# +# PLUTO_MY_CLIENT_NET +# is the IP address of our client net. If the client +# is just the host, this will be the host's own IP +# address. +# +# PLUTO_MY_CLIENT_MASK +# is the mask for our client net. If the client is +# just the host, this will be 255.255.255.255. +# +# PLUTO_MY_SOURCEIP +# if non-empty, then the source address for the route will be +# set to this IP address. +# +# PLUTO_MY_PROTOCOL +# is the protocol for this connection. Useful for +# firewalling. +# +# PLUTO_MY_PORT +# is the port. Useful for firewalling. +# +# PLUTO_PEER +# is the IP address of our peer. +# +# PLUTO_PEER_CLIENT +# is the IP address / count of the peer's client subnet. +# If the client is just the peer, this will be +# the peer's own IP address / mask (where max is 32 +# for IPv4 and 128 for IPv6). +# +# PLUTO_PEER_CLIENT_NET +# is the IP address of the peer's client net. If the +# client is just the peer, this will be the peer's +# own IP address. +# +# PLUTO_PEER_CLIENT_MASK +# is the mask for the peer's client net. If the +# client is just the peer, this will be +# 255.255.255.255. +# +# PLUTO_PEER_PROTOCOL +# is the protocol set for remote end with port +# selector. +# +# PLUTO_PEER_PORT +# is the peer's port. Useful for firewalling. +# +# PLUTO_CFG_CLIENT=0|1 +# is MODECFG or IKEv2 Config client. +# +# PLUTO_CFG_SERVER=0|1 +# is MODECFG or IKEv2 Config server. +# +# PLUTO_CONNECTION_TYPE +# +# PLUTO_CONN_ADDRFAMILY +# is the family type, "ipv4" or "ipv6" +# +# PLUTO_PROTO_STACK +# is the local IPsec kernel stack used, eg NETKEY, NOSTACK +# +# PLUTO_IS_PEER_CISCO=0|1 +# remote server type is cisco. Add support for cisco extensions +# when used with xauth. +# +# PLUTO_NM_CONFIGURED=0|1 +# is NetworkManager used for resolv.conf update +# +# PLUTO_SA_REQID +# When using KAME or XFRM/NETKEY, the IPsec SA reqid base value. +# ESP/AH out is base, ESP/AH in = base + 1 +# IPCOMP is base + 2 plus for inbound + 1 +# +# PLUTO_SA_TYPE +# The type of IPsec SA (ESP or AH) +# +# PLUTO_USERNAME +# The username (XAUTH or GSSAPI) that was authenticated (if any) +# for this SA +# +# PLUTO_VIRT_INTERFACE +# is the name of ipsec interface used by clear traffic in/out +# +# +# XAUTH_FAILED +# If xauthfail=soft this will be set to 1 if XAUTH authentication +# failed. If xauthfail=hard, the updown scripts never run. +# +# CONNMARK +# If mark= is set on the connection, this variable will be +# set with the value. It can be used for iptables or VTI. +# +# VTI_IFAC=iface +# Name of VTI interface to create +# +# VTI_ROUTING=yes|no +# Whether or not to perform ip rule and ip route commands +# covering the IPsec SA address ranges to route those packets +# into the VTI_IFACE interface. This should be enabled unless +# the IPsec SA covers 0.0.0.0/0 <-> 0.0.0.0/0 +# +# VTI_SHARED=yes|no +# Whether or not more conns (or instances) share a VTI device. +# If not shared, the VTI device is deleted when tunnel goes down. +# +# SPI_IN / SPI_OUT +# The inbound and outbound SPI's of the connection. + +# rpm based systems +if [ -f /etc/sysconfig/pluto_updown ]; then + . /etc/sysconfig/pluto_updown +# deb based systems +elif [ -f /etc/default/pluto_updown ]; then + . /etc/default/pluto_updown +fi + +BACKUP_RESOLV_CONF=/run/pluto/libreswan-resolv-conf-backup +ETC_RESOLV_CONF=/etc/resolv.conf + +case "${PLUTO_CONN_ADDRFAMILY}" in + ipv4) + FAMILY=4 + MAX_CIDR=32 + SCOPE=50 # Use scope 50 to verify ip was added by addsource() + ;; + ipv6) + FAMILY=6 + MAX_CIDR=128 + SCOPE=global + ;; + *) + echo "unknown address family \"${PLUTO_CONN_ADDRFAMILY}\"" >&2 + exit 1 + ;; +esac +export FAMILY MAX_CIDR SCOPE + +# 2022-09-03 - mbaudier : Hack when having an IPv6 subnet +export CLIENT_FAMILY=6 +export CLIENT_MAX_CIDR=128 + +# Ignore parameter custom +if [ "${1}" = "custom" ]; then + shift +fi + +while [ $# -gt 0 ]; do + case ${1} in + --route) + case ${2} in + [Yy]*) + ROUTE=yes + PROXY_ARP_ROUTE=no + ;; + *) + ROUTE= + PROXY_ARP_ROUTE= + ;; + esac + shift; shift + ;; + --iproute) + IPRARGS="${2}" + shift; shift + ;; + *) + echo "$0: Unknown argument \"${1}\"" >&2 + exit 1 + ;; + esac +done + +# utility functions for route manipulation +# Meddling with this stuff should not be necessary and requires great care. +uproute() { + doproxyarp add + doroute replace +} + +downroute() { + doroute del + doproxyarp delete +} + +downrule() { + if [ -n "${PLUTO_MY_SOURCEIP}" -a 0${PLUTO_IS_PEER_CISCO} -eq 1 ]; then + doroute del + fi +} + +updateresolvconf() { + local domain + local nameserver + local new_nameserver + local new_resolv_conf + local new_search + local orig_domain + local orig_nameserver + local rc + rc=0 + if [ 0${PLUTO_CFG_CLIENT} -eq 0 ]; then + return ${rc} + fi + if [ -n "$(pidof unbound)" -a \ + -n "${PLUTO_PEER_DNS_INFO}" -a \ + -n "${PLUTO_PEER_DOMAIN_INFO}" ] + then + for domain in ${PLUTO_PEER_DOMAIN_INFO}; do + echo "updating local nameserver for ${domain} with ${PLUTO_PEER_DNS_INFO}" + unbound-control forward_add ${domain} \ + ${PLUTO_PEER_DNS_INFO} + unbound-control flush_zone ${domain} + unbound-control flush_requestlist + done + rc=$? + elif [ 0${PLUTO_NM_CONFIGURED} -eq 0 -a \ + -n "${PLUTO_PEER_DNS_INFO}" ] + then + echo "updating resolvconf" + + if [ ! -e "${ETC_RESOLV_CONF}" ]; then + echo "resolv.conf does not exist, so doing nothing" + return 0 + fi + + if [ -e "${BACKUP_RESOLV_CONF}" ]; then + if grep -q Libreswan "${ETC_RESOLV_CONF}"; then + echo "Current resolv.conf is generated by Libreswan, and backup resolv.conf already exists, so doing nothing" + return 0 + else + echo "backup resolv.conf exists, but current resolv.conf is not generated by Libreswan" + fi + fi + + rm -f -- "${BACKUP_RESOLV_CONF}" + cp -- "${ETC_RESOLV_CONF}" "${BACKUP_RESOLV_CONF}" + + new_resolv_conf="# Generated by Libreswan (IPsec)" + + orig_domain="$(grep ^domain "${ETC_RESOLV_CONF}" 2>/dev/null | \ + awk '{ print $2 }')" + + orig_search=$(grep ^search "${ETC_RESOLV_CONF}" 2>/dev/null | \ + sed 's/^search[[:space:]]\+//;s/[[:space:]]*\#.*//') + + if [ -n "${orig_domain}" ]; then + new_resolv_conf="${new_resolv_conf} +domain ${orig_domain}" + fi + + if [ -n "${orig_search}" ]; then + new_search="${orig_search}" + elif [ -n "${orig_domain}" ]; then + new_search="${orig_domain}" + fi + + if [ -n "${PLUTO_PEER_DOMAIN_INFO}" ]; then + if [ -n "${new_search}" ]; then + new_search=$(echo $(echo "${new_search} ${PLUTO_PEER_DOMAIN_INFO}" | tr [:space:] '\n' | awk '!a[$0]++')) + else + new_search="${PLUTO_PEER_DOMAIN_INFO}" + fi + fi + + if [ -n "${new_search}" ]; then + new_resolv_conf="${new_resolv_conf} +search ${new_search}" + fi + + orig_nameserver=$(grep -m 1 ^nameserver "${ETC_RESOLV_CONF}" | \ + sed 's/^nameserver[[:space:]]\+//;s/[[:space:]]*\#.*//') + if [ -n "${orig_nameserver}" ]; then + new_nameserver=$(echo $(echo "${PLUTO_PEER_DNS_INFO} ${orig_nameserver}" | tr [:space:] '\n' | awk '!a[$0]++')) + else + new_nameserver="${PLUTO_PEER_DNS_INFO}" + fi + + for nameserver in ${new_nameserver}; do + new_resolv_conf="${new_resolv_conf} +nameserver ${nameserver}" + done + + echo "${new_resolv_conf}" > "${ETC_RESOLV_CONF}" + rc=$? + fi + return ${rc} +} + +restoreresolvconf() { + local domain + local rc + rc=0 + if [ 0${PLUTO_CFG_CLIENT} -eq 0 ]; then + return ${rc} + fi + if [ -n "$(pidof unbound)" -a \ + -n "${PLUTO_PEER_DNS_INFO}" -a \ + -n "${PLUTO_PEER_DOMAIN_INFO}" ] + then + for domain in ${PLUTO_PEER_DOMAIN_INFO}; do + echo "flushing local nameserver of ${domain}" + unbound-control forward_remove ${domain} + unbound-control flush_zone ${domain} + unbound-control flush_requestlist + done + rc=$? + elif [ 0${PLUTO_NM_CONFIGURED} -eq 0 ]; then + # We only restore if current resolv.conf is made by us. + if grep -q Libreswan "${ETC_RESOLV_CONF}" 2>/dev/null; then + # And if there is a backup... + if [ -e "${BACKUP_RESOLV_CONF}" ]; then + echo "restoring resolvconf" + else + return 0 + fi + cp -- "${BACKUP_RESOLV_CONF}" "${ETC_RESOLV_CONF}" + fi + rm -f -- "${BACKUP_RESOLV_CONF}" + rc=0 + fi + return ${rc} +} + +notifyNM() { + # This will be called whenever a connection is established or + # fails to establish (either phase 1, xauth phase, or phase 2) + # or whenever an already established connection is being terminated. + # This will send a signal to NetworkManager over dbus so that NM + # can keep track of the coonnections. + + if [ 0${PLUTO_NM_CONFIGURED} -eq 1 ]; then + echo "sending $1 signal to NetworkManager" + libreswan_reason=$1 + export libreswan_reason + export PLUTO_PEER_DOMAIN_INFO + export PLUTO_PEER_DNS_INFO + export PLUTO_PEER_BANNER + export PLUTO_MY_SOURCEIP + export PLUTO_PEER + [ -x /usr/libexec/nm-libreswan-service-helper ] && \ + /usr/libexec/nm-libreswan-service-helper + fi + return 0 +} + +addsource() { + local interface + local st + interface=lo + st=0 + + if [ -z "${PLUTO_MY_SOURCEIP}" ]; then + return ${st} + fi + # check if given sourceip is local and add as alias if not + if ! ip -${CLIENT_FAMILY} -o route get ${PLUTO_MY_SOURCEIP} | grep -q ^local; then + if [ -n "${VTI_IFACE}" -a "${VTI_ROUTING}" = yes ]; then + interface="${VTI_IFACE}" + elif [ -n "${PLUTO_XFRMI_ROUTE}" ]; then + interface=${PLUTO_VIRT_INTERFACE} + fi + it="ip addr add ${PLUTO_MY_SOURCEIP}/${CLIENT_MAX_CIDR} dev ${interface} scope ${SCOPE}" + oops="$(eval ${it} 2>&1)" + st=$? + if [ -z "${oops}" -a ${st} -ne 0 ]; then + oops="silent error, exit status ${st}" + fi + case "${oops}" in + 'RTNETLINK answers: File exists'*) + # should not happen, but ... ignore if the + # address was already assigned on interface + oops="" + st=0 + ;; + esac + if [ -n "${oops}" -o ${st} -ne 0 ]; then + echo "$0: addsource \"${it}\" failed (${oops})" >&2 + fi + fi + return ${st} +} + +delsource() { + local interface + local oops + local st + interface=lo + st=0 + if [ -z "${PLUTO_MY_SOURCEIP}" ]; then + return ${st} + fi + # Remove source ip if it's not used any more. + if [ -z "$(ip -${CLIENT_FAMILY} -o route list src ${PLUTO_MY_SOURCEIP})" ]; then + if [ -n "${VTI_IFACE}" -a "${VTI_ROUTING}" = yes ]; then + interface="${VTI_IFACE}" + elif [ -n "${PLUTO_XFRMI_ROUTE}" ]; then + interface=${PLUTO_VIRT_INTERFACE} + fi + # If there is no ip we just return + if ! ip -${FAMILY} -o addr list dev ${interface} scope ${SCOPE} | \ + grep -q ${PLUTO_MY_SOURCEIP}/${CLIENT_MAX_CIDR} + then + return ${st} + fi + + if [ -n "${PLUTO_MOBIKE_EVENT}" ] ; then + return ${st} + fi + + it="ip -${CLIENT_FAMILY} addr del ${PLUTO_MY_SOURCEIP}/${CLIENT_MAX_CIDR} dev ${interface}" + oops="$(eval ${it} 2>&1)" + st=$? + if [ -z "${oops}" -a ${st} -ne 0 ]; then + oops="silent error, exit status ${st}" + fi + case "${oops}" in + 'RTNETLINK answers: File exists'*) + # should not happen, but ... ignore if the + # address was already assigned on interface + oops="" + st=0 + ;; + 'RTNETLINK answers: Cannot assign'*) + # Address is not there to remove or is there with different + # netmask and in that case we must not remove it so we ignore + # the error. + oops="" + st=0 + ;; + esac + if [ -n "${oops}" -o ${st} -ne 0 ]; then + echo "$0: delsource \"${it}\" failed (${oops})" >&2 + fi + fi + return ${st} +} + +doproxyarp() { + local cmd + local iface + cmd=${1} + # Check if client has a single ip only client net + if [ ${PLUTO_PEER_CLIENT#*/} = ${MAX_CIDR} ]; then + # Skip OE special connections and direct host-host connections + if [ "${PLUTO_PEER_CLIENT_NET}" = "0.0.0.0" -o \ + "${PLUTO_PEER_CLIENT_NET}" = "::" -o \ + "${PLUTO_PEER_CLIENT_NET}" = "${PLUTO_PEER}" -o \ + "${PLUTO_MY_CLIENT_NET}" = "${PLUTO_ME}" ] + then + return 0 + fi + # check if client is routeable + if ip -${FAMILY} -o route get ${PLUTO_PEER_CLIENT_NET} 2>/dev/null | \ + grep -E -q -s -v " via |^local" + then + iface=$(ip -${FAMILY} -o route get ${PLUTO_PEER_CLIENT_NET} 2>/dev/null | \ + awk '{print $3}') + if [ -r /sys/class/net/${iface}/address ]; then + macaddr=$(cat /sys/class/net/${iface}/address) + fi + # add/remove arp entry for the client on ethernet devices only + if [ -n "${macaddr}" ]; then + if [ "${cmd}" = "add" ]; then + ip -${FAMILY} neigh add proxy ${PLUTO_PEER_CLIENT_NET} dev ${iface} \ + lladdr ${macaddr} nud permanent + # Force routing, required for proxyarp to work + PROXY_ARP_ROUTE=yes + export PROXY_ARP_ROUTE + else + ip -${FAMILY} neigh del proxy ${PLUTO_PEER_CLIENT_NET} dev ${iface} + fi + fi + fi + fi +} + +do_ip() +{ + local cmd="$1" + oops="$(eval ${cmd} 2>&1)" + st=$? + + if [ -z "${oops}" -a ${st} -ne 0 ]; then + oops="silent error, exit status ${st}" + fi + + case "${oops}" in + 'RTNETLINK answers: No such process'*) + # should not happen, but ... ignore if the + # route was already removed + oops="" + st=0 + ;; + esac + + if [ -n "${oops}" -a ${st} -ne 0 ]; then + echo "$0: doroute \"${cmd}\" failed (${oops})" >&2 + fi + + return ${st} +} + +doroute() { + local cmd + local esp_nexthop + local esp_peer_interface + local espipro + local ipru + local route_table + local oops + local parms + local parms2 + local st + local xfrmi_route + local xfrmi_rule + cmd=${1} + route_table=50 + st=0 + xfrmi_route="${PLUTO_XFRMI_ROUTE}" + + if [ ${cmd} != del ]; then + oops="$(ip -${FAMILY} route get ${PLUTO_PEER_CLIENT_NET} 2>&1)" + case "${oops}" in + 'RTNETLINK answers: No route to host'*) + if [ -z "${PLUTO_XFRMI_ROUTE}" ]; then + ROUTE=yes # Routing is mandatory for IPsec + fi + ;; + esac + fi + + if [ -n "${PLUTO_XFRMI_FWMARK}" ]; then + xfrmi_rule=yes # we have to add "ip rules" and "ip route table" + ROUTE=no # xfrmi_route will add the route + fi + + # skip routing if it's not enabled or necessary + if [ -z "${PLUTO_MY_SOURCEIP}" -a \ + -z "${PLUTO_MTU}" -a \ + "${PROXY_ARP_ROUTE}" != yes -a \ + "${cmd}" != "del" ] + then + PROXY_ARP_ROUTE=no + fi + + if [ -n "${PLUTO_MY_SOURCEIP}" -o -n "${PLUTO_MTU}" ]; then + ROUTE=yes + fi + + if [ "${PLUTO_PEER_CLIENT}" = "${PLUTO_MY_CLIENT}" -a \ + "${PLUTO_XFRMI_ROUTE}" = yes ] + then + xfrmi_route="samesubnets"; + echo "leftsubet == rightsubnet = ${PLUTO_PEER_CLIENT} cannot add route" + fi + + parms="${PLUTO_PEER_CLIENT}" + parms2=${IPRARGS} + # nexthop is not needed on ppp interfaces. unset it to make cases + # work, where left is set but no leftnexthop (e.g. left=%defaultroute) + if ip link show "${PLUTO_INTERFACE%:*}" | grep -q POINTOPOINT; then + POINTPOINT=yes + fi + # use nexthop if nexthop is not %direct and POINTPOINT is not set + if [ "${PLUTO_NEXT_HOP}" != "${PLUTO_PEER}" -a -z "${POINTPOINT}" ]; then + # XFRM interface needs no nexthop + if [ -z "${PLUTO_XFRMI_ROUTE}" ]; then + parms2="via ${PLUTO_NEXT_HOP}" + fi + esp_nexthop="via ${PLUTO_NEXT_HOP} " + fi + # route via proper interface according to routing table + if [ "${cmd}" = "del" ]; then + case "${PLUTO_PEER_CLIENT}" in + "0.0.0.0/0") + # in case of default route we use half routes + peer_interface=$(ip -${FAMILY} -o route list exact 0.0.0.0/1 | \ + sed "s/^.*dev \([^ ]*\) .*/\1/") + ;; + "::/0") + # in case of default route we use half routes + peer_interface=$(ip -${FAMILY} -o route list exact 2000::/3 | \ + sed "s/^.*dev \([^ ]*\) .*/\1/") + ;; + *) + peer_interface=$(ip -${CLIENT_FAMILY} -o route get ${PLUTO_PEER_CLIENT_NET} | \ + sed "s/^.*dev \([^ ]*\) .*/\1/") + ;; + esac + else + peer_interface=$(ip -o route get ${PLUTO_NEXT_HOP} | \ + sed "s/^.*dev \([^ ]*\) .*/\1/") + fi + + esp_peer_interface=$(ip -${FAMILY} -o route get ${PLUTO_NEXT_HOP} \ + from ${PLUTO_ME} | sed "s/^.*\(dev [^ ]*\) .*/\1/") + if [ -z "${esp_peer_interface}" ]; then + esp_peer_interface="dev ${PLUTO_INTERFACE}" + fi + + if [ -z "${peer_interface}" ]; then + peer_interface=${PLUTO_INTERFACE} + fi + + if [ "${PLUTO_XFRMI_ROUTE}" = "yes" ]; then + peer_interface=${PLUTO_VIRT_INTERFACE} + fi + + if [ -n "${VTI_IFACE}" ]; then + addsource + peer_interface="${VTI_IFACE}" + fi + + parms2="${parms2}${PLUTO_MTU:+ mtu ${PLUTO_MTU}}" + parms2="${parms2}${PLUTO_METRIC:+ metric ${PLUTO_METRIC}} ${IPROUTEARGS}" + + parms2="${parms2} dev ${peer_interface%:*}" + + # make sure we have sourceip locally in this machine + if [ "${cmd}" = "replace" -a -n "${PLUTO_MY_SOURCEIP}" ]; then + addsource + # use sourceip as route default source + parms2="${parms2} src ${PLUTO_MY_SOURCEIP}" + fi + + case "${PLUTO_PEER_CLIENT}" in + "0.0.0.0/0") + # need to provide route that eclipses default, without + # replacing it. + it="ip -${FAMILY} route ${cmd} 0.0.0.0/1 ${parms2} && \ + ip -${FAMILY} route ${cmd} 128.0.0.0/1 ${parms2}" + ;; + "::/0") + # need to provide route that eclipses default, without + # replacing it. + it="ip -${FAMILY} route ${cmd} 2000::/3 ${parms2}" + ;; + *) + it="ip -${CLIENT_FAMILY} route ${cmd} ${parms} ${parms2}" + ;; + esac + + if [ "${ROUTE}" = yes -o \ + "${xfrmi_route}" = yes -o \ + "${PROXY_ARP_ROUTE}" = yes ] + then + do_ip "${it}" + st=$? + if [ ${st} -ne 0 ]; then + return ${st} + fi + fi + + if [ "${xfrmi_rule}" = "yes" ]; then + espipro="ip -${FAMILY} route ${cmd} ${PLUTO_PEER}/${MAX_CIDR} ${esp_nexthop} ${esp_peer_interface%:*} table ${route_table}" + do_ip "${espipro}" + + st=$? + if [ ${st} -ne 0 ]; then + return ${st} + fi + + iprulecmd="${cmd}" + if [ "${cmd}" = "replace" ]; then + iprulecmd="add" + fi + + ipru="ip -${FAMILY} rule ${iprulecmd} prio 100 to ${parms}" + ipru="${ipru} fwmark ${PLUTO_XFRMI_FWMARK} lookup ${route_table}" + + do_ip "${ipru}" + st=$? + if [ ${st} -ne 0 ]; then + return ${st} + fi + + fi + return 0 +} + +# TODO: We need to specify CIDR mask but our _MASK variables are in old school format +# TODO: Exclude udp 4500 traffic +addnflog() { + if [ -n "${NFLOG}" ]; then + iptables -I OUTPUT -m policy --dir out --pol ipsec \ + -s ${PLUTO_MY_CLIENT} -d ${PLUTO_PEER_CLIENT} \ + -j NFLOG --nflog-group ${NFLOG} --nflog-prefix ${PLUTO_CONNECTION} + iptables -I INPUT -m policy --dir in --pol ipsec \ + -s ${PLUTO_PEER_CLIENT} -d ${PLUTO_MY_CLIENT} \ + -j NFLOG --nflog-group ${NFLOG} --nflog-prefix ${PLUTO_CONNECTION} + fi +} + +delnflog() { + if [ -n "${NFLOG}" ]; then + iptables -D OUTPUT -m policy --dir out --pol ipsec \ + -s ${PLUTO_MY_CLIENT} -d ${PLUTO_PEER_CLIENT} \ + -j NFLOG --nflog-group ${NFLOG} --nflog-prefix ${PLUTO_CONNECTION} + iptables -D INPUT -m policy --dir in --pol ipsec \ + -s ${PLUTO_PEER_CLIENT} -d ${PLUTO_MY_CLIENT} \ + -j NFLOG --nflog-group ${NFLOG} --nflog-prefix ${PLUTO_CONNECTION} + fi +} + +addvtiiface() { + if [ -n "${VTI_IFACE}" ]; then + if [ -z "${CONNMARK_IN}" -o -z "${CONNMARK_OUT}" ]; then + echo "vti-interface option ignored because no mark was configured" + else + if [ ! -d "/proc/sys/net/ipv4/conf/${VTI_IFACE}" ]; then + # echo "creating vti interface" + vtipeer="${PLUTO_PEER}" + if [ "${PLUTO_CONN_KIND}" = CK_INSTANCE -o "${VTI_SHARED}" = "yes" ]; then + vtipeer="0.0.0.0" + fi + ip tunnel add ${VTI_IFACE} mode vti local ${PLUTO_ME} \ + remote ${vtipeer} okey ${CONNMARK_OUT%/*} \ + ikey ${CONNMARK_IN%/*} + sysctl -w net.ipv4.conf.${VTI_IFACE}.disable_policy=1 + sysctl -w net.ipv4.conf.${VTI_IFACE}.rp_filter=0 + sysctl -w net.ipv4.conf.${VTI_IFACE}.forwarding=1 + if [ -n "${VTI_IP}" ]; then + ip addr add ${VTI_IP} dev ${VTI_IFACE} + fi + ip link set ${VTI_IFACE} up + else + # check there was no conflict if we are sharing - might be sensitive to /sbin/ip differences + if [ "${VTI_SHARED}" = yes ]; then + #test: ip/ip remote 3.4.5.6 local 1.2.3.4 ttl inherit key 5 + cur="$(ip tun show ${VTI_IFACE})" + new="${VTI_IFACE}: ip/ip remote any local ${PLUTO_ME} ttl inherit key ${CONNMARK_OUT%/*}" + if [ "${cur}" != "${new}" ]; then + echo "vti interface \"${VTI_IFACE}\" already exists with conflicting setting" + echo "existing: ${cur}" + echo "wanted : ${new}" + else + # temp debug + echo "vti interface already exists with identical parameters, OK" + fi + else + echo "vti interface \"${VTI_IFACE}\" already exists with conflicting setting (perhaps need vti-sharing=yes ?" + fi + fi + fi + fi +} + +addvti() { + if [ -n "${VTI_IFACE}" ]; then + if [ -z "${CONNMARK_IN}" -o -z "${CONNMARK_OUT}" ]; then + echo "vti-interface option ignored because no mark was configured" + else + if [ "${VTI_ROUTING}" = yes ]; then + # Tuomo should improve this with using ${PLUTO_MY_CLIENT_NET} + # echo "setting up vti routing" + r=add + ip route list | grep -q "${PLUTO_PEER_CLIENT%/*}" && r=change + if [ "${r}" = change ]; then + # resolve LAN conflict by forcing host route for default gw + gw="$(ip ro li | grep ^default | awk '{ print $3;}')" + gwdev="$(ip ro li | grep ^default | awk '{ print $5;}')" + # echo "ip route add ${gw} dev ${gwdev}" + ip route add ${gw} dev ${gwdev} >/dev/null ||: + fi + srcip="" + if [ -n "${PLUTO_MY_SOURCEIP}" ]; then + srcip=" src ${PLUTO_MY_SOURCEIP}" + fi + # echo "ip route ${r} ${PLUTO_PEER_CLIENT} dev ${VTI_IFACE} ${srcip}" + ip route ${r} ${PLUTO_PEER_CLIENT} dev ${VTI_IFACE} ${srcip} + echo "done ip route" + fi + fi + fi +} + +delvti() { + if [ -n "${VTI_IFACE}" -a -d /proc/sys/net/ipv4/conf/${VTI_IFACE} ]; then + if [ "${VTI_ROUTING}" = yes ]; then + ip route del ${PLUTO_PEER_CLIENT} dev ${VTI_IFACE} \ + src ${PLUTO_MY_SOURCEIP} ||: + fi + # TODO: we can't delete vti interface because we don't have proper reference + # counting. + #if [ "${VTI_SHARED}" = no -a "${PLUTO_CONN_KIND}" != CK_INSTANCE ]; then + # ip tun del ${VTI_IFACE} ||: + #fi + fi +} + +# Client Address Translation CAT +addcat() { + if [ -n "${CAT}" ] && [ "${PLUTO_MY_CLIENT_NET}" != "0.0.0.0" ] ; then + iptables -t nat -I POSTROUTING -m policy --dir out --pol ipsec \ + -d ${PLUTO_PEER_CLIENT} -j SNAT --to-source ${PLUTO_MY_CLIENT_NET} + iptables -t nat -I PREROUTING -m policy --dir in --pol ipsec \ + -d ${PLUTO_MY_CLIENT_NET} -s ${PLUTO_PEER_CLIENT} \ + -j DNAT --to-destination ${PLUTO_ME} + fi +} + +delcat() { + if [ -n "${CAT}" ]; then + iptables -t nat -D PREROUTING -m policy --dir in --pol ipsec \ + -d ${PLUTO_MY_CLIENT_NET} -s ${PLUTO_PEER_CLIENT} \ + -j DNAT --to-destination ${PLUTO_ME} + iptables -t nat -D POSTROUTING -m policy --dir out --pol ipsec \ + -d ${PLUTO_PEER_CLIENT} -j SNAT --to-source ${PLUTO_MY_CLIENT_NET} + fi +} + +# the big choice +case "${PLUTO_VERB}" in + prepare-host|prepare-client) + addvtiiface + ;; + route-host|route-client) + # connection to me or my client subnet being routed + addvti + uproute + addnflog + ;; + unroute-host|unroute-client) + # connection to me or my client subnet being unrouted + downroute + delsource + ;; + up-host) + # connection to me coming up + # If you are doing a custom version, firewall commands go here. + ;; + down-host) + # connection to me going down + downrule + delnflog + delcat + delvti + # If you are doing a custom version, firewall commands go here. + ;; + up-client) + # connection to my client subnet coming up + addvtiiface + updateresolvconf + addcat + addsource + notifyNM connect + addvti + # If you are doing a custom version, firewall commands go here. + ;; + down-client) + # connection to my client subnet going down + downrule + delnflog + delcat + delvti + restoreresolvconf + notifyNM disconnect + # If you are doing a custom version, firewall commands go here. + ;; + # + # IPv6 + # + prepare-host-v6|prepare-client-v6) + # prepare client for connection + ;; + route-host-v6|route-client-v6) + # connection to me or my client subnet being routed + uproute + ;; + unroute-host-v6|unroute-client-v6) + # connection to me or my client subnet being unrouted + downroute + delsource + ;; + up-host-v6) + # connection to me coming up + # If you are doing a custom version, firewall commands go here. + ;; + down-host-v6) + # connection to me going down + # If you are doing a custom version, firewall commands go here. + ;; + up-client-v6) + # connection to my client subnet coming up + addsource + updateresolvconf + notifyNM connect + # If you are doing a custom version, firewall commands go here. + ;; + down-client-v6) + # connection to my client subnet going down + restoreresolvconf + notifyNM disconnect + # If you are doing a custom version, firewall commands go here. + ;; + *) echo "$0: unknown verb \"${PLUTO_VERB}\" or parameter \"${1}\"" >&2 + exit 1 + ;; +esac diff --git a/usr/lib/systemd/system/freed-ipsec-roaming@.service b/usr/lib/systemd/system/freed-ipsec-roaming@.service deleted file mode 100644 index 374004b..0000000 --- a/usr/lib/systemd/system/freed-ipsec-roaming@.service +++ /dev/null @@ -1,27 +0,0 @@ -[Unit] -Description=Roaming IPSec to '%i' -After=network-online.target -Wants=network-online.target - -After=unbound.service -Requires=unbound.service - -After=ipsec.service -PartOf=ipsec.service -Requires=ipsec.service - -StartLimitIntervalSec=60 -StartLimitBurst=20 - -[Service] -Type=oneshot -RemainAfterExit=yes -ExecStart=ipsec auto --start %i -ExecStop=ipsec auto --delete %i - -Restart=on-failure -RestartSec=3 - -[Install] -WantedBy=multi-user.target -RequiredBy=ipsec.service diff --git a/usr/lib/systemd/system/freed-onresume.service b/usr/lib/systemd/system/freed-onresume.service deleted file mode 100644 index 7b7dc54..0000000 --- a/usr/lib/systemd/system/freed-onresume.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=On resume actions -After=sleep.target -After=network-online.target -Wants=network-online.target - -[Service] -Type=oneshot -ExecStartPre=sleep 3 -ExecStart=/usr/bin/systemctl restart ipsec - -[Install] -WantedBy=sleep.target - diff --git a/usr/lib/systemd/system/freed-onsuspend.service b/usr/lib/systemd/system/freed-onsuspend.service deleted file mode 100644 index 47afcc2..0000000 --- a/usr/lib/systemd/system/freed-onsuspend.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=On suspend actions -Before=sleep.target - -[Service] -Type=oneshot -ExecStart=/usr/bin/systemctl stop ipsec -ExecStartPost=/usr/bin/sleep 5 - -[Install] -WantedBy=sleep.target diff --git a/usr/libexec/ipsec/_updown.host4client6 b/usr/libexec/ipsec/_updown.host4client6 deleted file mode 100755 index 2f748a6..0000000 --- a/usr/libexec/ipsec/_updown.host4client6 +++ /dev/null @@ -1,977 +0,0 @@ -#!/bin/sh -# -# default updown script for use with NETKEY(XFRM) -# -# Copyright (C) 2003-2004 Nigel Metheringham -# Copyright (C) 2002-2007 Michael Richardson -# Copyright (C) 2007-2008 Paul Wouters -# Copyright (C) 2003-2020 Tuomo Soini -# Copyright (C) 2011-2016 Paul Wouters -# Copyright (C) 2016 Antony Antony -# -# 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 2 of the License, or (at your -# option) any later version. See . -# -# 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. - -# CAUTION: Installing a new version of Libreswan will install a new -# copy of this script, wiping out any custom changes you make. If -# you need changes, make a copy of this under another name, and customize -# that, and use the (left/right)updown= parameters in ipsec.conf to make -# Libreswan use your modified updown script instead of this default one. - -test ${IPSEC_INIT_SCRIPT_DEBUG} && set -v -x - -LC_ALL=C -export LC_ALL - -# Things that this script gets (from ipsec_pluto(8) man page) -# -# -# PLUTO_VERSION -# indicates what version of this interface is being -# used. This document describes version 1.1. This -# is upwardly compatible with version 1.0. -# -# PLUTO_VERB -# specifies the name of the operation to be performed -# (prepare-host, prepare-client, up-host, up-client, -# down-host, or down-client). If the address family -# for security gateway to security gateway -# communications is IPv6, then a suffix of -v6 is added -# to the verb. -# -# PLUTO_CONNECTION -# is the name of the connection for which we are -# routing. -# -# PLUTO_CONN_POLICY -# the policy of the connection, as in: -# RSASIG+ENCRYPT+TUNNEL+PFS+DONTREKEY+OPPORTUNISTIC -# +failureDROP+lKOD+rKOD -# -# PLUTO_NEXT_HOP -# is the next hop to which packets bound for the peer -# must be sent. -# -# PLUTO_INTERFACE -# is the name of the real interface used by encrypted traffic and IKE traffic -# -# PLUTO_ME -# is the IP address of our host. -# -# PLUTO_METRIC -# is the metric to set for the route -# -# PLUTO_MTU -# is the mtu to set for the route -# -# PLUTO_MY_CLIENT -# is the IP address / count of our client subnet. If -# the client is just the host, this will be the -# host's own IP address / mask (where max is 32 for -# IPv4 and 128 for IPv6). -# -# PLUTO_MY_CLIENT_NET -# is the IP address of our client net. If the client -# is just the host, this will be the host's own IP -# address. -# -# PLUTO_MY_CLIENT_MASK -# is the mask for our client net. If the client is -# just the host, this will be 255.255.255.255. -# -# PLUTO_MY_SOURCEIP -# if non-empty, then the source address for the route will be -# set to this IP address. -# -# PLUTO_MY_PROTOCOL -# is the protocol for this connection. Useful for -# firewalling. -# -# PLUTO_MY_PORT -# is the port. Useful for firewalling. -# -# PLUTO_PEER -# is the IP address of our peer. -# -# PLUTO_PEER_CLIENT -# is the IP address / count of the peer's client subnet. -# If the client is just the peer, this will be -# the peer's own IP address / mask (where max is 32 -# for IPv4 and 128 for IPv6). -# -# PLUTO_PEER_CLIENT_NET -# is the IP address of the peer's client net. If the -# client is just the peer, this will be the peer's -# own IP address. -# -# PLUTO_PEER_CLIENT_MASK -# is the mask for the peer's client net. If the -# client is just the peer, this will be -# 255.255.255.255. -# -# PLUTO_PEER_PROTOCOL -# is the protocol set for remote end with port -# selector. -# -# PLUTO_PEER_PORT -# is the peer's port. Useful for firewalling. -# -# PLUTO_CFG_CLIENT=0|1 -# is MODECFG or IKEv2 Config client. -# -# PLUTO_CFG_SERVER=0|1 -# is MODECFG or IKEv2 Config server. -# -# PLUTO_CONNECTION_TYPE -# -# PLUTO_CONN_ADDRFAMILY -# is the family type, "ipv4" or "ipv6" -# -# PLUTO_PROTO_STACK -# is the local IPsec kernel stack used, eg NETKEY, NOSTACK -# -# PLUTO_IS_PEER_CISCO=0|1 -# remote server type is cisco. Add support for cisco extensions -# when used with xauth. -# -# PLUTO_NM_CONFIGURED=0|1 -# is NetworkManager used for resolv.conf update -# -# PLUTO_SA_REQID -# When using KAME or XFRM/NETKEY, the IPsec SA reqid base value. -# ESP/AH out is base, ESP/AH in = base + 1 -# IPCOMP is base + 2 plus for inbound + 1 -# -# PLUTO_SA_TYPE -# The type of IPsec SA (ESP or AH) -# -# PLUTO_USERNAME -# The username (XAUTH or GSSAPI) that was authenticated (if any) -# for this SA -# -# PLUTO_VIRT_INTERFACE -# is the name of ipsec interface used by clear traffic in/out -# -# -# XAUTH_FAILED -# If xauthfail=soft this will be set to 1 if XAUTH authentication -# failed. If xauthfail=hard, the updown scripts never run. -# -# CONNMARK -# If mark= is set on the connection, this variable will be -# set with the value. It can be used for iptables or VTI. -# -# VTI_IFAC=iface -# Name of VTI interface to create -# -# VTI_ROUTING=yes|no -# Whether or not to perform ip rule and ip route commands -# covering the IPsec SA address ranges to route those packets -# into the VTI_IFACE interface. This should be enabled unless -# the IPsec SA covers 0.0.0.0/0 <-> 0.0.0.0/0 -# -# VTI_SHARED=yes|no -# Whether or not more conns (or instances) share a VTI device. -# If not shared, the VTI device is deleted when tunnel goes down. -# -# SPI_IN / SPI_OUT -# The inbound and outbound SPI's of the connection. - -# rpm based systems -if [ -f /etc/sysconfig/pluto_updown ]; then - . /etc/sysconfig/pluto_updown -# deb based systems -elif [ -f /etc/default/pluto_updown ]; then - . /etc/default/pluto_updown -fi - -BACKUP_RESOLV_CONF=/run/pluto/libreswan-resolv-conf-backup -ETC_RESOLV_CONF=/etc/resolv.conf - -case "${PLUTO_CONN_ADDRFAMILY}" in - ipv4) - FAMILY=4 - MAX_CIDR=32 - SCOPE=50 # Use scope 50 to verify ip was added by addsource() - ;; - ipv6) - FAMILY=6 - MAX_CIDR=128 - SCOPE=global - ;; - *) - echo "unknown address family \"${PLUTO_CONN_ADDRFAMILY}\"" >&2 - exit 1 - ;; -esac -export FAMILY MAX_CIDR SCOPE - -# 2022-09-03 - mbaudier : Hack when having an IPv6 subnet -export CLIENT_FAMILY=6 -export CLIENT_MAX_CIDR=128 - -# Ignore parameter custom -if [ "${1}" = "custom" ]; then - shift -fi - -while [ $# -gt 0 ]; do - case ${1} in - --route) - case ${2} in - [Yy]*) - ROUTE=yes - PROXY_ARP_ROUTE=no - ;; - *) - ROUTE= - PROXY_ARP_ROUTE= - ;; - esac - shift; shift - ;; - --iproute) - IPRARGS="${2}" - shift; shift - ;; - *) - echo "$0: Unknown argument \"${1}\"" >&2 - exit 1 - ;; - esac -done - -# utility functions for route manipulation -# Meddling with this stuff should not be necessary and requires great care. -uproute() { - doproxyarp add - doroute replace -} - -downroute() { - doroute del - doproxyarp delete -} - -downrule() { - if [ -n "${PLUTO_MY_SOURCEIP}" -a 0${PLUTO_IS_PEER_CISCO} -eq 1 ]; then - doroute del - fi -} - -updateresolvconf() { - local domain - local nameserver - local new_nameserver - local new_resolv_conf - local new_search - local orig_domain - local orig_nameserver - local rc - rc=0 - if [ 0${PLUTO_CFG_CLIENT} -eq 0 ]; then - return ${rc} - fi - if [ -n "$(pidof unbound)" -a \ - -n "${PLUTO_PEER_DNS_INFO}" -a \ - -n "${PLUTO_PEER_DOMAIN_INFO}" ] - then - for domain in ${PLUTO_PEER_DOMAIN_INFO}; do - echo "updating local nameserver for ${domain} with ${PLUTO_PEER_DNS_INFO}" - unbound-control forward_add ${domain} \ - ${PLUTO_PEER_DNS_INFO} - unbound-control flush_zone ${domain} - unbound-control flush_requestlist - done - rc=$? - elif [ 0${PLUTO_NM_CONFIGURED} -eq 0 -a \ - -n "${PLUTO_PEER_DNS_INFO}" ] - then - echo "updating resolvconf" - - if [ ! -e "${ETC_RESOLV_CONF}" ]; then - echo "resolv.conf does not exist, so doing nothing" - return 0 - fi - - if [ -e "${BACKUP_RESOLV_CONF}" ]; then - if grep -q Libreswan "${ETC_RESOLV_CONF}"; then - echo "Current resolv.conf is generated by Libreswan, and backup resolv.conf already exists, so doing nothing" - return 0 - else - echo "backup resolv.conf exists, but current resolv.conf is not generated by Libreswan" - fi - fi - - rm -f -- "${BACKUP_RESOLV_CONF}" - cp -- "${ETC_RESOLV_CONF}" "${BACKUP_RESOLV_CONF}" - - new_resolv_conf="# Generated by Libreswan (IPsec)" - - orig_domain="$(grep ^domain "${ETC_RESOLV_CONF}" 2>/dev/null | \ - awk '{ print $2 }')" - - orig_search=$(grep ^search "${ETC_RESOLV_CONF}" 2>/dev/null | \ - sed 's/^search[[:space:]]\+//;s/[[:space:]]*\#.*//') - - if [ -n "${orig_domain}" ]; then - new_resolv_conf="${new_resolv_conf} -domain ${orig_domain}" - fi - - if [ -n "${orig_search}" ]; then - new_search="${orig_search}" - elif [ -n "${orig_domain}" ]; then - new_search="${orig_domain}" - fi - - if [ -n "${PLUTO_PEER_DOMAIN_INFO}" ]; then - if [ -n "${new_search}" ]; then - new_search=$(echo $(echo "${new_search} ${PLUTO_PEER_DOMAIN_INFO}" | tr [:space:] '\n' | awk '!a[$0]++')) - else - new_search="${PLUTO_PEER_DOMAIN_INFO}" - fi - fi - - if [ -n "${new_search}" ]; then - new_resolv_conf="${new_resolv_conf} -search ${new_search}" - fi - - orig_nameserver=$(grep -m 1 ^nameserver "${ETC_RESOLV_CONF}" | \ - sed 's/^nameserver[[:space:]]\+//;s/[[:space:]]*\#.*//') - if [ -n "${orig_nameserver}" ]; then - new_nameserver=$(echo $(echo "${PLUTO_PEER_DNS_INFO} ${orig_nameserver}" | tr [:space:] '\n' | awk '!a[$0]++')) - else - new_nameserver="${PLUTO_PEER_DNS_INFO}" - fi - - for nameserver in ${new_nameserver}; do - new_resolv_conf="${new_resolv_conf} -nameserver ${nameserver}" - done - - echo "${new_resolv_conf}" > "${ETC_RESOLV_CONF}" - rc=$? - fi - return ${rc} -} - -restoreresolvconf() { - local domain - local rc - rc=0 - if [ 0${PLUTO_CFG_CLIENT} -eq 0 ]; then - return ${rc} - fi - if [ -n "$(pidof unbound)" -a \ - -n "${PLUTO_PEER_DNS_INFO}" -a \ - -n "${PLUTO_PEER_DOMAIN_INFO}" ] - then - for domain in ${PLUTO_PEER_DOMAIN_INFO}; do - echo "flushing local nameserver of ${domain}" - unbound-control forward_remove ${domain} - unbound-control flush_zone ${domain} - unbound-control flush_requestlist - done - rc=$? - elif [ 0${PLUTO_NM_CONFIGURED} -eq 0 ]; then - # We only restore if current resolv.conf is made by us. - if grep -q Libreswan "${ETC_RESOLV_CONF}" 2>/dev/null; then - # And if there is a backup... - if [ -e "${BACKUP_RESOLV_CONF}" ]; then - echo "restoring resolvconf" - else - return 0 - fi - cp -- "${BACKUP_RESOLV_CONF}" "${ETC_RESOLV_CONF}" - fi - rm -f -- "${BACKUP_RESOLV_CONF}" - rc=0 - fi - return ${rc} -} - -notifyNM() { - # This will be called whenever a connection is established or - # fails to establish (either phase 1, xauth phase, or phase 2) - # or whenever an already established connection is being terminated. - # This will send a signal to NetworkManager over dbus so that NM - # can keep track of the coonnections. - - if [ 0${PLUTO_NM_CONFIGURED} -eq 1 ]; then - echo "sending $1 signal to NetworkManager" - libreswan_reason=$1 - export libreswan_reason - export PLUTO_PEER_DOMAIN_INFO - export PLUTO_PEER_DNS_INFO - export PLUTO_PEER_BANNER - export PLUTO_MY_SOURCEIP - export PLUTO_PEER - [ -x /usr/libexec/nm-libreswan-service-helper ] && \ - /usr/libexec/nm-libreswan-service-helper - fi - return 0 -} - -addsource() { - local interface - local st - interface=lo - st=0 - - if [ -z "${PLUTO_MY_SOURCEIP}" ]; then - return ${st} - fi - # check if given sourceip is local and add as alias if not - if ! ip -${CLIENT_FAMILY} -o route get ${PLUTO_MY_SOURCEIP} | grep -q ^local; then - if [ -n "${VTI_IFACE}" -a "${VTI_ROUTING}" = yes ]; then - interface="${VTI_IFACE}" - elif [ -n "${PLUTO_XFRMI_ROUTE}" ]; then - interface=${PLUTO_VIRT_INTERFACE} - fi - it="ip addr add ${PLUTO_MY_SOURCEIP}/${CLIENT_MAX_CIDR} dev ${interface} scope ${SCOPE}" - oops="$(eval ${it} 2>&1)" - st=$? - if [ -z "${oops}" -a ${st} -ne 0 ]; then - oops="silent error, exit status ${st}" - fi - case "${oops}" in - 'RTNETLINK answers: File exists'*) - # should not happen, but ... ignore if the - # address was already assigned on interface - oops="" - st=0 - ;; - esac - if [ -n "${oops}" -o ${st} -ne 0 ]; then - echo "$0: addsource \"${it}\" failed (${oops})" >&2 - fi - fi - return ${st} -} - -delsource() { - local interface - local oops - local st - interface=lo - st=0 - if [ -z "${PLUTO_MY_SOURCEIP}" ]; then - return ${st} - fi - # Remove source ip if it's not used any more. - if [ -z "$(ip -${CLIENT_FAMILY} -o route list src ${PLUTO_MY_SOURCEIP})" ]; then - if [ -n "${VTI_IFACE}" -a "${VTI_ROUTING}" = yes ]; then - interface="${VTI_IFACE}" - elif [ -n "${PLUTO_XFRMI_ROUTE}" ]; then - interface=${PLUTO_VIRT_INTERFACE} - fi - # If there is no ip we just return - if ! ip -${FAMILY} -o addr list dev ${interface} scope ${SCOPE} | \ - grep -q ${PLUTO_MY_SOURCEIP}/${CLIENT_MAX_CIDR} - then - return ${st} - fi - - if [ -n "${PLUTO_MOBIKE_EVENT}" ] ; then - return ${st} - fi - - it="ip -${CLIENT_FAMILY} addr del ${PLUTO_MY_SOURCEIP}/${CLIENT_MAX_CIDR} dev ${interface}" - oops="$(eval ${it} 2>&1)" - st=$? - if [ -z "${oops}" -a ${st} -ne 0 ]; then - oops="silent error, exit status ${st}" - fi - case "${oops}" in - 'RTNETLINK answers: File exists'*) - # should not happen, but ... ignore if the - # address was already assigned on interface - oops="" - st=0 - ;; - 'RTNETLINK answers: Cannot assign'*) - # Address is not there to remove or is there with different - # netmask and in that case we must not remove it so we ignore - # the error. - oops="" - st=0 - ;; - esac - if [ -n "${oops}" -o ${st} -ne 0 ]; then - echo "$0: delsource \"${it}\" failed (${oops})" >&2 - fi - fi - return ${st} -} - -doproxyarp() { - local cmd - local iface - cmd=${1} - # Check if client has a single ip only client net - if [ ${PLUTO_PEER_CLIENT#*/} = ${MAX_CIDR} ]; then - # Skip OE special connections and direct host-host connections - if [ "${PLUTO_PEER_CLIENT_NET}" = "0.0.0.0" -o \ - "${PLUTO_PEER_CLIENT_NET}" = "::" -o \ - "${PLUTO_PEER_CLIENT_NET}" = "${PLUTO_PEER}" -o \ - "${PLUTO_MY_CLIENT_NET}" = "${PLUTO_ME}" ] - then - return 0 - fi - # check if client is routeable - if ip -${FAMILY} -o route get ${PLUTO_PEER_CLIENT_NET} 2>/dev/null | \ - grep -E -q -s -v " via |^local" - then - iface=$(ip -${FAMILY} -o route get ${PLUTO_PEER_CLIENT_NET} 2>/dev/null | \ - awk '{print $3}') - if [ -r /sys/class/net/${iface}/address ]; then - macaddr=$(cat /sys/class/net/${iface}/address) - fi - # add/remove arp entry for the client on ethernet devices only - if [ -n "${macaddr}" ]; then - if [ "${cmd}" = "add" ]; then - ip -${FAMILY} neigh add proxy ${PLUTO_PEER_CLIENT_NET} dev ${iface} \ - lladdr ${macaddr} nud permanent - # Force routing, required for proxyarp to work - PROXY_ARP_ROUTE=yes - export PROXY_ARP_ROUTE - else - ip -${FAMILY} neigh del proxy ${PLUTO_PEER_CLIENT_NET} dev ${iface} - fi - fi - fi - fi -} - -do_ip() -{ - local cmd="$1" - oops="$(eval ${cmd} 2>&1)" - st=$? - - if [ -z "${oops}" -a ${st} -ne 0 ]; then - oops="silent error, exit status ${st}" - fi - - case "${oops}" in - 'RTNETLINK answers: No such process'*) - # should not happen, but ... ignore if the - # route was already removed - oops="" - st=0 - ;; - esac - - if [ -n "${oops}" -a ${st} -ne 0 ]; then - echo "$0: doroute \"${cmd}\" failed (${oops})" >&2 - fi - - return ${st} -} - -doroute() { - local cmd - local esp_nexthop - local esp_peer_interface - local espipro - local ipru - local route_table - local oops - local parms - local parms2 - local st - local xfrmi_route - local xfrmi_rule - cmd=${1} - route_table=50 - st=0 - xfrmi_route="${PLUTO_XFRMI_ROUTE}" - - if [ ${cmd} != del ]; then - oops="$(ip -${FAMILY} route get ${PLUTO_PEER_CLIENT_NET} 2>&1)" - case "${oops}" in - 'RTNETLINK answers: No route to host'*) - if [ -z "${PLUTO_XFRMI_ROUTE}" ]; then - ROUTE=yes # Routing is mandatory for IPsec - fi - ;; - esac - fi - - if [ -n "${PLUTO_XFRMI_FWMARK}" ]; then - xfrmi_rule=yes # we have to add "ip rules" and "ip route table" - ROUTE=no # xfrmi_route will add the route - fi - - # skip routing if it's not enabled or necessary - if [ -z "${PLUTO_MY_SOURCEIP}" -a \ - -z "${PLUTO_MTU}" -a \ - "${PROXY_ARP_ROUTE}" != yes -a \ - "${cmd}" != "del" ] - then - PROXY_ARP_ROUTE=no - fi - - if [ -n "${PLUTO_MY_SOURCEIP}" -o -n "${PLUTO_MTU}" ]; then - ROUTE=yes - fi - - if [ "${PLUTO_PEER_CLIENT}" = "${PLUTO_MY_CLIENT}" -a \ - "${PLUTO_XFRMI_ROUTE}" = yes ] - then - xfrmi_route="samesubnets"; - echo "leftsubet == rightsubnet = ${PLUTO_PEER_CLIENT} cannot add route" - fi - - parms="${PLUTO_PEER_CLIENT}" - parms2=${IPRARGS} - # nexthop is not needed on ppp interfaces. unset it to make cases - # work, where left is set but no leftnexthop (e.g. left=%defaultroute) - if ip link show "${PLUTO_INTERFACE%:*}" | grep -q POINTOPOINT; then - POINTPOINT=yes - fi - # use nexthop if nexthop is not %direct and POINTPOINT is not set - if [ "${PLUTO_NEXT_HOP}" != "${PLUTO_PEER}" -a -z "${POINTPOINT}" ]; then - # XFRM interface needs no nexthop - if [ -z "${PLUTO_XFRMI_ROUTE}" ]; then - parms2="via ${PLUTO_NEXT_HOP}" - fi - esp_nexthop="via ${PLUTO_NEXT_HOP} " - fi - # route via proper interface according to routing table - if [ "${cmd}" = "del" ]; then - case "${PLUTO_PEER_CLIENT}" in - "0.0.0.0/0") - # in case of default route we use half routes - peer_interface=$(ip -${FAMILY} -o route list exact 0.0.0.0/1 | \ - sed "s/^.*dev \([^ ]*\) .*/\1/") - ;; - "::/0") - # in case of default route we use half routes - peer_interface=$(ip -${FAMILY} -o route list exact 2000::/3 | \ - sed "s/^.*dev \([^ ]*\) .*/\1/") - ;; - *) - peer_interface=$(ip -${CLIENT_FAMILY} -o route get ${PLUTO_PEER_CLIENT_NET} | \ - sed "s/^.*dev \([^ ]*\) .*/\1/") - ;; - esac - else - peer_interface=$(ip -o route get ${PLUTO_NEXT_HOP} | \ - sed "s/^.*dev \([^ ]*\) .*/\1/") - fi - - esp_peer_interface=$(ip -${FAMILY} -o route get ${PLUTO_NEXT_HOP} \ - from ${PLUTO_ME} | sed "s/^.*\(dev [^ ]*\) .*/\1/") - if [ -z "${esp_peer_interface}" ]; then - esp_peer_interface="dev ${PLUTO_INTERFACE}" - fi - - if [ -z "${peer_interface}" ]; then - peer_interface=${PLUTO_INTERFACE} - fi - - if [ "${PLUTO_XFRMI_ROUTE}" = "yes" ]; then - peer_interface=${PLUTO_VIRT_INTERFACE} - fi - - if [ -n "${VTI_IFACE}" ]; then - addsource - peer_interface="${VTI_IFACE}" - fi - - parms2="${parms2}${PLUTO_MTU:+ mtu ${PLUTO_MTU}}" - parms2="${parms2}${PLUTO_METRIC:+ metric ${PLUTO_METRIC}} ${IPROUTEARGS}" - - parms2="${parms2} dev ${peer_interface%:*}" - - # make sure we have sourceip locally in this machine - if [ "${cmd}" = "replace" -a -n "${PLUTO_MY_SOURCEIP}" ]; then - addsource - # use sourceip as route default source - parms2="${parms2} src ${PLUTO_MY_SOURCEIP}" - fi - - case "${PLUTO_PEER_CLIENT}" in - "0.0.0.0/0") - # need to provide route that eclipses default, without - # replacing it. - it="ip -${FAMILY} route ${cmd} 0.0.0.0/1 ${parms2} && \ - ip -${FAMILY} route ${cmd} 128.0.0.0/1 ${parms2}" - ;; - "::/0") - # need to provide route that eclipses default, without - # replacing it. - it="ip -${FAMILY} route ${cmd} 2000::/3 ${parms2}" - ;; - *) - it="ip -${CLIENT_FAMILY} route ${cmd} ${parms} ${parms2}" - ;; - esac - - if [ "${ROUTE}" = yes -o \ - "${xfrmi_route}" = yes -o \ - "${PROXY_ARP_ROUTE}" = yes ] - then - do_ip "${it}" - st=$? - if [ ${st} -ne 0 ]; then - return ${st} - fi - fi - - if [ "${xfrmi_rule}" = "yes" ]; then - espipro="ip -${FAMILY} route ${cmd} ${PLUTO_PEER}/${MAX_CIDR} ${esp_nexthop} ${esp_peer_interface%:*} table ${route_table}" - do_ip "${espipro}" - - st=$? - if [ ${st} -ne 0 ]; then - return ${st} - fi - - iprulecmd="${cmd}" - if [ "${cmd}" = "replace" ]; then - iprulecmd="add" - fi - - ipru="ip -${FAMILY} rule ${iprulecmd} prio 100 to ${parms}" - ipru="${ipru} fwmark ${PLUTO_XFRMI_FWMARK} lookup ${route_table}" - - do_ip "${ipru}" - st=$? - if [ ${st} -ne 0 ]; then - return ${st} - fi - - fi - return 0 -} - -# TODO: We need to specify CIDR mask but our _MASK variables are in old school format -# TODO: Exclude udp 4500 traffic -addnflog() { - if [ -n "${NFLOG}" ]; then - iptables -I OUTPUT -m policy --dir out --pol ipsec \ - -s ${PLUTO_MY_CLIENT} -d ${PLUTO_PEER_CLIENT} \ - -j NFLOG --nflog-group ${NFLOG} --nflog-prefix ${PLUTO_CONNECTION} - iptables -I INPUT -m policy --dir in --pol ipsec \ - -s ${PLUTO_PEER_CLIENT} -d ${PLUTO_MY_CLIENT} \ - -j NFLOG --nflog-group ${NFLOG} --nflog-prefix ${PLUTO_CONNECTION} - fi -} - -delnflog() { - if [ -n "${NFLOG}" ]; then - iptables -D OUTPUT -m policy --dir out --pol ipsec \ - -s ${PLUTO_MY_CLIENT} -d ${PLUTO_PEER_CLIENT} \ - -j NFLOG --nflog-group ${NFLOG} --nflog-prefix ${PLUTO_CONNECTION} - iptables -D INPUT -m policy --dir in --pol ipsec \ - -s ${PLUTO_PEER_CLIENT} -d ${PLUTO_MY_CLIENT} \ - -j NFLOG --nflog-group ${NFLOG} --nflog-prefix ${PLUTO_CONNECTION} - fi -} - -addvtiiface() { - if [ -n "${VTI_IFACE}" ]; then - if [ -z "${CONNMARK_IN}" -o -z "${CONNMARK_OUT}" ]; then - echo "vti-interface option ignored because no mark was configured" - else - if [ ! -d "/proc/sys/net/ipv4/conf/${VTI_IFACE}" ]; then - # echo "creating vti interface" - vtipeer="${PLUTO_PEER}" - if [ "${PLUTO_CONN_KIND}" = CK_INSTANCE -o "${VTI_SHARED}" = "yes" ]; then - vtipeer="0.0.0.0" - fi - ip tunnel add ${VTI_IFACE} mode vti local ${PLUTO_ME} \ - remote ${vtipeer} okey ${CONNMARK_OUT%/*} \ - ikey ${CONNMARK_IN%/*} - sysctl -w net.ipv4.conf.${VTI_IFACE}.disable_policy=1 - sysctl -w net.ipv4.conf.${VTI_IFACE}.rp_filter=0 - sysctl -w net.ipv4.conf.${VTI_IFACE}.forwarding=1 - if [ -n "${VTI_IP}" ]; then - ip addr add ${VTI_IP} dev ${VTI_IFACE} - fi - ip link set ${VTI_IFACE} up - else - # check there was no conflict if we are sharing - might be sensitive to /sbin/ip differences - if [ "${VTI_SHARED}" = yes ]; then - #test: ip/ip remote 3.4.5.6 local 1.2.3.4 ttl inherit key 5 - cur="$(ip tun show ${VTI_IFACE})" - new="${VTI_IFACE}: ip/ip remote any local ${PLUTO_ME} ttl inherit key ${CONNMARK_OUT%/*}" - if [ "${cur}" != "${new}" ]; then - echo "vti interface \"${VTI_IFACE}\" already exists with conflicting setting" - echo "existing: ${cur}" - echo "wanted : ${new}" - else - # temp debug - echo "vti interface already exists with identical parameters, OK" - fi - else - echo "vti interface \"${VTI_IFACE}\" already exists with conflicting setting (perhaps need vti-sharing=yes ?" - fi - fi - fi - fi -} - -addvti() { - if [ -n "${VTI_IFACE}" ]; then - if [ -z "${CONNMARK_IN}" -o -z "${CONNMARK_OUT}" ]; then - echo "vti-interface option ignored because no mark was configured" - else - if [ "${VTI_ROUTING}" = yes ]; then - # Tuomo should improve this with using ${PLUTO_MY_CLIENT_NET} - # echo "setting up vti routing" - r=add - ip route list | grep -q "${PLUTO_PEER_CLIENT%/*}" && r=change - if [ "${r}" = change ]; then - # resolve LAN conflict by forcing host route for default gw - gw="$(ip ro li | grep ^default | awk '{ print $3;}')" - gwdev="$(ip ro li | grep ^default | awk '{ print $5;}')" - # echo "ip route add ${gw} dev ${gwdev}" - ip route add ${gw} dev ${gwdev} >/dev/null ||: - fi - srcip="" - if [ -n "${PLUTO_MY_SOURCEIP}" ]; then - srcip=" src ${PLUTO_MY_SOURCEIP}" - fi - # echo "ip route ${r} ${PLUTO_PEER_CLIENT} dev ${VTI_IFACE} ${srcip}" - ip route ${r} ${PLUTO_PEER_CLIENT} dev ${VTI_IFACE} ${srcip} - echo "done ip route" - fi - fi - fi -} - -delvti() { - if [ -n "${VTI_IFACE}" -a -d /proc/sys/net/ipv4/conf/${VTI_IFACE} ]; then - if [ "${VTI_ROUTING}" = yes ]; then - ip route del ${PLUTO_PEER_CLIENT} dev ${VTI_IFACE} \ - src ${PLUTO_MY_SOURCEIP} ||: - fi - # TODO: we can't delete vti interface because we don't have proper reference - # counting. - #if [ "${VTI_SHARED}" = no -a "${PLUTO_CONN_KIND}" != CK_INSTANCE ]; then - # ip tun del ${VTI_IFACE} ||: - #fi - fi -} - -# Client Address Translation CAT -addcat() { - if [ -n "${CAT}" ] && [ "${PLUTO_MY_CLIENT_NET}" != "0.0.0.0" ] ; then - iptables -t nat -I POSTROUTING -m policy --dir out --pol ipsec \ - -d ${PLUTO_PEER_CLIENT} -j SNAT --to-source ${PLUTO_MY_CLIENT_NET} - iptables -t nat -I PREROUTING -m policy --dir in --pol ipsec \ - -d ${PLUTO_MY_CLIENT_NET} -s ${PLUTO_PEER_CLIENT} \ - -j DNAT --to-destination ${PLUTO_ME} - fi -} - -delcat() { - if [ -n "${CAT}" ]; then - iptables -t nat -D PREROUTING -m policy --dir in --pol ipsec \ - -d ${PLUTO_MY_CLIENT_NET} -s ${PLUTO_PEER_CLIENT} \ - -j DNAT --to-destination ${PLUTO_ME} - iptables -t nat -D POSTROUTING -m policy --dir out --pol ipsec \ - -d ${PLUTO_PEER_CLIENT} -j SNAT --to-source ${PLUTO_MY_CLIENT_NET} - fi -} - -# the big choice -case "${PLUTO_VERB}" in - prepare-host|prepare-client) - addvtiiface - ;; - route-host|route-client) - # connection to me or my client subnet being routed - addvti - uproute - addnflog - ;; - unroute-host|unroute-client) - # connection to me or my client subnet being unrouted - downroute - delsource - ;; - up-host) - # connection to me coming up - # If you are doing a custom version, firewall commands go here. - ;; - down-host) - # connection to me going down - downrule - delnflog - delcat - delvti - # If you are doing a custom version, firewall commands go here. - ;; - up-client) - # connection to my client subnet coming up - addvtiiface - updateresolvconf - addcat - addsource - notifyNM connect - addvti - # If you are doing a custom version, firewall commands go here. - ;; - down-client) - # connection to my client subnet going down - downrule - delnflog - delcat - delvti - restoreresolvconf - notifyNM disconnect - # If you are doing a custom version, firewall commands go here. - ;; - # - # IPv6 - # - prepare-host-v6|prepare-client-v6) - # prepare client for connection - ;; - route-host-v6|route-client-v6) - # connection to me or my client subnet being routed - uproute - ;; - unroute-host-v6|unroute-client-v6) - # connection to me or my client subnet being unrouted - downroute - delsource - ;; - up-host-v6) - # connection to me coming up - # If you are doing a custom version, firewall commands go here. - ;; - down-host-v6) - # connection to me going down - # If you are doing a custom version, firewall commands go here. - ;; - up-client-v6) - # connection to my client subnet coming up - addsource - updateresolvconf - notifyNM connect - # If you are doing a custom version, firewall commands go here. - ;; - down-client-v6) - # connection to my client subnet going down - restoreresolvconf - notifyNM disconnect - # If you are doing a custom version, firewall commands go here. - ;; - *) echo "$0: unknown verb \"${PLUTO_VERB}\" or parameter \"${1}\"" >&2 - exit 1 - ;; -esac