From patchwork Wed Jul 18 21:23:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qiuyu Xiao X-Patchwork-Id: 945926 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dVsLumVK"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41W9DQ28KCz9s4w for ; Thu, 19 Jul 2018 07:25:42 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id AB4FDD1C; Wed, 18 Jul 2018 21:23:51 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 3CA0DD1A for ; Wed, 18 Jul 2018 21:23:51 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 642517AA for ; Wed, 18 Jul 2018 21:23:50 +0000 (UTC) Received: by mail-pg1-f194.google.com with SMTP id y4-v6so2562305pgp.9 for ; Wed, 18 Jul 2018 14:23:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WQ8KxftQzD6xAPP2Ff+imdqOLPUqp/gORtPRxP6BSDM=; b=dVsLumVKGPS5kXo0lmxNRjWO6otGkPU1wZrp9PzOcBq8vVOGx6rFZH/Per4oKL1EwR eaP5TWg4Fw+jFGKPpjVhnHT6xO2nDNuh9tw7+2QBj7XrqVBY9WN5hD2eQ+2FSnXKzR9O 8ybBlWoOinOR5EMN3MAGQDTztCAJVstgui3c89/UwwByuRch1WWoriNUMyiS6VxCWH1t k+vOs/X/kk5IUzzZy6H810RWJYNT4Xt+5y3NRRvFs+tWtQ/fGc7Om3l8lFK9JzMTRXT5 Npl2kGqxrvXGMbalmp+MdVGetFWzBsWdiC5tQ4EwEMsbNDenTGR2JficW7S11+LKNvAT k7TQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WQ8KxftQzD6xAPP2Ff+imdqOLPUqp/gORtPRxP6BSDM=; b=OeuCCyt5URd5oBYEPqYViH9gZ4xjzsRNtlBhGBnx+QMao540FqUQDSPxHaCzmtj+rK 2NgLgwcZWGFb4IiZ8pw2iVSWf92BufJ3jmJtQId46cbaNpXKZUZQcLlKqjyemuHoo3Lv wwxWaKq8BJWXcwOt+GSS9wFZPM4ier070Rz75yZO1BxZkAsxeqrPTN1a6M8jRYbfnDaB fY9UJ6S6RUCcJmAwLtAzGHanUIjf+exf29Ao18HmffR6cD7TtQlFGuBl3ixx32h0YHGo N8C57zmMryH24Xu1dNVRNVpfWM6ME7zFqMrAX8OXZPh0H4IZA6I6bm7qxyWn2gxZ4AXL 8bAg== X-Gm-Message-State: AOUpUlFXGjMdPyFbWnOyBIwjG+u25vM5JSFsafU+HE16OHzo0EvDhGGZ coeEiiHg5v8NGOOX+ZuAdQ+xcw== X-Google-Smtp-Source: AAOMgpeaXuzrqjdV9ELWunmdtZQSjUg9xVs3bGvmD2tTeY5ba/v7XvhFLyshlsy3V7wJgHdb7LTEJQ== X-Received: by 2002:a63:d916:: with SMTP id r22-v6mr7125654pgg.381.1531949029329; Wed, 18 Jul 2018 14:23:49 -0700 (PDT) Received: from vm1.eng.vmware.com ([66.170.99.1]) by smtp.gmail.com with ESMTPSA id z123-v6sm6126277pfz.16.2018.07.18.14.23.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 18 Jul 2018 14:23:48 -0700 (PDT) From: Qiuyu Xiao To: ovs-dev@openvswitch.org Date: Wed, 18 Jul 2018 14:23:02 -0700 Message-Id: <20180718212302.3080-5-qiuyu.xiao.qyx@gmail.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180718212302.3080-1-qiuyu.xiao.qyx@gmail.com> References: <20180718212302.3080-1-qiuyu.xiao.qyx@gmail.com> X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v2 4/4] OVN: native support for tunnel encryption X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This patch adds IPsec support for OVN tunnel. Basically, OVN offers a binary option to its user for encryption configuration. If the IPsec option is turned on, all tunnels will be encrypted. Otherwise, no tunnel will be encrypted. The changes are summarized as below: 1) Added a ipsec column on the NB_Global table and SB_Global table. The value of ipsec column is propagated by ovn-northd from NB_Global to SB_Global. 2) ovn-controller monitors the ipsec column in SB_Global. If the ipsec value is true, ovn-controller sets options of the tunnel interface by specifying "options:remote_name=". If the ipsec value is false, ovn-controller removes these options. 3) ovs-monitor-ipsec daemon (https://mail.openvswitch.org/pipermail/ovs-dev/2018-June/348701.html) monitors the tunnel interface options and configures IKE daemon accordingly for IPsec encryption. Signed-off-by: Qiuyu Xiao --- ovn/controller/encaps.c | 33 ++++++++++++++++++++++++---- ovn/controller/encaps.h | 7 +++++- ovn/controller/ovn-controller.c | 4 +++- ovn/northd/ovn-northd.c | 8 +++++-- ovn/ovn-architecture.7.xml | 39 +++++++++++++++++++++++++++++++++ ovn/ovn-nb.ovsschema | 7 +++--- ovn/ovn-nb.xml | 6 +++++ ovn/ovn-sb.ovsschema | 7 +++--- ovn/ovn-sb.xml | 6 +++++ 9 files changed, 103 insertions(+), 14 deletions(-) diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c index fde017586..115c36411 100644 --- a/ovn/controller/encaps.c +++ b/ovn/controller/encaps.c @@ -79,8 +79,9 @@ tunnel_create_name(struct tunnel_ctx *tc, const char *chassis_id) } static void -tunnel_add(struct tunnel_ctx *tc, const char *new_chassis_id, - const struct sbrec_encap *encap) +tunnel_add(struct tunnel_ctx *tc, const struct sbrec_sb_global *sbg, + const char *new_chassis_id, const struct sbrec_encap *encap, + const char *local_ip) { struct smap options = SMAP_INITIALIZER(&options); smap_add(&options, "remote_ip", encap->ip); @@ -90,6 +91,17 @@ tunnel_add(struct tunnel_ctx *tc, const char *new_chassis_id, smap_add(&options, "csum", csum); } + /* Add auth info if ipsec is enabled. */ + if (sbg->ipsec) { + smap_add(&options, "remote_name", new_chassis_id); + if (local_ip) { + smap_add(&options, "local_ip", local_ip); + } + else { + VLOG_INFO("Need to specify encap ip for IPsec tunnels."); + } + } + /* If there's an existing chassis record that does not need any change, * keep it. Otherwise, create a new record (if there was an existing * record, the new record will supplant it and encaps_run() will delete @@ -157,7 +169,9 @@ encaps_run(struct ovsdb_idl_txn *ovs_idl_txn, const struct ovsrec_bridge_table *bridge_table, const struct ovsrec_bridge *br_int, const struct sbrec_chassis_table *chassis_table, - const char *chassis_id) + const char *chassis_id, + const struct sbrec_sb_global *sbg, + const struct ovsrec_open_vswitch_table *ovs_table) { if (!ovs_idl_txn || !br_int) { return; @@ -201,6 +215,17 @@ encaps_run(struct ovsdb_idl_txn *ovs_idl_txn, } } + /* Get IP address of local chassis. */ + const char *chassis_ip; + const struct ovsrec_open_vswitch *cfg; + cfg = ovsrec_open_vswitch_table_first(ovs_table); + if (cfg) { + chassis_ip = smap_get(&cfg->external_ids, "ovn-encap-ip"); + } + else { + chassis_ip = NULL; + } + SBREC_CHASSIS_TABLE_FOR_EACH (chassis_rec, chassis_table) { if (strcmp(chassis_rec->name, chassis_id)) { /* Create tunnels to the other chassis. */ @@ -209,7 +234,7 @@ encaps_run(struct ovsdb_idl_txn *ovs_idl_txn, VLOG_INFO("No supported encaps for '%s'", chassis_rec->name); continue; } - tunnel_add(&tc, chassis_rec->name, encap); + tunnel_add(&tc, sbg, chassis_rec->name, encap, chassis_ip); } } diff --git a/ovn/controller/encaps.h b/ovn/controller/encaps.h index 054bdfa78..680b62df7 100644 --- a/ovn/controller/encaps.h +++ b/ovn/controller/encaps.h @@ -23,13 +23,18 @@ struct ovsdb_idl_txn; struct ovsrec_bridge; struct ovsrec_bridge_table; struct sbrec_chassis_table; +struct sbrec_sb_global; +struct ovsrec_open_vswitch_table; void encaps_register_ovs_idl(struct ovsdb_idl *); void encaps_run(struct ovsdb_idl_txn *ovs_idl_txn, const struct ovsrec_bridge_table *, const struct ovsrec_bridge *br_int, const struct sbrec_chassis_table *, - const char *chassis_id); + const char *chassis_id, + const struct sbrec_sb_global *, + const struct ovsrec_open_vswitch_table *); + bool encaps_cleanup(struct ovsdb_idl_txn *ovs_idl_txn, const struct ovsrec_bridge *br_int); diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 6ee72a9fa..d6dd3e268 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -679,7 +679,9 @@ main(int argc, char *argv[]) chassis_id, br_int); encaps_run(ovs_idl_txn, ovsrec_bridge_table_get(ovs_idl_loop.idl), br_int, - sbrec_chassis_table_get(ovnsb_idl_loop.idl), chassis_id); + sbrec_chassis_table_get(ovnsb_idl_loop.idl), chassis_id, + sbrec_sb_global_first(ovnsb_idl_loop.idl), + ovsrec_open_vswitch_table_get(ovs_idl_loop.idl)); bfd_calculate_active_tunnels(br_int, &active_tunnels); binding_run(ovnsb_idl_txn, ovs_idl_txn, sbrec_chassis_by_name, sbrec_datapath_binding_by_key, diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 74eefc6ca..51f1671cd 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -6606,8 +6606,8 @@ ovnnb_db_run(struct northd_context *ctx, } hmap_destroy(&ports); - /* Copy nb_cfg from northbound to southbound database. - * + /* Sync ipsec configuration. + * Copy nb_cfg from northbound to southbound database. * Also set up to update sb_cfg once our southbound transaction commits. */ const struct nbrec_nb_global *nb = nbrec_nb_global_first(ctx->ovnnb_idl); if (!nb) { @@ -6617,6 +6617,9 @@ ovnnb_db_run(struct northd_context *ctx, if (!sb) { sb = sbrec_sb_global_insert(ctx->ovnsb_txn); } + if (nb->ipsec != sb->ipsec) { + sbrec_sb_global_set_ipsec(sb, nb->ipsec); + } sbrec_sb_global_set_nb_cfg(sb, nb->nb_cfg); sb_loop->next_cfg = nb->nb_cfg; @@ -7120,6 +7123,7 @@ main(int argc, char *argv[]) ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_sb_global); add_column_noalert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_nb_cfg); + add_column_noalert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_ipsec); ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_logical_flow); add_column_noalert(ovnsb_idl_loop.idl, diff --git a/ovn/ovn-architecture.7.xml b/ovn/ovn-architecture.7.xml index ae5ca8e4a..55a5db9ea 100644 --- a/ovn/ovn-architecture.7.xml +++ b/ovn/ovn-architecture.7.xml @@ -1621,6 +1621,45 @@ +

Encrypt Tunnel Traffic with IPsec

+

+ OVN tunnel traffic goes through physical routers and switches. These + physical devices could be untrusted (devices in public network) or might be + compromised. Enabling encryption to the tunnel traffic can prevent the + traffic data from being monitored and manipulated. +

+

+ The tunnel traffic is encrypted with IPsec. The CMS sets the + ipsec column in the northbound NB_Global table to + enable or disable IPsec encrytion. If ipsec is true, all OVN + tunnels will be encrypted. If ipsec is false, no OVN tunnels + will be encrypted. +

+

+ When CMS updates the ipsec column in the northbound + NB_Global table, ovn-northd copies the value to + the ipsec column in the southbound SB_Global + table. ovn-controller in each chassis monitors the southbound + database and sets the options of the OVS tunnel interface accordingly. OVS + tunnel interface options are monitored by the + ovs-monitor-ipsec daemon which configures IKE daemon to set up + IPsec connections. +

+

+ Chassis authenticates each other by using certificate. The authentication + succeeds if the other end in tunnel presents a certificate signed by a + trusted CA and the common name (CN) matches the expected chassis name. The + SSL certificates used in role-based access controls (RBAC) can be used in + IPsec. Or use ovs-pki to create different certificates. The + certificate is required to be x.509 version 3, and with CN field and + subjectAltName field being set to the chassis name. +

