| Server IP : 172.67.134.114 / Your IP : 162.159.115.42 Web Server : Apache/2.4.37 System : Linux almalinux.duckdns.org 4.18.0-553.111.1.el8_10.x86_64 #1 SMP Sun Mar 8 20:06:07 EDT 2026 x86_64 User : ricodeal ( 1046) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/libexec/ipsec/ |
Upload File : |
#!/usr/bin/sh
# -*- mode: sh; sh-shell: sh -*-
#
# default updown script for use with NETKEY(XFRM)
#
# Copyright (C) 2003-2004 Nigel Metheringham
# Copyright (C) 2002-2007 Michael Richardson <[email protected]>
# Copyright (C) 2007-2008 Paul Wouters <[email protected]>
# Copyright (C) 2003-2020 Tuomo Soini <[email protected]>
# Copyright (C) 2011-2016 Paul Wouters <[email protected]>
# Copyright (C) 2016 Antony Antony <[email protected]>
#
# 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 <https://www.gnu.org/licenses/gpl2.txt>.
#
# 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_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_CONNECTION_TYPE
# is type of the connection, "tunnel" or "transport".
#
# PLUTO_CONN_POLICY
# the policy of the connection, as in:
# RSASIG+ENCRYPT+TUNNEL+PFS+DONTREKEY+OPPORTUNISTIC
# +failureDROP+lKOD+rKOD
#
# CAT=YES|
# if client address translation inside IPsec stack is enabled
#
# 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_MY_ID
# is our ID.
#
# PLUTO_METRIC
# is the metric to set for the route
#
# PLUTO_MTU
# is the mtu to set for the route
#
# PLUTO_ADD_TIME
# Time the IPsec SA was added to the kernel
#
# PLUTO_MOBIKE_EVENT
# wether the connection is underdoing MOBIKE migration
#
# 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_ID
# is the ID 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_PEER_CA
# is the DN of the peer's CA that signed its certificate
#
# PLUTO_CFG_CLIENT=0|1
# is MODECFG or IKEv2 Config client.
#
# PLUTO_CFG_SERVER=0|1
# is MODECFG or IKEv2 Config server.
#
# PLUTO_PEER_DNS_INFO
# The peer's supplied DNS information (IKEv1 and IKEv2)
#
# PLUTO_PEER_DOMAIN_INFO
# The peer's supplied domain list for local resolving (IKEv2 only)
#
# PLUTO_PEER_BANNER
# is the peer's provided banner
#
# PLUTO_NM_CONFIGURED=0|1
# is NetworkManager used for resolv.conf update
#
# PLUTO_CONN_ADDRFAMILY
# is the family type, "ipv4" or "ipv6"
#
# PLUTO_CONN_KIND
# is the "kind" of connection (CK_PERMANENT, CK_INSTANCE, etc)
#
# PLUTO_STACK
# is the local IPsec kernel stack used, eg XFRM, BSDKAME, NOSTACK
#
# PLUTO_IS_PEER_CISCO=0|1
# remote server type is cisco. Add support for cisco extensions
# when used with xauth.
#
# PLUTO_SA_REQID
# When using KAME or XFRM, 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_XFRMI_FWMARK
# use outgoing mark
#
# 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
#
# INTERFACE_IP
# The IP to configure / expect on the interface? Currently is never set
#
# PLUTO_XFRM_ROUTE
# if an XFRM (ipsec-device) has been specified, value will be "yes"
#
# 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.
#
# CONNMARK_IN
# the incoming mark to use
#
# CONNMARK_OUT
# the outgoing mark to use
#
# 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.
#
# VTI_IP
# The IP to configure on the VTI device
#
# SPI_IN / SPI_OUT
# The inbound and outbound SPI's of the connection.
#
# PLUTO_INBYTES
# total bytes received
#
# PLUTO_OUTBYTES
# total bytes sent
#
# NFLOG
# is the nflog group to use
#
# 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
# 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 -${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}/${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 -${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}/${MAX_CIDR}
then
return ${st}
fi
if [ -n "${PLUTO_MOBIKE_EVENT}" ] ; then
return ${st}
fi
it="ip -${FAMILY} addr del ${PLUTO_MY_SOURCEIP}/${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 "leftsubnet == 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 -${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 -${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
}
firewall_cmd() {
HAVE_IPTABLES=true
HAVE_NFTABLES=false
# if [ "${HAVE_NFTABLES}" = true ]; #nft has precedence
# FIREWALL=NFTABLES;
if [ "${HAVE_IPTABLES}" = true ]; then
FIREWALL=IPTABLES
else
FIREWALL=""
fi
}
# TODO: We need to specify CIDR mask but our _MASK variables are in old school format
# TODO: Exclude udp 4500 traffic
addnflog() {
firewall_cmd
if [ "${FIREWALL}" = IPTABLES -a -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() {
firewall_cmd
if [ "${FIREWALL}" = IPTABLES -a -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() {
firewall_cmd
if [ "${FIREWALL}" = IPTABLES -a -n "${CAT}" -a "${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() {
firewall_cmd
if [ "${FIREWALL}" = IPTABLES -a -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