diff mbox series

[ovs-dev,v2,1/3] ovn-controller: Support ssl cert rotation when command line options are used.

Message ID 20210520011428.1049939-1-hzhou@ovn.org
State Superseded
Headers show
Series [ovs-dev,v2,1/3] ovn-controller: Support ssl cert rotation when command line options are used. | expand

Commit Message

Han Zhou May 20, 2021, 1:14 a.m. UTC
When SSL configurations are set in Open_vSwitch SSL table,
ovn-controller handles file update properly by re-applying the settings
in the main loop. However, it is also valid to set the options in
command line of ovn-controller without using the SSL table. In this
case, the options are set onetime only and it never reapplies when the
file content changes. This patch fixes this by allowing reapplying the
command line options in the main loop, if they are set. SSL table
settings still takes precedence if both exist.

Signed-off-by: Han Zhou <hzhou@ovn.org>
---
v1 -> v2:
    - Addressed Mark Michelson's comments
        - Added test cases.
        - Check NULL pointer for key & cert, cacert separately.
    - Combined ovn-northd/ddlog/ovn-ic changes to one patch.

 controller/ovn-controller.c | 27 ++++++++++++++++++-
 tests/ovn-controller.at     | 53 +++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 031b275c8..d48ddc7a2 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -98,6 +98,11 @@  static unixctl_cb_func debug_delay_nb_cfg_report;
 static char *parse_options(int argc, char *argv[]);
 OVS_NO_RETURN static void usage(void);
 
+/* SSL options */
+static const char *ssl_private_key_file;
+static const char *ssl_certificate_file;
+static const char *ssl_ca_cert_file;
+
 /* By default don't set an upper bound for the lflow cache. */
 #define DEFAULT_LFLOW_CACHE_MAX_ENTRIES UINT32_MAX
 #define DEFAULT_LFLOW_CACHE_MAX_MEM_KB (UINT64_MAX / 1024)
@@ -447,6 +452,14 @@  update_ssl_config(const struct ovsrec_ssl_table *ssl_table)
     if (ssl) {
         stream_ssl_set_key_and_cert(ssl->private_key, ssl->certificate);
         stream_ssl_set_ca_cert_file(ssl->ca_cert, ssl->bootstrap_ca_cert);
+    } else {
+        if (ssl_private_key_file && ssl_certificate_file) {
+            stream_ssl_set_key_and_cert(ssl_private_key_file,
+                                        ssl_certificate_file);
+        }
+        if (ssl_ca_cert_file) {
+            stream_ssl_set_ca_cert_file(ssl_ca_cert_file, false);
+        }
     }
 }
 
@@ -3333,7 +3346,19 @@  parse_options(int argc, char *argv[])
 
         VLOG_OPTION_HANDLERS
         OVN_DAEMON_OPTION_HANDLERS
-        STREAM_SSL_OPTION_HANDLERS
+
+        case 'p':
+            ssl_private_key_file = optarg;
+            break;
+
+        case 'c':
+            ssl_certificate_file = optarg;
+            break;
+
+        case 'C':
+            ssl_ca_cert_file = optarg;
+            break;
+
 
         case OPT_PEER_CA_CERT:
             stream_ssl_set_peer_ca_cert_file(optarg);
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
index d1d758c49..cff08cb7b 100644
--- a/tests/ovn-controller.at
+++ b/tests/ovn-controller.at
@@ -549,3 +549,56 @@  done
 
 OVN_CLEANUP([hv1])
 AT_CLEANUP
+
+AT_SETUP([ovn-controller - ssl files change when using command line options])
+AT_KEYWORDS([ovn])
+AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
+PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
+AT_SKIP_IF([expr "$PKIDIR" : ".*[ 	'\"
+\\]"])
+ovn_start
+
+net_add n1
+sim_add hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+
+key=testpki-hv1-privkey.pem
+cert=testpki-hv1-cert.pem
+cacert=testpki-cacert.pem
+
+key2=testpki-hv2-privkey.pem
+cert3=testpki-hv3-cert.pem
+
+# Use mismatched key and cert when restarting ovn-controller
+cp $PKIDIR/$key2 $key
+cp $PKIDIR/$cert3 $cert
+cp $PKIDIR/$cacert $cacert
+
+# Restart ovn-controller using command line options for SSL parameters
+OVS_APP_EXIT_AND_WAIT([ovn-controller])
+check ovs-vsctl del-ssl
+start_daemon ovn-controller -p $key -c $cert -C $cacert
+
+# SSL should not connect because of key and cert mismatch
+OVS_WAIT_UNTIL([ovn-appctl -t ovn-controller connection-status], [0], [not connected])
+
+# Modify the files with the correct key and cert, and reconnect should succeed
+cp $PKIDIR/$key $key
+cp $PKIDIR/$cert $cert
+
+OVS_WAIT_UNTIL([ovn-appctl -t ovn-controller connection-status], [0], [connected])
+
+# Remove the files and expect the connection to drop
+rm $key $cert
+OVS_WAIT_UNTIL([ovn-appctl -t ovn-controller connection-status], [0], [not connected])
+
+# Restore the files again and expect the connection to recover
+cp $PKIDIR/$key $key
+cp $PKIDIR/$cert $cert
+OVS_WAIT_UNTIL([ovn-appctl -t ovn-controller connection-status], [0], [connected])
+
+cat hv1/ovn-controller.log
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP