Vault: SSL/TLS Question

Created on 17 May 2015  路  15Comments  路  Source: hashicorp/vault

Hi,
I am trying to get TLS working.
Here is my vault.hcl on the server :

backend "file" {
  path="/Users/mic/tmp/"
}

listener "tcp" {
  address = "127.0.0.1:8200"
  tls_enable = 1
  tls_cert_file = "/Users/mic/tmp/server.crt"
  tls_key_file = "/Users/mic/tmp/server.key"
}

On the client I export URL like this :

export VAULT_ADDR='https://127.0.0.1:8200'

when I issue vault init command, I keep getting this error :

Error initializing Vault: Put https://127.0.0.1:8200/v1/sys/init: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs

I used the key and cert files from the test folder in your repo.

Please advice.

Thanks !

Most helpful comment

@bigmyx TLS verification is falling because your self signed certificate has a common name which does not match what the host is. The TLS client is connecting to the server at "127.0.0.1:8200", but the CN of the certificate is some other hostname "foo.com". You can use the -tls-skip-verify to avoid this error, but for production you may want to generate a correctly signed cert!

All 15 comments

P.S.
Also tried to create the cert my self like described here and here

@bigmyx TLS verification is falling because your self signed certificate has a common name which does not match what the host is. The TLS client is connecting to the server at "127.0.0.1:8200", but the CN of the certificate is some other hostname "foo.com". You can use the -tls-skip-verify to avoid this error, but for production you may want to generate a correctly signed cert!

Thanks!

Can you explain to generate a correctly signed cert for 127.0.0.1? I tried using:

127.0.0.1 as the Common Name (e.g. server FQDN or YOUR name) but still failing with:

Error initializing: Put https://127.0.0.1:8200/v1/sys/init: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs

@armon @jefferai I'm still experiencing the same error. I'm trying to run vault container using :
docker run -v /home/jwahba/PycharmProjects/work/vault:/usr/secrets --cap-add=IPC_LOCK -e 'VAULT_LOCAL_CONFIG={"backend": {"inmem": {}}, "listener": {"tcp":{"address":"127.0.0.1:8200", "tls_disable":"0", "tls_cert_file": "/usr/secrets/cert.pem", "tls_key_file": "/usr/secrets/key.pem"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h"}, VAULT_SKIP_VERIFY=true' vault server

and I have put the following in openssl.cnf
[ v3_ca ]
subjectAltName = IP:127.0.0.1

and I generated the cert and key using
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

I saw this thread on google groups and tried @jefferai suggestion but didn't work. tried as well this that discusses the same issue but in vain. Can anyone please advice what's the solution for this problem

@nodesocket & @joseph-stratoscale Certificates are tied to domain names. You need to have a domain name that satisfies the certificate attached to the server/container in question. Apparently, the vault command is not able to lookup an entry in the /etc/hosts file. The best bet, if you need to access vault within the container or docker host (and you do to initialize it), is to use the -tls-skip-verify option. Outside of that, have your domain name server reference your hostname to the one running vault. Example: your certificate is for *.example.com. You choose vault.example.com as a domain name for your vault server. The the certificate will match when HTTP requests are made using the domain name. Your vault config needs the "address" field to also reference the domain name (not 127.0.0.1).

@kbuchsicf So, the vault config's address field should be vault.example.com:8200?

Yes, that would do it. But, since you have a wildcard certificate (*.example.com) you can make the prefix what you want (e.g. tluav-backwards.example.com). There are also certificates that are bound to a non-wildcard name, such as my-vault.example.com. Those are cheaper than the wildcard certificates, but you need one for each TLS domain name you want to use. Also, the assumption is that you have control of the domain name you are going to use, so that you can point it at the correct IP address of your server.

api_addr and cluster_addr need to be set to the "https://FQDN:PORT" form (the cluster's port above the API's one). Skipping TLS verification makes TLS useless. Adding a numeric IP to the cert request's alt name makes it vulnerable to spoofing in LAN.

With trial and error, I figured Vault expects an inverted order of certificates in the cert chain file (with the server cert on top). It reads the path to the cert chain file from a property tls_cert_file,

listener "tcp" {
  address = "0.0.0.0:8200"
  tls_disable = false
  tls_cert_file = "/vault/config/vault_chain2.pem"
  tls_key_file  = "/vault/config/vault_key.pem"
}

# Advertise the non-loopback interface
api_addr = "https://vault.FOO.test:8200"
cluster_addr = "https://vault.FOO.test:8201"

The address property above can have all zeros as it's a directive to listen on all IP interfaces.

@bigmyx TLS verification is falling because your self signed certificate has a common name which does not match what the host is. The TLS client is connecting to the server at "127.0.0.1:8200", but the CN of the certificate is some other hostname "foo.com". You can use the -tls-skip-verify to avoid this error, but for production you may want to generate a correctly signed cert!

Thanks this worked for me

export VAULT_SKIP_VERIFY=true

This should do the job temporarily.

Maybe you could set the correct VAULT_ADDR env variable to be matched with the domain name you used to issue your certificate if you are inside the same host, the name is gonna be resolved to the ip address of the node itself, so the packet gets to the vault socket on your vault instance, e.g.

export VAULT_ADDR="https://YOUR_FQDN_NAME_HERE:8200"

I certainly do not recommend to skip the certificate validation for the production env.

I was able to get this working by providing CN as the hostname while generating certificates
Followed this to generate crt,key. (It generates a root key, root cert, a csr which is used to generate vault key and cert)

https://gist.github.com/fntlnz/cf14feb5a46b2eda428e000157447309

storage "consul" {
  address = "127.0.0.1:8500"
  path    = "vault/"
}

listener "tcp" {
 address     = "dummy.vault.com:8200"
  tls_cert_file = "/home/dorian/ValutLearning/vault.com.crt"
  tls_key_file  = "/home/dorian/ValutLearning/vault.com.key"
}
disable_mlock = true

export VAULT_ADDR='https://dummy.vault.com:8200'
export VAULT_CACERT=/home/dorian/ValutLearning/rootCA.crt
Above is required to access vault from command line I guess.

Following is required for curl without explicit --cacert. (For ubuntu 14.04, depends on OS)
sudo cp rootCA.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

Or alternatively you can curl with --cacert:
curl --cacert rootCA.crt --header "X-Vault-Token: s.**********" --request GET https://dummy.vault.com:8200/v1/secret/hello

EXTFILE for IP SANS !!!! when signing CSR to CRT
https://www.golinuxcloud.com/openssl-create-client-server-certificate/
openssl x509 -req -in server.csr -CA selfca.crt -CAkey selfca.key -CAcreateserial --extensions v3_req -extfile server.req -out server.crt

Was this page helpful?
0 / 5 - 0 ratings

Related issues

anthonyGuo picture anthonyGuo  路  3Comments

adamroddick picture adamroddick  路  3Comments

frntn picture frntn  路  3Comments

mfischer-zd picture mfischer-zd  路  3Comments

gtmtech picture gtmtech  路  3Comments