Skip to content

Commit

Permalink
OVN: native support for tunnel encryption
Browse files Browse the repository at this point in the history
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=<remote_chassis_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 <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
qiuyuX authored and blp committed Nov 9, 2018
1 parent 7b243c3 commit b1cc0db
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 14 deletions.
14 changes: 10 additions & 4 deletions ovn/controller/encaps.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ 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)
{
struct smap options = SMAP_INITIALIZER(&options);
smap_add(&options, "remote_ip", encap->ip);
Expand All @@ -90,6 +90,11 @@ 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 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
Expand Down Expand Up @@ -157,7 +162,8 @@ 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)
{
if (!ovs_idl_txn || !br_int) {
return;
Expand Down Expand Up @@ -209,7 +215,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);
}
}

Expand Down
6 changes: 5 additions & 1 deletion ovn/controller/encaps.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ 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 *);

bool encaps_cleanup(struct ovsdb_idl_txn *ovs_idl_txn,
const struct ovsrec_bridge *br_int);

Expand Down
3 changes: 2 additions & 1 deletion ovn/controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,8 @@ main(int argc, char *argv[])
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));
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,
Expand Down
8 changes: 6 additions & 2 deletions ovn/northd/ovn-northd.c
Original file line number Diff line number Diff line change
Expand Up @@ -7161,8 +7161,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) {
Expand All @@ -7172,6 +7172,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);
sbrec_sb_global_set_options(sb, &nb->options);
sb_loop->next_cfg = nb->nb_cfg;
Expand Down Expand Up @@ -7689,6 +7692,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_options);
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,
Expand Down
39 changes: 39 additions & 0 deletions ovn/ovn-architecture.7.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1621,6 +1621,45 @@
</li>
</ol>

<h2>Encrypt Tunnel Traffic with IPsec</h2>
<p>
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.
</p>
<p>
The tunnel traffic is encrypted with IPsec. The CMS sets the
<code>ipsec</code> column in the northbound <code>NB_Global</code> table to
enable or disable IPsec encrytion. If <code>ipsec</code> is true, all OVN
tunnels will be encrypted. If <code>ipsec</code> is false, no OVN tunnels
will be encrypted.
</p>
<p>
When CMS updates the <code>ipsec</code> column in the northbound
<code>NB_Global</code> table, <code>ovn-northd</code> copies the value to
the <code>ipsec</code> column in the southbound <code>SB_Global</code>
table. <code>ovn-controller</code> 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
<code>ovs-monitor-ipsec</code> daemon which configures IKE daemon to set up
IPsec connections.
</p>
<p>
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 <code>ovs-pki</code> 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.
</p>
<p>
The CA certificate, chassis certificate and private key are required to be
installed in each chassis before enabling IPsec. Please see
<code>ovs-vswitchd.conf.db</code>(5) for setting up CA based IPsec
authentication.
</p>
<h1>Design Decisions</h1>

<h2>Tunnel Encapsulations</h2>
Expand Down
7 changes: 4 additions & 3 deletions ovn/ovn-nb.ovsschema
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "OVN_Northbound",
"version": "5.13.1",
"cksum": "749176366 20467",
"version": "5.14.0",
"cksum": "3600467067 20513",
"tables": {
"NB_Global": {
"columns": {
Expand All @@ -22,7 +22,8 @@
"min": 0, "max": 1}},
"options": {
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}},
"min": 0, "max": "unlimited"}},
"ipsec": {"type": "boolean"}},
"maxRows": 1,
"isRoot": true},
"Logical_Switch": {
Expand Down
6 changes: 6 additions & 0 deletions ovn/ovn-nb.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@
Global SSL configuration.
</column>
</group>
<group title="Security Configurations">
<column name="ipsec">
Tunnel encryption configuration. If this column is set to be true, all
OVN tunnels will be encrypted with IPsec.
</column>
</group>
</table>

<table name="Logical_Switch" title="L2 logical switch">
Expand Down
7 changes: 4 additions & 3 deletions ovn/ovn-sb.ovsschema
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "OVN_Southbound",
"version": "1.16.1",
"cksum": "2148542239 14999",
"version": "1.17.0",
"cksum": "3217981733 15045",
"tables": {
"SB_Global": {
"columns": {
Expand All @@ -20,7 +20,8 @@
"min": 0, "max": 1}},
"options": {
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}},
"min": 0, "max": "unlimited"}},
"ipsec": {"type": "boolean"}},
"maxRows": 1,
"isRoot": true},
"Chassis": {
Expand Down
6 changes: 6 additions & 0 deletions ovn/ovn-sb.xml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@
Global SSL configuration.
</column>
</group>
<group title="Security Configurations">
<column name="ipsec">
Tunnel encryption configuration. If this column is set to be true, all
OVN tunnels will be encrypted with IPsec.
</column>
</group>
</table>

<table name="Chassis" title="Physical Network Hypervisor and Gateway Information">
Expand Down

0 comments on commit b1cc0db

Please sign in to comment.