From: Tobias Brunner Date: Mon, 25 Mar 2019 17:31:28 +0000 (+0100) Subject: testing: Add scenario that uses IKE-specific interface IDs X-Git-Tag: 5.8.0rc1~41^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=072de7c150f0afc1de94623162e17e751d8fdee8;p=thirdparty%2Fstrongswan.git testing: Add scenario that uses IKE-specific interface IDs --- diff --git a/testing/tests/route-based/net2net-xfrmi-ike/description.txt b/testing/tests/route-based/net2net-xfrmi-ike/description.txt new file mode 100644 index 0000000000..b362a0a07c --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/description.txt @@ -0,0 +1,18 @@ +One connection with two CHILD_SAs between the hosts and subnet behind the +gateways moon and sun, respectively, are set up using XFRM +interfaces. +

+The gateways use route-based forwarding with XFRM interfaces, with +firewall rules to allow traffic to pass. Both peers use connection-defined +interface IDs so all CHILD_SAs share the same XFRM interface. The IKE daemon +does not install routes for CHILD_SAs with outbound interface ID, so routes for +the target subnets are installed statically or via updown events. +

+Both gateways use separate interfaces for in- and outbound traffic (which is +completely optional and mainly for testing purposes, a single interface will +usually be enough). Gateway moon creates them before initiating the +connection, while gateway sun dynamically creates the interfaces via +ike-updown event using the passed unique generated interface IDs. +

