Introduction
Even for development purposes or to test products, we want to setup HTTPS, especially if we want the packets to be encrypted over internet network.
Creating a self-signed certicicate is quite easy in the "quick and dirty way" : public certificate + private key.
$ openssl req -x509 -out VPSFRSQLPAC.crt -keyout VPSFRSQLPAC.key \
-newkey rsa:2048 -nodes -sha256 -days 3650 \
-subj '/CN=VPSFRSQLPAC' -extensions EXT -config <( \
printf "[dn]\nCN=VPSFRSQLPAC\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:VPSFRSQLPAC\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
In the above example, a self-signed certificate is created for the host vpsfrsqlpac
.
-days 3650
: 10 years (for development purposes, should be enough…).VPSFRSQLPAC.key
: private key.VPSFRSQLPAC.crt
: public certificate.
The product for which we want HTTPS is then started with the certificates, for example InfluxDB :
influxdb.toml
tls-cert = "/etc/ssl/VPSFRSQLPAC.crt"
tls-key = "/etc/ssl/VPSFRSQLPAC.key"
On the client machine, the public certificate (VPSFRSQLPAC.crt
) is imported in the trusted root certification authorities certificate store.
https://vpsfrsqlpac:8086
works very well on the client until more sophisticated commands are needed and invoked, commands which then raise x509
errors :
x509: certificate signed by unknown authority
Options exist to prevent checks up to certificate authority : curl --insecure
, influx --skip verify
. As time goes by,
we don’t want to use these options everywhere, especially in maintenance scripts.
Let’s see how to create our own tiny fictitious certificate authority (SQLPAC in this paper).
For brevity reasons in the following sections, certificate authority will often be shortened to CA.
Creating the Certificate Authority SQLPAC
For the ficticious Certificate Authority SQLPAC, a private key sqlpac.key
(2048 bytes length) is created in the directory /etc/ssl/sqlpac
:
$ openssl genrsa -out /etc/ssl/sqlpac/sqlpac.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes) ............................................+++++ ..............+++++ e is 65537 (0x010001)
To apply a password if needed, add the flag -des3
or -aes256
. Password will be prompted when generating the key.
The associated public certificate sqlpac.crt
is generated :
openssl req -x509 -new -nodes \
-key /etc/ssl/sqlpac/sqlpac.key \
-sha256 \
-days 3650 \
-out /etc/ssl/sqlpac/sqlpac.crt \
-subj "/O=SQLPAC/CN=SQLPAC - Certificate authority/OU=SQLPAC - Certificate authority"
-x509
: request to generate a X.509 certificate.-days 3650
: certificate expiration period.-sha256
: SHA-256 encryption algorithm (by default SHA-1 algorithm is used, weaker from a security point of view).-new
: generation of a new public certificate.-nodes
: no passphrase.-key sqlpac.key
: certificate authority RSA private key, generated previously.-out sqlpac.crt
: certificate authority public certificate filename in output.-subj "/O=SQLPAC/CN=SQLPAC - Certificate authority"
: specify the organization (/O=SQLPAC
) and the common name (/CN=SQLPAC - Certificate authority
). When omitted,openssl
prompts for them.
The common name (CN) is the name displayed in the clients certificates stores.
Deploying the CA authority public certificate on clients
The public certificate sqlpac.crt
is then deployed to all clients certificates stores.
Windows
On Windows, to import the public certificate sqlpac.crt
, open Microsoft Management Console (MMC) :
MMC File Add/Remove Snap-in… Certificates
Import the certificate authority public certificate (sqlpac.crt
) into the "Trusted Root Certification Authorities" store
from the context menu Certificates All Tasks Import… :
Ubuntu
On Ubuntu, as root
, copy the CA public certificate to the directory /usr/local/share/ca-certificates
:
$ cp /etc/ssl/sqlpac/sqlpac.crt /usr/local/share/ca-certificates/extra
Run update-ca-certificates
:
$ update-ca-certificates
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done.
Clients are ready.
Generating the private key for https://vpsfrsqlpac and the signing request
The certificate authority SQLPAC is ready. A private key for https://vpsfrsqlpac
is created : VPSFRSQLPAC.key
.
openssl req -new -sha256 -nodes \ -out /etc/ssl/VPSFRSQLPAC.csr \ -newkey rsa:2048 -keyout /etc/ssl/VPSFRSQLPAC.key \ -subj "/O=SQLPAC/CN=VPSFRSQLPAC"
Generating a RSA private key .............................................................+++++ .............+++++ writing new private key to '/etc/ssl/VPSFRSQLPAC.key' -----
The option -out /etc/ssl/VPSFRSQLPAC.csr
produces a signing request file (CSR - Common Signing Request).
This CSR will be submitted later to SQLPAC certificate authority to get the associated public certificate signed by the CA.
CN
parameter must be the same than the hostname in the URL.
CN=VPSFRSQLPAC https://vpsfrsqlpac
If the private key is generated by root
account, do not forget to modify the permissions. By default
openssl
creates the key RSA file in read only mode to the used account.
$ chmod o+r VPSFRSQLPAC.key
Getting the signed public certificate
Last step, the associated public certificate VPSFRSQLPAC.crt
signed by SQLPAC CA is generated.
openssl x509 -req \ -in /etc/ssl/VPSFRSQLPAC.csr \ -CAkey /etc/ssl/sqlpac/sqlpac.key \ -CA /etc/ssl/sqlpac/sqlpac.crt \ -CAcreateserial -CAserial /etc/ssl/VPSFRSQLPAC.serial \ -out /etc/ssl/VPSFRSQLPAC.crt \ -days 3650 \ -sha256 \ -extfile /etc/ssl/VPSFRSQLPAC.sslv3.txt
Signature ok subject=O = SQLPAC, CN = VPSFRSQLPAC Getting CA Private Key
-in /etc/ssl/VPSFRSQLPAC.csr
: the signing request in input.-CAkey /etc/ssl/sqlpac/sqlpac.key
: CA RSA private key.-CA /etc/ssl/sqlpac/sqlpac.crt
: CA public certificate.-CAcreateserial -CAserial /etc/ssl/VPSFRSQLPAC.serial
: optional, serial number generation.-out /etc/ssl/VPSFRSQLPAC.crt
: the signed public certificate in output.
In the file /etc/ssl/VPSFRSQLPAC.sslv3.txt
sent with the argument -extfile
,
some SSL v3 parameters are specified, especially the alternative DNS names (https://<DNS names>
)
VPSFRSQLPAC.sslv3.txt
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = vpsfrsqlpac
It is an important directive. For Apache, alternative names alt_names
will look like the below example for all possible URLs (https://fr.sqlpac.uat
, https://sqlpac.uat
…) :
[alt_names]
DNS.1 = sqlpac.uat
DNS.2 = *.sqlpac.uat
Final steps, checks
That’s all, everything is ready. Restart the softwares running on https://vpsfrsqlpac:*
with the private key and the public certificate :
influxdb.toml | grafana.ini |
---|---|
|
|
No need anymore to add extra options to command lines (curl --insecure
, influx --skip-verify
…) in order to prevent CA check.
How to test the validation mechanism with the CA ? Use openssl
with the option s_client
, the
validation path is displayed :
$ openssl s_client -connect vpsfrsqlpac:8086
CONNECTED(00000005) … --- Certificate chain 0 s:O = SQLPAC, CN = VPSFRSQLPAC i:O = SQLPAC, CN = SQLPAC - Certificate authority, OU = SQLPAC - Certificate authority --- … SSL handshake has read 1615 bytes and written 793 bytes Verification: OK … New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256 … Verify return code: 0 (ok) …