From 24a1eb20e154e180e477d96a2a1207709760f235 Mon Sep 17 00:00:00 2001 From: Alex Shearn <244545+shearn89@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:51:00 +0100 Subject: [PATCH] Add support for mutual authentication via TLS (#459) Prior to this change, there was no way to pass in a client certificate if you had set up Nexus behind a load balancer with mutual auth configured. This change exposes some new configuration values that allow you to pass in a path to a file on disk containing your client key/cert (which can be in a single file) and optionally a Root CA. --- README.md | 29 +++++++++++++++++++++++++---- internal/provider/main.go | 34 +++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 57b13aca..dd658bd9 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,34 @@ Implemented and tested with Sonatype Nexus `3.70.1-02`. ```hcl provider "nexus" { - insecure = true - password = "admin123" - url = "https://127.0.0.1:8080" - username = "admin" + insecure = true + password = "admin123" + url = "https://127.0.0.1:8080" + username = "admin" } ``` +Optionally with mTLS if Nexus is deployed behind a reverse proxy: + +```hcl +provider "nexus" { + insecure = true + password = "admin123" + url = "https://127.0.0.1:8080" + username = "admin" + client_cert_path = "/path/to/client.crt" + client_key_path = "/path/to/client.key" + root_ca_path = "/path/to/root_ca.crt" +} +``` + +Note that the `root_ca_path` should contain ALL certificates required for +communication. It overrides the system CA store, rather than adding to it. + +You can point the `root_ca_path` to the system trust store if required, e.g.: + +`root_ca_path = "/etc/ssl/certs/ca-certificates.crt"` + ## Development ### Build diff --git a/internal/provider/main.go b/internal/provider/main.go index 6bb79628..0b0b70e3 100755 --- a/internal/provider/main.go +++ b/internal/provider/main.go @@ -178,6 +178,24 @@ func Provider() *schema.Provider { Optional: true, Type: schema.TypeInt, }, + "client_cert_path": { + Description: "Path to a client PEM certificate to load for mTLS. Reading environment variable NEXUS_CLIENT_CERT_PATH. Default:``", + DefaultFunc: schema.EnvDefaultFunc("NEXUS_CLIENT_CERT_PATH", ""), + Optional: true, + Type: schema.TypeString, + }, + "client_key_path": { + Description: "Path to a client PEM key to load for mTLS. Reading environment variable NEXUS_CLIENT_KEY_PATH. Default:``", + DefaultFunc: schema.EnvDefaultFunc("NEXUS_CLIENT_KEY_PATH", ""), + Optional: true, + Type: schema.TypeString, + }, + "root_ca_path": { + Description: "Path to a root CA certificate to load for mTLS. Reading environment variable NEXUS_ROOT_CA_PATH. Default:``", + DefaultFunc: schema.EnvDefaultFunc("NEXUS_ROOT_CA_PATH", ""), + Optional: true, + Type: schema.TypeString, + }, }, ConfigureFunc: providerConfigure, } @@ -185,12 +203,18 @@ func Provider() *schema.Provider { func providerConfigure(d *schema.ResourceData) (interface{}, error) { timeout := d.Get("timeout").(int) + clientCertPath := d.Get("client_cert_path").(string) + clientKeyPath := d.Get("client_key_path").(string) + rootCaPath := d.Get("root_ca_path").(string) config := client.Config{ - Insecure: d.Get("insecure").(bool), - Password: d.Get("password").(string), - URL: d.Get("url").(string), - Username: d.Get("username").(string), - Timeout: &timeout, + Insecure: d.Get("insecure").(bool), + Password: d.Get("password").(string), + URL: d.Get("url").(string), + Username: d.Get("username").(string), + Timeout: &timeout, + ClientCertificatePath: &clientCertPath, + ClientKeyPath: &clientKeyPath, + RootCAPath: &rootCaPath, } return nexus.NewClient(config), nil