Un petit howto pour créer des certificats et les utiliser avec PostgreSQL et pgBouncer.
Autorité de certification avec EasyRSA
Installation
Télécharger et installer la dernière version de EasyRSA. La version 3 est différente de la version 2, fournie dans Debain Stretch.
wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.3/EasyRSA-3.0.3.tgz
tar xzf EasyRSA-3.0.3.tgz
cd EasyRSA-3.0.3
Création de l’autorité de certification
Créer un fichier de configuration :
cp vars.example vars
vi vars
Changer quelques informations :
set_var EASYRSA_REQ_COUNTRY "FR"
set_var EASYRSA_REQ_PROVINCE "Ile-de-France"
set_var EASYRSA_REQ_CITY "Paris"
set_var EASYRSA_REQ_ORG "MyOrg"
set_var EASYRSA_REQ_EMAIL "admin@myorg.lo"
set_var EASYRSA_REQ_OU "Clients"
Créer l’autorité :
./easyrsa init-pki
./easyrsa build-ca
Il faut lui donner un nom, par exemple CA Clients ou PostgreSQL ou un truc significatif. Il faut aussi saisir un mot de passe pour la clé du certificat racine, celui qui permet de signer tout le reste.
Création des certificats
Pour créer un bi-clé pour un serveur :
./easyrsa build-server-full postgresql nopass
Si la clé et le certificat du serveur doivent être transmis pas un moyen peu sécurisé, comme le mail, créer un fichier PKCS#12 plutot qu’un tar :
./easyrsa export-p12 postgresql
On peut mettre un mot de passe au fichier.
./easyrsa build-server-full pgbouncer nopass
Générer aussi la liste de révocation, qui permet rendre des certificats invalides.
./easyrsa gen-crl
Extraction des éléments du p12
La clé privée :
openssl pkcs12 -in postgresql.p12 -nocerts -nodes -out postgresql.key
chmod 600 postgresql.key
Le certificat :
openssl pkcs12 -in postgresql.p12 -clcerts -out postgresql.crt
Le certificat de l’AC :
openssl pkcs12 -in postgresql.p12 -cacerts -out ca.crt
Configurer PostgreSQL pour le TLS
il faut les fichiers suivants :
pki/ca.crt
pki/crl.pem
pki/issued/postgresql.crt
pki/private/postgresql.key
ou
pki/crl.pem
pki/private/postgresql.p12
et extraire le contenu du fichier PKCS#12 (voir plus haut).
Le plus simple est de placer ces fichiers dans le répertoire $PGDATA, les chemins dans la configuration sont relatifs à ce répertoire.
Dans $PGDATA/postgresql.conf, configurer au minimum :
ssl = on
ssl_cert_file = 'postgresql.crt'
ssl_key_file = 'postgresql.key'
ssl_ca_file = 'ca.crt'
ssl_crl_file = 'crl.pem'
Un reload de la configuration suffit pour prendre en compte les modifications. Ce paramétrage permet à l’instance de chiffrer les connexions. On définit si la connexion TLS est imposé au clients et l’authentification par certificat dans le fichier pg_hba.conf
Le TLS ne concerne pas les connections locales par socket unix, géré par le type ‘local’.
Le type ‘host’, concerne les connexions en clair ou TLS, utiliser ‘hostssl’ ou ‘hostnossl’ pour distinguer le TLS dans les autorisations.
On peut interdire les connexions en clair avec ces deux lignes :
hostnossl all all 0.0.0.0/0 reject
hostnossl all all ::/0 reject
Toutes les lignes ‘host’ suivantes ne concerneront que les connexions TLS, du fait de l’interdiction précédente.
Configurer pgBouncer pour le TLS
Clients
il faut les fichiers suivants :
pki/ca.crt
pki/crl.pem
pki/issued/postgresql.crt
pki/private/postgresql.key
ou
pki/crl.pem
pki/private/postgresql.p12
et extraire le contenu du fichier PKCS#12 (voir plus haut).
Dans /etc/pgbouncer/pgbouncer.ini, il faut configurer ‘client_tls_sslmode’ :
- disable : n’accepte pas les connexions TLS, le paramétrage par défaut
- allow : accepte les connexions TLS et les connexions en clair
- require : n’accepte que les connexions TLS
- verify-ca, verify-full : n’accepte que les connexions TLS, et demande un certificat au client issue de la même AC
Pour les chemins vers les fichiers :
client_tls_ca_file = /etc/pgbouncer/ca.crt
client_tls_key_file = /etc/pgbouncer/pgbouncer.key
client_tls_cert_file = /etc/pgbouncer/pgbouncer.crt
Pour authentifier les clients avec un certificat, il faut :
auth_type = cert
Le CN du certificat doit alors être identique au nom d’utilisateur de connexion.
Cela ne dispense pas de la configuration de l’authenfication entre pgBouncer et PostgreSQL, avec ‘auth_file’, voire ‘auth_user’ et ‘auth_query’.
Backends PostgreSQL
Pour que pgBouncer se connecte aux serveurs PostgreSQL en TLS, dans /etc/pgbouncer/pgbouncer.ini, il faut configurer :
server_tls_sslmode = require
Si on souhaite que pgBouncer vérifie le certificat de l’AC du serveur PostgreSQL :
server_tls_sslmode = verify-ca
server_tls_ca_file = /etc/pgbouncer/ca.crt
On peut enfin configurer pgBouncer et PostgreSQL pour que pgBouncer s’authentifie avec un certificat client, dans /etc/pgbouncer.ini :
server_tls_sslmode = verify-ca
server_tls_ca_file = /etc/pgbouncer/ca.crt
server_tls_key_file = /etc/pgbouncer/pgbouncer_back.key
server_tls_cert_file = /etc/pgbouncer/pgbouncer_back.crt
Le fichier pg_hba.conf devra alors demander un certificat avec l’option clientcert=1 :
hostssl all all ip_pgbouncer/32 md5 clientcert=1
On ne peut utiliser la méthode cert uniquement si le CN du certificat client de pgBouncer est identique au nom de l’utilisateur qui se connecte. Ainsi, on ne peut plus utiliser qu’un seul nom d’utilisateur pour les accès à PostgreSQL, dans ce cas là il vaut mieux forcer le nom d’utilisateur dans la section [database].