+

+ The CA certificate, chassis certificate and private key are required to be + installed in each chassis before enabling IPsec. Please see + ovs-vswitchd.conf.db(5) for setting up CA based IPsec + authentication. +

Design Decisions

Tunnel Encapsulations

diff --git a/ovn/ovn-nb.ovsschema b/ovn/ovn-nb.ovsschema index 8e6ddec46..528614efa 100644 --- a/ovn/ovn-nb.ovsschema +++ b/ovn/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", - "version": "5.11.0", - "cksum": "1149260021 18713", + "version": "5.12.0", + "cksum": "3682343791 18759", "tables": { "NB_Global": { "columns": { @@ -19,7 +19,8 @@ "ssl": { "type": {"key": {"type": "uuid", "refTable": "SSL"}, - "min": 0, "max": 1}}}, + "min": 0, "max": 1}}, + "ipsec": {"type": "boolean"}}, "maxRows": 1, "isRoot": true}, "Logical_Switch": { diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml index 6aed6102a..ddee98cd1 100644 --- a/ovn/ovn-nb.xml +++ b/ovn/ovn-nb.xml @@ -80,6 +80,12 @@ Global SSL configuration. + + + Tunnel encryption configuration. If this column is set to be true, all + OVN tunnels will be encrypted with IPsec. + + diff --git a/ovn/ovn-sb.ovsschema b/ovn/ovn-sb.ovsschema index 9e271d433..9c5c2ef29 100644 --- a/ovn/ovn-sb.ovsschema +++ b/ovn/ovn-sb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Southbound", - "version": "1.15.0", - "cksum": "1839738004 13639", + "version": "1.16.0", + "cksum": "3309568193 13685", "tables": { "SB_Global": { "columns": { @@ -17,7 +17,8 @@ "ssl": { "type": {"key": {"type": "uuid", "refTable": "SSL"}, - "min": 0, "max": 1}}}, + "min": 0, "max": 1}}, + "ipsec": {"type": "boolean"}}, "maxRows": 1, "isRoot": true}, "Chassis": { diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml index b17110e48..4090581fc 100644 --- a/ovn/ovn-sb.xml +++ b/ovn/ovn-sb.xml @@ -174,6 +174,12 @@ Global SSL configuration. + + + Tunnel encryption configuration. If this column is set to be true, all + OVN tunnels will be encrypted with IPsec. + +