Exiger SSL, garder SELinux activé, surveiller les journaux, et utiliser une version actuelle de PostgreSQL .
Côté serveur
Exiger SSL
En postgresql.conf
set ssl=on
et assurez-vous que votre fichier de clé et votre fichier de certificat sont installés de manière appropriée (voir la documentation et les commentaires dans le fichier postgresql.conf
).
Il se peut que vous deviez acheter un certificat auprès d'une autorité de certification si vous voulez qu'il soit reconnu par les clients sans configuration spéciale sur le client.
En pg_hba.conf
utiliser quelque chose comme :
hostssl theuser thedatabase 1.2.3.4/32 md5
... éventuellement avec "tous" pour l'utilisateur et/ou la base de données, et éventuellement avec un filtre d'adresse IP source plus large.
Limiter le nombre d'utilisateurs qui peuvent se connecter, refuser la connexion du superutilisateur à distance.
N'autorisez pas "tout" pour les utilisateurs si possible ; vous ne voulez pas autoriser les connexions de superutilisateurs à distance si vous pouvez éviter d'en avoir besoin.
Limiter les droits des utilisateurs
Restreindre les droits des utilisateurs qui peuvent se connecter. Ne leur donnez pas CREATEDB
o CREATEUSER
droits.
REVOKE
le site CONNECT
à partir de PUBLIC
sur toutes vos bases de données, puis le redonner aux seuls utilisateurs/rôles qui doivent pouvoir accéder à cette base de données. (Regroupez les utilisateurs en rôles et accordez les droits aux rôles, plutôt que directement aux utilisateurs individuels).
Assurez-vous que les utilisateurs ayant un accès distant ne peuvent se connecter qu'aux bases de données dont ils ont besoin et qu'ils n'ont des droits que sur les schémas, les tables et les colonnes dont ils ont réellement besoin. C'est également une bonne pratique pour les utilisateurs locaux, c'est une sécurité raisonnable.
Configuration du client
Dans PgJDBC, passez le paramètre ssl=true
:
Pour demander au pilote JDBC d'essayer d'établir une connexion SSL, vous devez ajouter le paramètre ssl=true à l'URL de connexion.
... et installez le certificat du serveur dans le magasin de confiance du client, ou utilisez un certificat de serveur approuvé par l'une des autorités de certification du magasin de confiance intégré de Java si vous ne voulez pas que l'utilisateur ait à installer le certificat.
Action en cours
Maintenant s'assurer que vous maintenez PostgreSQL à jour . PostgreSQL n'a eu que quelques failles de sécurité préauth, mais c'est plus que zéro, alors restez à jour. Vous devriez de toute façon, les corrections de bogues sont des choses agréables à avoir.
Ajoutez un pare-feu en amont s'il y a de grands blocs de réseaux/régions dont vous savez que vous n'aurez jamais besoin d'y accéder.
Consigner les connexions et les déconnexions (voir postgresql.conf
). Enregistrez les requêtes si possible. Exécuter un système de détection d'intrusion ou fail2ban ou similaire en amont si possible. Pour fail2ban avec postgres, il existe un mode d'emploi pratique. ici
Surveillez les fichiers journaux.
Bonus paranoïa
Des étapes supplémentaires auxquelles il faut penser...
Exiger les certificats des clients
Si vous le souhaitez, vous pouvez également utiliser pg_hba.conf
pour exiger que le client présente un certificat client X.509 reconnu par le serveur. Il n'est pas nécessaire d'utiliser la même autorité de certification que le certificat du serveur, vous pouvez le faire avec une autorité de certification openssl maison. Un utilisateur JDBC doit importer le certificat du client dans son Keystore Java avec keytool
et éventuellement configurer certaines propriétés du système JSSE afin de diriger Java vers leur keystore, de sorte que ce n'est pas totalement transparent.
Mettre l'instance en quarantaine
Si vous voulez être vraiment paranoïaque, exécutez l'instance pour le client dans un conteneur / VM séparé, ou au moins sous un compte utilisateur différent, avec uniquement la ou les bases de données dont il a besoin.
De cette façon, s'ils compromettent l'instance PostgreSQL, ils n'iront pas plus loin.
Utiliser SELinux
Je ne devrais pas avoir à dire ça, mais...
Exécuter une machine avec un support SELinux comme RHEL 6 ou 7, et ne pas désactiver SELinux ou le mettre en mode permissif . Gardez-le en mode d'application.
Utiliser un port autre que celui par défaut
Sécurité par seulement l'obscurité est une stupidité. Une sécurité qui utilise un peu d'obscurité une fois que vous avez fait le nécessaire pour être raisonnable ne fera probablement pas de mal.
Exécutez Pg sur un port autre que celui par défaut pour rendre la vie un peu plus difficile aux attaquants automatiques.
Mettez un proxy devant
Vous pouvez également exécuter PgBouncer ou PgPool-II devant PostgreSQL, en agissant comme un pool de connexion et un proxy. De cette façon, vous pouvez laisser le proxy gérer SSL, et non le véritable hôte de la base de données. Le proxy peut être sur une VM ou une machine séparée.
L'utilisation de proxies de mise en commun des connexions est généralement une bonne idée avec PostgreSQL de toute façon, à moins que l'application cliente ait déjà un pool intégré. La plupart des serveurs d'application Java, Rails, etc. ont un pool intégré. Même dans ce cas, un proxy de mise en commun côté serveur est au pire inoffensif.
4 votes
Les tunnels SSH ne sont pas une option ? Cet article pratique utilise en fait des tunnels PostgreSQL à titre d'exemple. Vous pourriez fournir au client un client SSH préconfiguré pour faciliter la connexion.
0 votes
La base de données sera utilisée par une application Java développée en interne sur une centaine de machines de l'entreprise. Notre seul moyen de les configurer est de donner une url de connexion jdbc à leur administration locale, tout autre moyen est très, très problématique.
0 votes
@milkman que fait l'application ? peut-être pourrait-elle interroger un serveur RESTful à la place ? Évidemment, passer du SQL au REST n'apporte rien, mais en supposant qu'il s'agisse d'un CRUD
0 votes
@tedder42 Il manipule la base de données du CMS de l'utilisateur, qui est également hébergé chez nous. Nous n'avons pas la permission de changer sa source.