Client authentication with TLS
Database users or roles granted a tls
authentication record can authenticate to Vertica with a TLS certificate.
Prerequisites
You must configure Vertica for mutual mode client-server TLS.
In mutual mode, the client and server must verify each other's identity before connecting. This mode allows Vertica to verify the identity of the client and allow them to authenticate the client through their certificate.
Configuring TLS authentication
The following sections generate a private key and certificate for the client. For simplicity, the example signs the client certificate with the following self-signed CA certificate (which has also, in the context of the example, signed the Vertica database's server certificate):
=> CREATE KEY SSCA_key TYPE 'RSA' LENGTH 2048;
=> CREATE CA CERTIFICATE ca_certificate
SUBJECT '/C=US/ST=Massachusetts/L=Cambridge/O=OpenText/OU=Vertica/CN=Vertica Root CA'
VALID FOR 3650
EXTENSIONS 'nsComment' = 'Self-signed root CA cert'
KEY SSCA_key;
In a production environment, you should instead use a CA certificate from a trusted certificate authority.
Create client keys
The following steps generate a client key and certificate, and then make them available to the client:
-
Generate the client key:
=> CREATE KEY client_private_key TYPE 'RSA' LENGTH 2048; CREATE KEY
-
Generate the client certificate. Mutual TLS requires that the Common Name (
CN
) in theSUBJECT
specifies a database username:=> CREATE CERTIFICATE client_certificate SUBJECT '/C=US/ST=Massachusetts/L=Cambridge/O=OpenText/OU=Vertica/CN=dbadmin/emailAddress=example@example.com' SIGNED BY ca_certificate EXTENSIONS 'nsComment' = 'Vertica client cert', 'extendedKeyUsage' = 'clientAuth' KEY client_private_key; CREATE CERTIFICATE
-
On the client machine, export the client key and client certificate to the client filesystem. The following commands use the vsql client:
$ vsql -At -c "SELECT key FROM cryptographic_keys WHERE name = 'client_private_key';" -o client_private_key.key $ vsql -At -c "SELECT certificate_text FROM certificates WHERE name = 'client_certificate';" -o client_cert.pem
In the preceding command:
-A
: enables unaligned output.-t
: prevents the command from outputting metadata, such as column names.-c
: instructs the shell to run one command and then exit.-o
: writes the query output to the specified filename.
For details about all vsql command line options, see Command-line options
-
Copy or move the client key and certificate to a location that your client recognizes.
The following commands move the client key and certificate to the hidden directory
~/.client-creds
, and then grants the file owner read and write permissions withchmod
:$ mkdir ~/.client-creds $ mv client_private_key.key ~/.client-creds/client_key.key $ mv client_cert.pem ~/.client-creds/client_cert.pem $ chmod 600 ~/.client-creds/client_key.key ~/.client-creds/client_cert.pem
Create an authentication record
Next, you must create an authentication record in the database. An authentication record defines a set of authentication and the access methods for the database. You grant this record to a user or role to control how they authenticate to the database:
-
Create the authentication record. The
tls
method requires that clients authenticate with a certificate whose Common Name (CN) specifies a database username:=> CREATE AUTHENTICATION auth_record METHOD 'tls' HOST TLS '0.0.0.0/0'; CREATE AUTHENTICATION
-
Grant the authentication record to a user or to a role. The following example grants the authentication record to PUBLIC, the default role for all users:
=> GRANT AUTHENTICATION auth_record TO PUBLIC; GRANT AUTHENTICATION
Reject plaintext connections
You can create an authentication record that rejects remote connections from a specified IP range.
For example, to reject all plaintext client connections, specify the reject
authentication method and the HOST NO TLS
access method as follows:
=> CREATE AUTHENTICATION RejectNoSSL METHOD 'reject' HOST NO TLS '0.0.0.0/0'; --IPv4
=> CREATE AUTHENTICATION RejectNoSSL METHOD 'reject' HOST NO TLS '::/0'; --IPv6