varnish / hitch

A scalable TLS proxy by Varnish Software.
https://www.varnish-software.com/
Other
1.87k stars 157 forks source link

password interaction / systemd #365

Open ehdis opened 2 years ago

ehdis commented 2 years ago

I wonder what options i have. I am migrating some hitch instances from an OS with upstart init system to a systemd based one. Some instances have by policy the pem files encrypted. While starting the password is provided manually. Now with systemd the start process just fails. Does hitch provide such capabilities to interact with systemd and pass a request to the tty?

Service section part of the unit file:

  [Service]
  PIDFile=/run/hitch/hitch.pid
  RuntimeDirectory=hitch
  Type=forking
  PrivateTmp=true
  ExecStart=/usr/sbin/hitch --pidfile=/run/hitch/hitch.pid --config=/etc/hitch/hitch.conf 
  ExecReload=/usr/bin/kill -HUP $MAINPID

Thanks

ehdis commented 2 years ago

Based on #53 | patch | just a POC | not for prod

# pem-keypass -- supply password for key file
#
# Patch [2021-11-07 @ehdis]
#
# Code [https://github.com/varnish/hitch/pull/53 - 2015 @afterfate]
#
diff -r -u o/hitch/hitch.conf.man.rst w/hitch/hitch.conf.man.rst
--- o/hitch/hitch.conf.man.rst  2021-11-07 17:05:43.353079435 +0100
+++ w/hitch/hitch.conf.man.rst  2021-11-07 17:12:57.136141852 +0100
@@ -527,6 +527,9 @@
     # run Varnish as backend over PROXY; varnishd -a :80 -a localhost:6086,PROXY ..
     write-proxy-v2 = on             # Write PROXY header

+    # Password for private key in PEM file OPTIONAL.
+    # pem-keypass = "mypassword"
+

 .. example-end

diff -r -u o/hitch/src/cfg_lex.l w/hitch/src/cfg_lex.l
--- o/hitch/src/cfg_lex.l   2021-11-07 17:05:43.354079435 +0100
+++ w/hitch/src/cfg_lex.l   2021-11-07 18:48:29.123753162 +0100
@@ -96,6 +96,7 @@
 "ocsp-dir"         { return (TOK_OCSP_DIR); }
 "pem-dir"          { return (TOK_PEM_DIR); }
 "pem-dir-glob"         { return (TOK_PEM_DIR_GLOB); }
+"pem-keypass"          { return (TOK_PEM_KEYPASS); }
 "session-cache"            { return (TOK_SESSION_CACHE); }
 "shared-cache-listen"      { return (TOK_SHARED_CACHE_LISTEN); }
 "shared-cache-peer"        { return (TOK_SHARED_CACHE_PEER); }
diff -r -u o/hitch/src/cfg_parser.y w/hitch/src/cfg_parser.y
--- o/hitch/src/cfg_parser.y    2021-11-07 17:05:43.354079435 +0100
+++ w/hitch/src/cfg_parser.y    2021-11-07 18:47:24.825771238 +0100
@@ -57,7 +57,7 @@
 %token TOK_TLSv1_3 TOK_CIPHERSUITES TOK_ECDH_CURVE
 %token TOK_SESSION_CACHE TOK_SHARED_CACHE_LISTEN TOK_SHARED_CACHE_PEER
 %token TOK_SHARED_CACHE_IF TOK_PRIVATE_KEY TOK_BACKEND_REFRESH
-%token TOK_OCSP_REFRESH_INTERVAL TOK_PEM_DIR TOK_PEM_DIR_GLOB
+%token TOK_OCSP_REFRESH_INTERVAL TOK_PEM_DIR TOK_PEM_DIR_GLOB TOK_PEM_KEYPASS
 %token TOK_LOG_LEVEL TOK_PROXY_TLV TOK_PROXY_AUTHORITY TOK_TFO
 %token TOK_CLIENT_VERIFY TOK_VERIFY_NONE TOK_VERIFY_OPT TOK_VERIFY_REQ
 %token TOK_CLIENT_VERIFY_CA TOK_PROXY_CCERT
@@ -111,6 +111,7 @@
    | OCSP_DIR
    | PEM_DIR
    | PEM_DIR_GLOB
+  | PEM_KEYPASS_REC
    | SESSION_CACHE_REC
    | SHARED_CACHE_LISTEN_REC
    | SHARED_CACHE_PEER_REC
@@ -230,6 +231,14 @@

 };

