PostgreSQL™ dispose d'un support natif des connexions SSL pour crypter les connexions client/serveur et améliorer ainsi la sécurité. Voir la Section 17.9, « Connexions tcp/ip sécurisées avec ssl » pour des détails sur la fonctionnalité SSL côté serveur.
libpq lit le fichier de configuration système d'OpenSSL™. Par défaut, ce fichier est nommé openssl.cnf et est placé dans le répertoire indiqué par openssl version -d. Cette valeur par défaut peut être surchargé en configurant la variable d'environnement OPENSSL_CONF avec le nom du fichier de configuration souhaité.
Par défaut, PostgreSQL™ ne vérifie pas le certificat du serveur. Cela signifie qu'il est possible de se faire passer pour le serveur final (par exemple en modifiant un enregistrement DNS ou en prenant l'adresse IP du serveur) sans que le client ne le sache. Pour empêcher ceci, la vérification du certificat SSL doit être activée.
Si le paramètre sslmode est configuré à verify-ca, libpq vérifiera que le serveur est de confiance en vérifiant que le certificat a bien été généré par une autorité de certificats (CA) de confiance. Si sslmode est configuré à verify-full, libpq vérifiera aussi que le nom du serveur correspond à son certificat. La connexion SSL échouera si le certificat du serveur n'établit pas ces correspondances. La connexion SSL échouera si le certificat du serveur ne peut pas être vérifié. verify-full est recommandé pour les environnements les plus sensibles à la sécurité.
Dans le mode verify-full, l'attribut cn (Common Name) du certificat est testé par rapport au nom du serveur . Si l'attribut cn commence avec un astérisque(*), il sera traité comme un joker, et correspondra à tous les caractères sauf un point (.). Cela signifie que le certificat ne pourra pas être utilisé pour des sous-domaines complets. Si la connexion se fait en utilisant une adresse IP au lieu d'un nom d'hôte, l'adresse IP sera vérifiée (sans faire de recherche DNS).
Pour permettre la vérification du certificat du serveur, le certificat d'un ou plusieurs CA de confiance doit être placé dans le fichier ~/.postgresql/root.crt dans le répertoire personnel de l'utilisateur. Su Microsoft Windows, le fichier est nommé %APPDATA%\postgresql\root.crt.
Les entrées de la liste de révocation des certificats (CRL) sont aussi vérifiées si le fichier ~/.postgresql/root.crl existe (%APPDATA%\postgresql\root.crl sur Microsoft Windows).
L'emplacement du certificat racine et du CRL peuvent être changés avec les paramètres de connexion sslrootcert et sslcrl, ou les variables d'environnement PGSSLROOTCERT et PGSSLCRL.
Pour une compatibilité ascendantes avec les anciennes versions de PostgreSQL, si un certificat racine d'autorité existe, le comportement de sslmode=require sera identique à celui de verify-ca. Cela signifie que le certificat du serveur est validé par l'autorité de certificat. Il ne faut pas se baser sur ce comportement. Les applications qui ont besoin d'une validation du certificat doivent toujours utiliser verify-ca ou verify-full.
Si le serveur réclame un certificat de confiance du client, libpq enverra le certificat stocké dans le fichier ~/.postgresql/postgresql.crt du répertoire personnel de l'utilisateur. Le certificat doit être signé par une des autorités (CA) de confiance du serveur. Un fichier de clé privé correspondant ~/.postgresql/postgresql.key doit aussi être présent. Le fichier de clé privée ne doit pas permettre son accès pour le groupe ou pour le reste du monde ; cela se fait avec la commande chmod 0600 ~/.postgresql/postgresql.key. Sur Microsoft Windows, ces fichiers sont nommés %APPDATA%\postgresql\postgresql.crt et %APPDATA%\postgresql\postgresql.key, et il n'existe pas de vérification de droits car ce répertoire est présumé sécurisé. L'emplacement des fichiers certificat et clé peut être surchargé par les paramètres de connexion sslcert et sslkey, ou les variables d'environnement PGSSLCERT et PGSSLKEY.
Dans certains cas, le certificat du client peut être signé par une autorité de certificat « intermédiaire », plutôt que par un qui est directement accepté par le serveur. Pour utiliser un tel certificat, ajoutez le certificat de l'autorité signataire du fichier postgresql.crt, alors son certificat de l'autorité parente, et ainsi de suite jusqu'à arriver à l'autorité « racine » qui est accepté par le serveur. Le certificat racine doit être inclus dans chaque cas où postgresql.crt contient plus d'un certificat.
Notez que root.crt liste les autorités de certificat de haut-niveau qui sont considérées de confiance pour les certificats serveur signataires. En principe, il n'a pas besoin de lister l'autorité de certificats qui a signé le certificat du client, bien que dans la plupart des cas, l'autorité du certificat sera aussi de confiance pour les certificats serveur.
Les différentes valeurs du paramètre sslmode fournissent différents niveaux de protection. SSL peut fournir une protection contre trois types d'attaques différentes :
Si une troisième partie peut examiner le trafic réseau entre le client et le serveur, il peut lire à la fois les informations de connexion (ceci incluant le nom de l'utilisateur et son mot de passe) ainsi que les données qui y passent. SSL utilise le chiffrement pour empêcher cela.
Si une troisième partie peut modifier les données passant entre le client et le serveur, il peut prétendre être le serveur et, du coup, voir et modifier les données y compris si elles sont chiffrées. La troisième partie peut ensuite renvoyer les informations de connexion et les données au serveur d'origine, rendant à ce dernier impossible la détection de cette attaque. Les vecteurs communs pour parvenir à ce type d'attaque sont l'empoisonnement des DNS et la récupération des adresses IP où le client est dirigé vers un autre serveur que celui attendu. Il existe aussi plusieurs autres méthodes d'attaque pour accomplir ceci. SSL utilise la vérification des certificats pour empêcher ceci, en authentifiant le serveur auprès du client.
Si une troisième partie peut prétendre être un client autorisé, il peut tout simplement accéder aux données auquel il n'a pas droit. Typiquement, cela peut arrier avec une gestion incorrecte des mots de passe. SSL utilise les certificats clients pour empêcher ceci, en s'assurant que seuls les propriétaires de certificats valides peuvent accéder au serveur.
Pour qu'une connexion soit sûre, l'utilisation de SSL doit être configurée sur le client et sur le serveur avant que la connexion ne soit effective. Si c'est seulement configuré sur le serveur, le client pourrait envoyer des informations sensibles (comme les mots de passe) avant qu'il ne sache que le serveur réclame une sécurité importante. Dans libpq, les connexions sécurisées peuvent être garanties en configurant le paramètre sslmode à verify-full ou verify-ca, et en fournissant au système un certificat racine à vérifier. Ceci est analogue à l'utilisation des URL https pour la navigation web chiffrée.
Une fois que le serveur est authentifié, le client peut envoyer des données sensibles. Cela signifie que jusqu'à ce point, le client n'a pas besoin de savoir si les certificats seront utilisés pour l'authentification, rendant particulièrement sûr de ne spécifier que ceci dans la configuration du serveur.
Toutes les options SSL ont une surcharge du type chiffrement et échange de clés. Il y a donc une balance entre performance et sécurité. Tableau 31.1, « Description des modes SSL » illustre les risques que les différentes valeurs de sslmode cherchent à protéger, et ce que cela apporte en sécurité et fait perdre en performances.
Tableau 31.1. Description des modes SSL
sslmode | Protection contre l'écoute | Protection contre l'attaque MITM | Remarques |
---|---|---|---|
disable | Non | Non | Peu m'importe la sécurité, je ne veux pas la surcharge apportée par le chiffrement. |
allow | Peut-être | Non | Peu m'importe la sécurité, mais je vais accepter la surcharge du chiffrement si le serveur insiste là-dessus. |
prefer | Peut-être | Non | Peu m'importe la sécurité, mais j'accepte la surcharge du chiffrement si le serveur le supporte. |
require | Oui | Non | Je veux chiffrer mes données, et j'accepte la surcharge. Je fais confiance au résreau pour me connecter toujours au serveur que je veux. |
verify-ca | Oui | Depends on CA-policy | Je veux chiffrer mes données, et j'accepte la surcharge. Je veux aussi être sûr que je me connecte à un serveur en qui j'ai confiance. |
verify-full | Oui | Oui | Je veux chiffrer mes données, et j'accepte la surcharge. Je veux être sûr que je me connecte à un serveur en qui j'ai confiance et que c'est bien celui que j'indique. |
La différence entre verify-ca et verify-full dépend de la politique du CA racine. Si un CA publique est utilisé, verify-ca permet les connexions à un serveur que quelqu'un d'autre a pu enregistrer avec un CA accepté. Dans ce cas, verify-full devrait toujours être utilisé. Si un CA local est utilisé, voire même un certificat signé soi-même, utiliser verify-ca fournit souvent suffisamment de protection.
La valeur par défaut pour sslmode est prefer. Comme l'indique la table ci-dessus, cela n'a pas de sens d'un point de vue de la sécurité, et cela ne promet qu'une surcharge en terme de performance si possible. C'est uniquement fourni comme valeur par défaut pour la compatibilité ascendante, et n'est pas recommandé pour les déploiements de serveurs nécessitant de la sécurité.
Tableau 31.2, « Utilisation des fichiers SSL libpq/client » résume les fichiers liés à la configuration de SSL sur le client.
Tableau 31.2. Utilisation des fichiers SSL libpq/client
Fichier | Contenu | Effet |
---|---|---|
~/.postgresql/postgresql.crt | certificat client | requis par le serveur |
~/.postgresql/postgresql.key | clé privée du client | prouve le certificat client envoyé par l'utilisateur ; n'indique pas que le propriétaire du certificat est de confiance |
~/.postgresql/root.crt | autorité de confiance du certificat | vérifie que le certificat du serveur est signé par une autorité de confiance |
~/.postgresql/root.crl | certificats révoqués par les autorités | le certificat du serveur ne doit pas être sur cette liste |
Si votre application initialise les bibliothèques libssl et/ou libcrypto et que libpq est construit avec le support de SSL, vous devez appeler la fonction PQinitOpenSSL pour indiquer à libpq que les bibliothèques libssl et/ou libcrypto ont été initialisées par votre application, de façon à ce que libpq n'initialise pas elle-aussi ces bibliothèques. Voir http://h71000.www7.hp.com/doc/83final/BA554_90007/ch04.html pour plus de détails sur l'API SSL.
Permet aux applications de sélectionner les bibliothèques de sécurité à initialiser.
void PQinitOpenSSL(int do_ssl, int do_crypto);
Quand do_ssl est différent de zéro, libpq initialisera la bibliothèque OpenSSL avant d'ouvrir une connexion à la base de données. Quand do_crypto est différent de zéro, la bibliothèque libcrypto sera initialisée. Par défaut (si PQinitOpenSSL n'est pas appelé), les deux bibliothèques sont initialisées. Quand le support de SSL n'est pas intégré, cette fonction est présente mais ne fait rien.
Si votre application utilise et initialise soit OpenSSL soit libcrypto, vous devez appeler cette fonction avec des zéros pour les paramètres appropriés avant d'ouvrir la première connexion à la base de données. De plus, assurez-vous que vous avez fait cette initialisation avant d'ouvrir une connexion à la base de données.
Permet aux applications de sélectionner les bibliothèques de sécurité à initialiser.
void PQinitSSL(int do_ssl);
Cette fonction est équivalent à PQinitOpenSSL(do_ssl, do_ssl). C'est suffisant pour les applications qui initialisent à la fois OpenSSL etlibcrypto ou aucune des deux.
PQinitSSL est présente depuis PostgreSQL™ 8.0, alors que PQinitOpenSSL a été ajoutée dans PostgreSQL™ 8.4, donc PQinitSSL peut être préférée pour les applications qui ont besoin de fonctionner avec les anciennes versions de libpq.