+Clients alice and venus behind gateway moon ping client +bob located behind gateway sun. diff --git a/testing/tests/route-based/net2net-xfrmi-ike/evaltest.dat b/testing/tests/route-based/net2net-xfrmi-ike/evaltest.dat new file mode 100644 index 0000000000..cd514c9a24 --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/evaltest.dat @@ -0,0 +1,6 @@ +moon::swanctl --list-sas --ike-id 1 --raw 2> /dev/null::gw.*version=2 state=ESTABLISHED local-host=PH_IP_MOON local-port=4500 local-id=moon.strongswan.org remote-host=PH_IP_SUN remote-port=4500 remote-id=sun.strongswan.org.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL.*ESP.*local-ts=\[10.1.0.10/32] remote-ts=\[10.2.0.0/16].*local-ts=\[10.1.0.20/32] remote-ts=\[10.2.0.0/16]::YES +sun::swanctl --list-sas --ike-id 1 --raw 2> /dev/null::gw.*version=2 state=ESTABLISHED local-host=PH_IP_SUN local-port=4500 local-id=sun.strongswan.org remote-host=PH_IP_MOON remote-port=4500 remote-id=moon.strongswan.org.*child-sas.*net.*reqid=1 state=INSTALLED mode=TUNNEL.*ESP.*local-ts=\[10.2.0.0/16] remote-ts=\[10.1.0.10/32].*local-ts=\[10.2.0.0/16] remote-ts=\[10.1.0.20/32]::YES +alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=1::YES +venus::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=1::YES +sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES +sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES diff --git a/testing/tests/route-based/net2net-xfrmi-ike/hosts/moon/etc/strongswan.conf b/testing/tests/route-based/net2net-xfrmi-ike/hosts/moon/etc/strongswan.conf new file mode 100644 index 0000000000..15f8ad5bc3 --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/hosts/moon/etc/strongswan.conf @@ -0,0 +1,9 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon-systemd { + load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default updown +} diff --git a/testing/tests/route-based/net2net-xfrmi-ike/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/route-based/net2net-xfrmi-ike/hosts/moon/etc/swanctl/swanctl.conf new file mode 100755 index 0000000000..ca8bd29045 --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/hosts/moon/etc/swanctl/swanctl.conf @@ -0,0 +1,33 @@ +connections { + + gw-gw { + local_addrs = PH_IP_MOON + remote_addrs = PH_IP_SUN + + if_id_out = 1337 + if_id_in = 42 + + local { + auth = pubkey + certs = moonCert.pem + id = moon.strongswan.org + } + remote { + auth = pubkey + id = sun.strongswan.org + } + children { + alice-net { + local_ts = 10.1.0.10/32 + remote_ts = 0.0.0.0/0 + + esp_proposals = aes128gcm128-x25519 + } + venus-net : connections.gw-gw.children.alice-net { + local_ts = 10.1.0.20/32 + } + } + version = 2 + proposals = aes128-sha256-x25519 + } +} diff --git a/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/strongswan.conf b/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/strongswan.conf new file mode 100644 index 0000000000..283cb1d724 --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/strongswan.conf @@ -0,0 +1,12 @@ +# /etc/strongswan.conf - strongSwan configuration file + +swanctl { + load = pem pkcs1 x509 revocation constraints pubkey openssl random +} + +charon-systemd { + load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac vici kernel-netlink socket-default + start-scripts { + updown = /usr/bin/python /etc/updown.py + } +} diff --git a/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/swanctl/swanctl.conf b/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/swanctl/swanctl.conf new file mode 100755 index 0000000000..ebe3b58730 --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/swanctl/swanctl.conf @@ -0,0 +1,30 @@ +connections { + + gw-gw { + local_addrs = PH_IP_SUN + remote_addrs = PH_IP_MOON + + if_id_in = %unique-dir + if_id_out = %unique-dir + + local { + auth = pubkey + certs = sunCert.pem + id = sun.strongswan.org + } + remote { + auth = pubkey + id = moon.strongswan.org + } + children { + net-net { + local_ts = 10.2.0.0/16 + remote_ts = 10.1.0.0/16 + + esp_proposals = aes128gcm128-x25519 + } + } + version = 2 + proposals = aes128-sha256-x25519 + } +} diff --git a/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/updown.py b/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/updown.py new file mode 100755 index 0000000000..b17eb6bab9 --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/hosts/sun/etc/updown.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python + +import vici +import daemon +import logging +from logging.handlers import SysLogHandler +import subprocess + + +logger = logging.getLogger('updownLogger') +handler = SysLogHandler(address='/dev/log', facility=SysLogHandler.LOG_DAEMON) +handler.setFormatter(logging.Formatter('charon-updown: %(message)s')) +logger.addHandler(handler) +logger.setLevel(logging.INFO) + + +def handle_interfaces(ike_sa, up): + if_id_in = int(ike_sa['if-id-in'], 16) + if_id_out = int(ike_sa['if-id-out'], 16) + ifname_in = "xfrm-{}-in".format(if_id_in) + ifname_out = "xfrm-{}-out".format(if_id_out) + + if up: + logger.info("add XFRM interfaces %s and %s", ifname_in, ifname_out) + subprocess.call(["/usr/local/libexec/ipsec/xfrmi", "-n", ifname_out, + "-i", str(if_id_out), "-d", "eth0"]) + subprocess.call(["/usr/local/libexec/ipsec/xfrmi", "-n", ifname_in, + "-i", str(if_id_in), "-d", "eth0"]) + subprocess.call(["ip", "link", "set", ifname_out, "up"]) + subprocess.call(["ip", "link", "set", ifname_in, "up"]) + subprocess.call(["iptables", "-A", "FORWARD", "-o", ifname_out, + "-j", "ACCEPT"]) + subprocess.call(["iptables", "-A", "FORWARD", "-i", ifname_in, + "-j", "ACCEPT"]) + + else: + logger.info("delete XFRM interfaces %s and %s", ifname_in, ifname_out) + subprocess.call(["iptables", "-D", "FORWARD", "-o", ifname_out, + "-j", "ACCEPT"]) + subprocess.call(["iptables", "-D", "FORWARD", "-i", ifname_in, + "-j", "ACCEPT"]) + subprocess.call(["ip", "link", "del", ifname_out]) + subprocess.call(["ip", "link", "del", ifname_in]) + + +def install_routes(ike_sa): + if_id_out = int(ike_sa['if-id-out'], 16) + ifname_out = "xfrm-{}-out".format(if_id_out) + child_sa = next(ike_sa["child-sas"].itervalues()) + + for ts in child_sa['remote-ts']: + logger.info("add route to %s via %s", ts, ifname_out) + subprocess.call(["ip", "route", "add", ts, "dev", ifname_out]) + + +# daemonize and run parallel to the IKE daemon +with daemon.DaemonContext(): + logger.debug("starting Python updown listener") + try: + session = vici.Session() + ver = session.version() + logger.info("connected to {daemon} {version} ({sysname}, {release}, " + "{machine})".format(**ver)) + except: + logger.error("failed to get status via vici") + sys.exit(1) + + try: + for label, event in session.listen(["ike-updown", "child-updown"]): + logger.debug("received event: %s %s", label, repr(event)) + + name = next((x for x in iter(event) if x != "up")) + up = event.get("up", "") == "yes" + ike_sa = event[name] + + if label == "ike-updown": + handle_interfaces(ike_sa, up) + + elif label == "child-updown" and up: + install_routes(ike_sa) + + except IOError: + logger.error("daemon disconnected") + except: + logger.error("exception while listening for events " + + repr(sys.exc_info()[1])) diff --git a/testing/tests/route-based/net2net-xfrmi-ike/posttest.dat b/testing/tests/route-based/net2net-xfrmi-ike/posttest.dat new file mode 100644 index 0000000000..310a564adf --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/posttest.dat @@ -0,0 +1,10 @@ +moon::swanctl --terminate --ike gw-gw +moon::systemctl stop strongswan-swanctl +sun::systemctl stop strongswan-swanctl +moon::iptables-restore < /etc/iptables.flush +sun::iptables-restore < /etc/iptables.flush +moon::ip -s link show xfrm-moon-out +moon::ip -s link show xfrm-moon-in +moon::ip link del xfrm-moon-out +moon::ip link del xfrm-moon-in +sun::rm /etc/updown.py diff --git a/testing/tests/route-based/net2net-xfrmi-ike/pretest.dat b/testing/tests/route-based/net2net-xfrmi-ike/pretest.dat new file mode 100644 index 0000000000..bdd904ae1f --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/pretest.dat @@ -0,0 +1,15 @@ +moon::iptables-restore < /etc/iptables.rules +sun::iptables-restore < /etc/iptables.rules +moon::/usr/local/libexec/ipsec/xfrmi -n xfrm-moon-out -d eth0 -i 1337 +moon::/usr/local/libexec/ipsec/xfrmi -n xfrm-moon-in -d eth0 -i 42 +moon::ip link set xfrm-moon-out up +moon::ip link set xfrm-moon-in up +moon::ip route add 10.2.0.0/16 dev xfrm-moon-out +moon::iptables -A FORWARD -o xfrm-moon-out -j ACCEPT +moon::iptables -A FORWARD -i xfrm-moon-in -j ACCEPT +moon::systemctl start strongswan-swanctl +sun::systemctl start strongswan-swanctl +moon::expect-connection gw-gw +sun::expect-connection gw-gw +moon::swanctl --initiate --child alice-net +moon::swanctl --initiate --child venus-net diff --git a/testing/tests/route-based/net2net-xfrmi-ike/test.conf b/testing/tests/route-based/net2net-xfrmi-ike/test.conf new file mode 100644 index 0000000000..7f82c02f11 --- /dev/null +++ b/testing/tests/route-based/net2net-xfrmi-ike/test.conf @@ -0,0 +1,25 @@ +#!/bin/bash +# +# This configuration file provides information on the +# guest instances used for this test + +# All guest instances that are required for this test +# +VIRTHOSTS="alice venus moon winnetou sun bob" + +# Corresponding block diagram +# +DIAGRAM="a-v-m-w-s-b.png" + +# Guest instances on which tcpdump is to be started +# +TCPDUMPHOSTS="sun" + +# Guest instances on which IPsec is started +# Used for IPsec logging purposes +# +IPSECHOSTS="moon sun" + +# charon controlled by swanctl +# +SWANCTL=1