+PEM_KEYPASS_REC: TOK_PEM_KEYPASS '=' STRING {
+   if ($3)
+       cfg->PEM_KEYPASS = strdup($3);
+   else
+       cfg->PEM_KEYPASS = NULL;
+
+};
+
 OCSP_DIR: TOK_OCSP_DIR '=' STRING {
    free(cfg->OCSP_DIR);
    if ($3)
diff -r -u o/hitch/src/configuration.c w/hitch/src/configuration.c
--- o/hitch/src/configuration.c 2021-11-07 17:05:43.354079435 +0100
+++ w/hitch/src/configuration.c 2021-11-07 17:22:23.517160157 +0100
@@ -63,6 +63,7 @@
 #define CFG_WRITE_PROXY_V1 "write-proxy-v1"
 #define CFG_WRITE_PROXY_V2 "write-proxy-v2"
 #define CFG_PEM_FILE "pem-file"
+#define CFG_PEM_KEYPASS "pem-keypass"
 #define CFG_PROXY_PROXY "proxy-proxy"
 #define CFG_ALPN_PROTOS "alpn-protos"
 #define CFG_PARAM_ALPN_PROTOS 48173
@@ -307,6 +308,7 @@
    free(cfg->ALPN_PROTOS_LV);
    free(cfg->PEM_DIR);
    free(cfg->PEM_DIR_GLOB);
+   free(cfg->PEM_KEYPASS);
    free(cfg->CLIENT_VERIFY_CA);
 #ifdef USE_SHARED_CACHE
    int i;
@@ -1011,8 +1013,17 @@
                cfg_cert_add(tmp, &cfg->CERT_FILES);
            }
            cfg->CERT_DEFAULT = cert;
-       } else
+       } else {
            cfg_cert_file_free(&cert);
+    }
+   } else if (strcmp(k, CFG_PEM_KEYPASS) == 0) {
+       // this should only be null if we haven't hit the value yet.
+       // if we hit it a second time it's an error
+       if (cfg->PEM_KEYPASS == NULL) {
+           config_assign_str(&cfg->PEM_KEYPASS, v);
+       } else {
+           config_error_set("Duplicate PEM private key passwords");
+       }
    } else if (strcmp(k, CFG_BACKEND_CONNECT_TIMEOUT) == 0) {
        r = config_param_val_int(v, &cfg->BACKEND_CONNECT_TIMEOUT, 1);
    } else if (strcmp(k, CFG_SSL_HANDSHAKE_TIMEOUT) == 0) {
diff -r -u o/hitch/src/configuration.h w/hitch/src/configuration.h
--- o/hitch/src/configuration.h 2021-11-07 17:05:43.354079435 +0100
+++ w/hitch/src/configuration.h 2021-11-07 17:25:16.829151900 +0100
@@ -145,6 +145,7 @@
    char            *PEM_DIR;
    char            *PEM_DIR_GLOB;
    char            *ECDH_CURVE;
+  char      *PEM_KEYPASS;
    int         OCSP_VFY;
    char            *OCSP_DIR;
    double          OCSP_RESP_TMO;
diff -r -u o/hitch/src/hitch.c w/hitch/src/hitch.c
--- o/hitch/src/hitch.c 2021-11-07 17:05:43.355079435 +0100
+++ w/hitch/src/hitch.c 2021-11-07 17:41:35.637945052 +0100
@@ -709,6 +709,24 @@

 #endif /*USE_SHARED_CACHE */

+/* 
+ * callback method for openssl config password handling, effectively just 
+ * copies the user data pointer contents to the buffer.  We pass the pointer
+ * to the config password entry in to the calling method
+ */
+int cfg_pw_callback(char *buf, int size, __attribute__((unused)) int rwflag, void *u) {
+   char *pw = (char*)u;
+   int pwlen = strlen(pw);
+   if (pwlen > size || pwlen <= 0)  {
+       LOG("(config file password callback) Invalid config file password entry.");
+       return 0;
+   }
+
+   memset(buf, '\0', size);
+   memcpy(buf, pw, size);
+   return strlen(pw);
+}
+
 EVP_PKEY *
 load_privatekey(SSL_CTX *ctx, const char *file)
 {
@@ -721,9 +739,16 @@
        return (NULL);
    }

-   pkey = PEM_read_bio_PrivateKey(bio, NULL,
-       SSL_CTX_get_default_passwd_cb(ctx),
-       SSL_CTX_get_default_passwd_cb_userdata(ctx));
+  if(CONFIG->PEM_KEYPASS != NULL) {
+     pkey = PEM_read_bio_PrivateKey(bio, NULL,
+        cfg_pw_callback,
+        (void*)CONFIG->PEM_KEYPASS);
+   } else {
+     pkey = PEM_read_bio_PrivateKey(bio, NULL,
+         SSL_CTX_get_default_passwd_cb(ctx),
+         SSL_CTX_get_default_passwd_cb_userdata(ctx));
+   }
+
    BIO_free(bio);

    if (!pkey) {