diff --git a/README.md b/README.md index 0c3145f36df..43b986244a1 100644 --- a/README.md +++ b/README.md @@ -130,8 +130,8 @@ the `--storepass` flag. If you want to use ghostunnel with a PKCS#11 module, see the section on PKCS#11 below. In the event your certificate and key are not bundled together (for example -created by cert-manager in Kubernetes), you can use `--keystore ` -and `--keystoreKeyPath `. +created by cert-manager in Kubernetes), you can use `--cert ` +and `--key `. ### Server mode diff --git a/main.go b/main.go index 6d0c58ad4d8..f596c7dd34c 100644 --- a/main.go +++ b/main.go @@ -91,7 +91,8 @@ var ( // TLS options keystorePath = app.Flag("keystore", "Path to certificate and keystore (PEM with certificate/key, or PKCS12).").PlaceHolder("PATH").String() - keystoreKeyPath = app.Flag("keystoreKeyPath", "Path to certificate key (PEM with key).").PlaceHolder("PATH").String() + cert = app.Flag("cert", "Path to certificate (PEM without key).").PlaceHolder("PATH").String() + key = app.Flag("key", "Path to certificate private key (PEM key).").PlaceHolder("PATH").String() keystorePass = app.Flag("storepass", "Password for certificate and keystore (optional).").PlaceHolder("PASS").String() caBundlePath = app.Flag("cacert", "Path to CA bundle file (PEM/X509). Uses system trust store by default.").String() enabledCipherSuites = app.Flag("cipher-suites", "Set of cipher suites to enable, comma-separated, in order of preference (AES, CHACHA).").Default("AES,CHACHA").String() @@ -216,8 +217,11 @@ func serverValidateFlags() error { len(*serverAllowedIPs) > 0 || len(*serverAllowedURIs) > 0 - if *keystorePath == "" && !hasKeychainIdentity() { - return errors.New("at least one of --keystore or --keychain-identity (if supported) flags is required") + if (*key != "" && *cert == "") || (*key == "" && *cert != "") { + return errors.New("both key and cert are required") + } + if (*key == "" && *cert == "" && *keystorePath == "") && !hasKeychainIdentity() { + return errors.New("at least one of --keystore/cert/key or --keychain-identity (if supported) flags is required") } if *keystorePath != "" && hasKeychainIdentity() { return errors.New("--keystore and --keychain-identity flags are mutually exclusive") @@ -326,7 +330,7 @@ func run(args []string) error { } metrics := sqmetrics.NewMetrics(*metricsURL, *metricsPrefix, client, *metricsInterval, metrics.DefaultRegistry, logger) - cert, err := buildCertificate(*keystorePath, *keystoreKeyPath, *keystorePass) + cert, err := buildCertificate(*keystorePath, *cert, *key, *keystorePass) if err != nil { fmt.Fprintf(os.Stderr, "error: unable to load certificates: %s\n", err) return err diff --git a/tls.go b/tls.go index e6c69ba7787..2bd424b8f7e 100644 --- a/tls.go +++ b/tls.go @@ -41,17 +41,17 @@ var cipherSuites = map[string][]uint16{ } // Build reloadable certificate -func buildCertificate(keystorePath, keystoreKeyPath, keystorePass string) (certloader.Certificate, error) { +func buildCertificate(keystorePath, certPath, keyPath, keystorePass string) (certloader.Certificate, error) { if hasPKCS11() { return buildCertificateFromPKCS11(keystorePath) } if hasKeychainIdentity() { return buildCertificateFromCertstore() } + if keyPath != "" && certPath != "" { + return certloader.CertificateFromPEMFiles(certPath, keyPath) + } if keystorePath != "" { - if keystoreKeyPath != "" { - return certloader.CertificateFromPEMFiles(keystorePath, keystoreKeyPath) - } return certloader.CertificateFromKeystore(keystorePath, keystorePass) } return nil, nil diff --git a/tls_test.go b/tls_test.go index 69eb40130aa..476181dccfc 100644 --- a/tls_test.go +++ b/tls_test.go @@ -229,26 +229,26 @@ func TestBuildConfig(t *testing.T) { assert.Nil(t, conf, "conf with invalid params should be nil") assert.NotNil(t, err, "should reject invalid CA cert bundle") - cert, err := buildCertificate("", "", "") + cert, err := buildCertificate("", "", "", "") assert.Nil(t, err, "empty keystorePath should not raise an error") - cert, err = buildCertificate(tmpKeystore.Name(), "", "totes invalid") + cert, err = buildCertificate(tmpKeystore.Name(), "", "", "totes invalid") assert.Nil(t, cert, "cert with invalid params should be nil") assert.NotNil(t, err, "should reject invalid keystore pass") - cert, err = buildCertificate("does-not-exist", "", testKeystorePassword) + cert, err = buildCertificate("does-not-exist", "", "", testKeystorePassword) assert.Nil(t, cert, "cert with invalid params should be nil") assert.NotNil(t, err, "should reject missing keystore (not found)") - cert, err = buildCertificate(tmpKeystoreNoPrivKey.Name(), "", "") + cert, err = buildCertificate(tmpKeystoreNoPrivKey.Name(), "", "", "") assert.Nil(t, cert, "cert with invalid params should be nil") assert.NotNil(t, err, "should reject invalid keystore (no private key)") - cert, err = buildCertificate("/dev/null", "", "") + cert, err = buildCertificate("/dev/null", "", "", "") assert.Nil(t, cert, "cert with invalid params should be nil") assert.NotNil(t, err, "should reject invalid keystore (empty)") - cert, err = buildCertificate(tmpKeystoreSeparateCert.Name(), tmpKeystoreSeparateKey.Name(), "") + cert, err = buildCertificate("", tmpKeystoreSeparateCert.Name(), tmpKeystoreSeparateKey.Name(), "") assert.Nil(t, cert, "cert with sep key be ok") } @@ -286,7 +286,7 @@ func TestReload(t *testing.T) { defer os.Remove(tmpKeystore.Name()) - c, err := buildCertificate(tmpKeystore.Name(), "", testKeystorePassword) + c, err := buildCertificate(tmpKeystore.Name(), "", "", testKeystorePassword) assert.Nil(t, err, "should be able to build certificate") c.Reload()