Skip to content

Commit

Permalink
ipsec: Do not allow ipsec_gre tunnel traffic to exit unencrypted
Browse files Browse the repository at this point in the history
If ipsec_gre tunnel configuration is changed in OVSDB,
then GRE packets may sometimes exit unencrypted until
per-tunnel IPsec policies are installed by ovs-monitor-ipsec
daemon.

This patch fixes this issue by installing single, low
priority IPsec block policy that drops all GRE packets
coming out from ipsec_gre tunnels that do not have yet
their own IPsec policies installed.

This patch depends on to two other recently committed
patches:
1. 574ff4aa (tunneling: get skb marking to work
   properly with tunnels)
2. ca3574d (IPsec: refactor out some code in
   OVS_MONITOR_IPSEC_START macro)

Signed-off-by: Ansis Atteka <aatteka@ovn.org>
Reported-by: Steffen Birkeland <Steffefb@stud.ntnu.no>
Acked-by: Jesse Gross <jesse@kernel.org>
  • Loading branch information
Ansis Atteka committed Sep 1, 2016
1 parent 8275398 commit 87e731f
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
1 change: 1 addition & 0 deletions debian/control
Expand Up @@ -181,6 +181,7 @@ Description: OVN Docker drivers
Package: openvswitch-ipsec
Architecture: linux-any
Depends: ipsec-tools (>=0.8~alpha20101208),
iproute2,
openvswitch-common (= ${binary:Version}),
openvswitch-switch (= ${binary:Version}),
python,
Expand Down
16 changes: 14 additions & 2 deletions debian/ovs-monitor-ipsec
Expand Up @@ -45,7 +45,9 @@ import six
vlog = ovs.vlog.Vlog("ovs-monitor-ipsec")
root_prefix = '' # Prefix for absolute file names, for testing.
SETKEY = "/usr/sbin/setkey"
IP = "/sbin/ip"
exiting = False
IPSEC_MARK = "1"


def unixctl_exit(conn, unused_argv, unused_aux):
Expand Down Expand Up @@ -281,6 +283,12 @@ class IPsec(object):
p.stdin.write(cmds)
return p.communicate()[0]

def call_ip_xfrm(self, cmds):
exitcode = subprocess.call([root_prefix + IP, "xfrm"] + cmds)
if exitcode != 0:
vlog.err("couldn't install IPsec policy that prevents "
"traffic from exiting unencrypted")

def get_spi(self, local_ip, remote_ip, proto="esp"):
# Run the setkey dump command to retrieve the SAD. Then, parse
# the output looking for SPI buried in the output. Note that
Expand Down Expand Up @@ -322,6 +330,10 @@ class IPsec(object):

def spd_flush(self):
self.call_setkey("spdflush;\n")
self.call_ip_xfrm(["policy", "add", "src", "0.0.0.0/0", "dst",
"0.0.0.0/0", "proto", "gre", "dir", "out",
"mark", IPSEC_MARK, "mask", IPSEC_MARK,
"action", "block", "priority", "4294967295"]);

def spd_add(self, local_ip, remote_ip):
cmds = ("spdadd %s %s gre -P out ipsec esp/transport//require;\n" %
Expand Down Expand Up @@ -413,15 +425,15 @@ def main():
schema_helper.register_columns("SSL", ["certificate", "private_key"])
idl = ovs.db.idl.Idl(remote, schema_helper)

ipsec = IPsec()

ovs.daemon.daemonize()

ovs.unixctl.command_register("exit", "", 0, 0, unixctl_exit, None)
error, unixctl_server = ovs.unixctl.server.UnixctlServer.create(None)
if error:
ovs.util.ovs_fatal(error, "could not create unixctl server", vlog)

ipsec = IPsec()

interfaces = {}
seqno = idl.change_seqno # Sequence number when we last processed the db
while True:
Expand Down
7 changes: 7 additions & 0 deletions tests/ofproto-macros.at
Expand Up @@ -480,6 +480,7 @@ on_exit 'kill `cat pid ovs-monitor-ipsec.pid`'

mkdir etc etc/init.d etc/racoon etc/racoon/certs
mkdir usr usr/sbin
mkdir sbin

AT_DATA([etc/init.d/racoon], [dnl
#! /bin/sh
Expand All @@ -498,6 +499,12 @@ done
])
chmod +x usr/sbin/setkey

AT_DATA([sbin/ip], [dnl
#! /bin/sh
exit 0
])
chmod +x sbin/ip

touch etc/racoon/certs/ovs-stale.pem

###
Expand Down

0 comments on commit 87e731f

Please sign in to comment.