-
Notifications
You must be signed in to change notification settings - Fork 375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
configuring users with TLS certificate authentication does not seem to exist in hvac #481
Comments
Ack! Blank description. I want to do the equivalent of: vault write auth/cert/certs/ I don't see a way to do it currently in hvac. Please let me know because I might be able to create a pull request with it implemented. |
Hi @buchs, did you end up implementing this feature? I'm keen to use it. I thought that the 'enable_auth_method()' might be a simple wrapper around the Vault (https://www.vaultproject.io/api-docs/system/auth) auth api endpoint, but alas, hvac wants a class implemented for each auth method. |
I did not end up using this. |
OK, thanks Kevin. |
Hi, I would like to use this feature in my code aswell, any updates as far as implementation?
|
I'll take a look at adding support for the TLS Certificates auth method over the next week or so. |
Thanks for looking into this. |
Should be solved with #691 |
Hi @Tylerlhess, thanks for giving this a go. For context, I'd like to be able to use your new implementation for mutual TLS authentication between the Vault instance and the hvac client. It seemed I had the auth part working up through hvac 0.10.11 using the auth_tls method. The storing of the certificates on the cert mount point, I had to do outside hvac. Afterwards (>= hvac 0.10.12), something else has changed where the client certificate appears to be dropped. This looks like it isn't necessarily related to your work but something deeper. To help give a bit more context, here's an adapted toy example: #!/usr/bin/env python
import hvac
import json
import logging as logger
import sys
from pydantic import BaseSettings
logger.basicConfig(stream=sys.stdout, level=logger.DEBUG)
class VaultSettings(BaseSettings):
VAULT_SERVER_NAME: str = "vault"
VAULT_SERVER_URL: str = "https://kme1:8200"
CLIENT_NAME: str = "watcher"
CERT_DIRPATH: str = "/volumes/kme1/certificates/production/admin"
CLIENT_DIRPATH: str = f"{CERT_DIRPATH}/{CLIENT_NAME}"
CA_CHAIN_SUFFIX: str = ".ca-chain.cert.pem"
KEY_SUFFIX: str = ".key.pem"
CLIENT_CERT_FILEPATH: str = f"{CLIENT_DIRPATH}/{CLIENT_NAME}{CA_CHAIN_SUFFIX}"
CLIENT_KEY_FILEPATH: str = f"{CLIENT_DIRPATH}/{CLIENT_NAME}{KEY_SUFFIX}"
SERVER_CERT_FILEPATH: str = f"{CERT_DIRPATH}/{VAULT_SERVER_NAME}/{VAULT_SERVER_NAME}{CA_CHAIN_SUFFIX}"
VAULT_CERT_AUTH_MOUNT_POINT: str = "cert"
settings = VaultSettings()
class VaultClientAuthCert:
def __init__(self) -> None:
"""Authenticate to Vault server instance with TLS certificates
"""
self.create_client()
def create_client(self) -> None:
"""Create hvac vault client
"""
logger.info("Attempt hvac create client")
logger.debug(f"Vault Server URL: {settings.VAULT_SERVER_URL}")
logger.debug(f"Client Certificate Filepath: {settings.CLIENT_CERT_FILEPATH}")
logger.debug(f"Client Key Filepath: {settings.CLIENT_KEY_FILEPATH}")
logger.debug(f"Server CA Chain Filepath: {settings.SERVER_CERT_FILEPATH}")
self.vclient: hvac.Client = \
hvac.Client(url=settings.VAULT_SERVER_URL,
cert=(settings.CLIENT_CERT_FILEPATH,
settings.CLIENT_KEY_FILEPATH),
verify=settings.SERVER_CERT_FILEPATH
)
def vault_cert_client_auth(self,
role_name: str = settings.CLIENT_NAME
) -> None:
mount_point = settings.VAULT_CERT_AUTH_MOUNT_POINT
logger.info("Attempt TLS client login")
logger.debug(f"Cert Auth Mount Point: {mount_point}")
auth_response = self.vclient.auth.\
cert.login(name=role_name,
cacert=False, # Should already be picked up from verify above?
cert_pem=settings.CLIENT_CERT_FILEPATH,
key_pem=settings.CLIENT_KEY_FILEPATH,
mount_point=mount_point,
use_token=True)
logger.debug(f"Vault auth response: {json.dumps(auth_response, indent=2, sort_keys=True)}")
if self.vclient.is_authenticated():
logger.info(f"\"{settings.CLIENT_NAME}\" is now authenticated")
else:
logger.info(f"\"{settings.CLIENT_NAME}\" has failed to authenticate")
# Old method of logging in. Works up through hvac 0.10.11
# Afterwards:
# Vault log info: http: TLS handshake error from ... tls: client didn't provide a certificate
# requests.exceptions.SSLError: HTTPSConnectionPool(host='...', port=8200): Max retries
# exceeded with url: /v1/auth/cert/login (Caused by SSLError(SSLError(1, '[SSL:
# SSLV3_ALERT_BAD_CERTIFICATE] sslv3 alert bad certificate (_ssl.c:2633)')))
def vault_client_auth_tls(self) -> None:
mount_point = settings.VAULT_CERT_AUTH_MOUNT_POINT
logger.info("Attempt TLS client login")
logger.debug(f"Cert Auth Mount Point: {mount_point}")
auth_response = self.vclient.\
auth_tls(mount_point=mount_point,
use_token=True
)
logger.debug(f"Vault auth response: {json.dumps(auth_response, indent=2, sort_keys=True)}")
if self.vclient.is_authenticated():
logger.info(f"\"{settings.CLIENT_NAME}\" is now authenticated")
else:
logger.info(f"\"{settings.CLIENT_NAME}\" has failed to authenticate")
if __name__ == "__main__":
# toggle between hvac versions to get old client to work
logger.debug("Try new auth method")
new_client = VaultClientAuthCert().vault_cert_client_auth()
logger.debug("Try auth_tls method")
old_client = VaultClientAuthCert().vault_client_auth_tls() In hvac 0.10.10, this runs the old method okay and the new method isn't implemented yet. In 0.10.14, both auth methods seem to fail because of the same reason. new_method: hvac.exceptions.InvalidRequest: invalid certificate or no client certificate supplied, on post https://kme1:8200/v1/auth/cert/login old method: requests.exceptions.SSLError: HTTPSConnectionPool(host='kme1', port=8200): Max retries exceeded with url: /v1/auth/cert/login (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_BAD_CERTIFICATE] sslv3 alert bad certificate (_ssl.c:2633)')))
vault output:
http: TLS handshake error from ...: tls: client didn't provide a certificate
Hopefully someone can shed some light what I might be doing incorrectly or what might be happening. Thanks! |
No description provided.
The text was updated successfully, but these errors were encountered: