Skip to content

Add TLS configuration#37

Open
heurtematte wants to merge 1 commit intolrstanley:masterfrom
heurtematte:master
Open

Add TLS configuration#37
heurtematte wants to merge 1 commit intolrstanley:masterfrom
heurtematte:master

Conversation

@heurtematte
Copy link
Copy Markdown
Contributor

🚀 Changes proposed by this PR

I propose to add full TLS configuration for vault client.

TLS struct {
	CACert        string `env:"TLS_CA_CERT" long:"ca-cert" description:"the path to a PEM-encoded CA cert file to use to verify the Vault server SSL certificate. It takes precedence over CACertBytes and CAPath" yaml:"ca_cert"`
	CACertBytes   []byte `env:"TLS_CA_CERT_BYTES" long:"ca-cert-bytes" description:"PEM-encoded certificate or bundle. It takes precedence over CAPath" yaml:"ca_cert_bytes"`
	CAPath        string `env:"TLS_CA_PATH" long:"ca-path" description:"path to a directory of PEM-encoded CA cert files to verify the Vault server SSL certificate" yaml:"ca_path"`
	ClientCert    string `env:"TLS_CLIENT_CERT" long:"client-cert" description:"path to the certificate for Vault communication" yaml:"client_path"`
	ClientKey     string `env:"TLS_CLIENT_KEY" long:"client-key" description:"path to the private key for Vault communication" yaml:"client_key"`
	TLSServerName string `env:"TLS_SERVER_NAME" long:"server-name" description:"if set, is used to set the SNI host when connecting via TLS" yaml:"server_name"`
	Insecure      bool   `env:"TLS_INSECURE" long:"insecure" description:"enables or disables SSL verification: DO NOT DO THIS" yaml:"insecure"`
} `group:"TLS Options" namespace:"tls" yaml:"tls"`

tls_skip_verifyis replaced by insecure parameter in tlsstruct.

i.e:

tls:
  insecure: false

🧰 Type of change

  • Bug fix (non-breaking change which fixes an issue).
  • New feature (non-breaking change which adds functionality).
  • Breaking change (fix or feature that causes existing functionality to not work as expected).
  • This change requires (or is) a documentation update.

Signed-off-by: sebastien.heurtematte <sebastien.heurtematte@eclipse-foundation.org>

TLS struct {
CACert string `env:"TLS_CA_CERT" long:"ca-cert" description:"the path to a PEM-encoded CA cert file to use to verify the Vault server SSL certificate. It takes precedence over CACertBytes and CAPath" yaml:"ca_cert"`
CACertBytes []byte `env:"TLS_CA_CERT_BYTES" long:"ca-cert-bytes" description:"PEM-encoded certificate or bundle. It takes precedence over CAPath" yaml:"ca_cert_bytes"`
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of ca-cert, ca-cert-bytes, and ca-path all being supported? ca-path is going to be the most secure option, so should probably be the only supported option out of the three.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is ca path the most secure option? Why are you trying to "secure" a certificate? It's not sensitive by any means, it's meant to be distributed. Would be convenient to just put the cert content directly in the configuration, and use a file path as an alternative

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect I was likely mistaking it for client cert/key pair, which is below, and is sensitive (the key portion is, but like stated below, inputs should be provided in the same way, and env vars are less secure).

In any case, no need for 3 ways to do it, 1 is sufficient, and 1 which matches all other formats for providing certificates and keys.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike the client cert and key, it would be far more common for a user to need a ca cert. Only doing mutual TLS would require a client cert and key (rare). Therefore in most situations there will be no need to write additional files to a filesystem, making the ca cert load by content a very attractive option. I agree that 3 ways may be generous, but don't discount how convenient it is to embed the ca cert directly in the config or env var.

ClientKey string `env:"TLS_CLIENT_KEY" long:"client-key" description:"path to the private key for Vault communication" yaml:"client_key"`
TLSServerName string `env:"TLS_SERVER_NAME" long:"server-name" description:"if set, is used to set the SNI host when connecting via TLS" yaml:"server_name"`
Insecure bool `env:"TLS_INSECURE" long:"insecure" description:"enables or disables SSL verification: DO NOT DO THIS" yaml:"insecure"`
} `group:"TLS Options" namespace:"tls" yaml:"tls"`
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

env-namespace:"TLS" can be added here, and the TLS_ prefix can be removed from all other flags.

)

func ConvertTLSConfigToTLS(src Config, dest *vapi.TLSConfig) error {
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using mapstructure here feels fragile, as it moves most type safety to runtime, rather than compile time. Mapping from flags to vault TLSConfig{} should be done specifically for the fields we want to override via struct initialization, similar to what we had before.

ClientCert string `env:"TLS_CLIENT_CERT" long:"client-cert" description:"path to the certificate for Vault communication" yaml:"client_path"`
ClientKey string `env:"TLS_CLIENT_KEY" long:"client-key" description:"path to the private key for Vault communication" yaml:"client_key"`
TLSServerName string `env:"TLS_SERVER_NAME" long:"server-name" description:"if set, is used to set the SNI host when connecting via TLS" yaml:"server_name"`
Insecure bool `env:"TLS_INSECURE" long:"insecure" description:"enables or disables SSL verification: DO NOT DO THIS" yaml:"insecure"`
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TLS_SKIP_VERIFY is common for Go apps, so I would prefer to keep the naming standard. with the below note about env-namespace, if you keep the environment variable as SKIP_VERIFY, this will ensure the old environment variable method approach to providing this flag will still work.

I would still support --tls-skip-verify, however, remove env from the old flag. In the TLSConfig{} initialization, the new flag should take priority.

CAPath string `env:"TLS_CA_PATH" long:"ca-path" description:"path to a directory of PEM-encoded CA cert files to verify the Vault server SSL certificate" yaml:"ca_path"`
ClientCert string `env:"TLS_CLIENT_CERT" long:"client-cert" description:"path to the certificate for Vault communication" yaml:"client_path"`
ClientKey string `env:"TLS_CLIENT_KEY" long:"client-key" description:"path to the private key for Vault communication" yaml:"client_key"`
TLSServerName string `env:"TLS_SERVER_NAME" long:"server-name" description:"if set, is used to set the SNI host when connecting via TLS" yaml:"server_name"`
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost forgot, I don't see a scenario where --tls.server-name should be used -- if it is, sounds like there might be a misconfiguration, legacy environment, etc, which I don't think should be supported.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A scenario for --tls.server-name would be that you have a single TLS certificate for vault.example.com and use e.g. HAProxy in TCP mode to forward the API requests to the leader node. In that case vault.example.com DNS points to the HAProxy but when connecting to each node's API directly the certificate will not match the IP/hostname.

It sounds like this might be a common scenario because Vault client has -tls-server-name flag and in raft storage retry_join stanza has leader_tls_servername option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants