sepgsql
est un module chargeable ajoutant le
support des contrôles d'accès par label basé sur la politique de
sécurité de SELinux.
L'implémentation actuelle a des limitations importantes et ne force pas le contrôle d'accès pour toutes les actions. Voir Section F.37.7.
Ce module s'intègre avec SELinux pour fournir une couche de vérification de sécurité supplémentaire qui va au-delà de ce qui est déjà fournit par PostgreSQL. De la perspective de SELinux, ce module permet à PostgreSQL de fonctionner comme un gestionnaire d'objet en espace utilisateur. Chaque accès à une table ou à une fonction initié par une requête DML sera vérifié par rapport à la politique de sécurité du système. Cette vérification est en plus des vérifications de droits SQL habituels effectuées par PostgreSQL.
Les décisions de contrôle d'accès de SELinux
sont faites en utilisant les labels de sécurité qui sont représentés
par des chaînes comme
system_u:object_r:sepgsql_table_t:s0
. Chaque
décision de contrôle d'accès implique deux labels : celui de
l'utilisateur tentant de réaliser l'action et celui de l'objet sur
lequel l'action est réalisée. Comme ces labels peuvent être appliqués
sur tout type d'objet, les décisions de contrôle d'accès pour les
objets stockés dans la base peuvent être (et avec ce module, sont)
sujets au même critère général utilisé pour les objets de tout type
(par exemple les fichiers). Ce concept a pour but de permettre la mise
en place d'une politique centralisée pour protéger l'information
quelque soit la façon dont l'information est stockée.
L'instruction SECURITY
LABEL
permet d'affecter
un label de sécurité à un objet de la base de données.
sepgsql
peut seulement être utilisé sur
Linux 2.6.28 ou ultérieur, avec
SELinux activé. Il n'est pas disponible
sur les autres plateformes. Vous aurez aussi besoin
de libselinux ou ultérieur et de
selinux-policy 2.1.10 ou ultérieur
(même si certaines distributions peuvent proposer les règles nécessaires
dans des versions antérieures de politique).
La commande sestatus
vous permet de vérifier le
statut de SELinux. Voici un affichage
standard :
$ sestatus SELinux status: enabled SELinuxfs mount: /selinux Current mode: enforcing Mode from config file: enforcing Policy version: 24 Policy from config file: targeted
Si SELinux est désactivé ou non installé, vous devez tout d'abord configurer ce produit avant d'utiliser ce module.
Pour construire ce module, ajoutez l'option --with-selinux
dans votre commande configure
lors de la compilation
de PostgreSQL. Assurez-vous que le RPM libselinux-devel
est installé au moment de la construction.
Pour utiliser ce module, vous devez ajouter sepgsql
dans le paramètre shared_preload_libraries du
fichier postgresql.conf
. Le module ne
fonctionnera pas correctement s'il est chargé d'une autre façon. Une
fois que le module est chargé, vous devez exécuter
sepgsql.sql
dans chaque base de données. Cela
installera les fonctions nécessaires à la gestion des labels de
sécurité et affectera des labels initiaux de sécurité.
Voici un exemple montrant comment initialiser un répertoire de données
avec les fonctions sepgsql
et les labels de
sécurité installés. Ajustez les chemins de façon approprié pour que
cela corresponde à votre installation :
$ export PGDATA=/path/to/data/directory $ initdb $ vi $PGDATA/postgresql.conf modifiez #shared_preload_libraries = '' # (change requires restart) en shared_preload_libraries = 'sepgsql' # (change requires restart) $ for DBNAME in template0 template1 postgres; do postgres --single -F -c exit_on_error=true $DBNAME \ </usr/local/pgsql/share/contrib/sepgsql.sql >/dev/null done
Notez que vous pourriez voir les notifications suivantes, suivant la combinaison de versions particulières de libselinux et de selinux-policy.
/etc/selinux/targeted/contexts/sepgsql_contexts: line 33 has invalid object type db_blobs /etc/selinux/targeted/contexts/sepgsql_contexts: line 36 has invalid object type db_language /etc/selinux/targeted/contexts/sepgsql_contexts: line 37 has invalid object type db_language /etc/selinux/targeted/contexts/sepgsql_contexts: line 38 has invalid object type db_language /etc/selinux/targeted/contexts/sepgsql_contexts: line 39 has invalid object type db_language /etc/selinux/targeted/contexts/sepgsql_contexts: line 40 has invalid object type db_language
Ces messages ne sont graves et peuvent être ignorés sans conséquence.
Si le processus d'installation se termine sans erreur, vous pouvez commencer à lancer le serveur normalement.
Dû à la nature de SELinux, exécuter les
tests de régression pour sepgsql
nécessite
quelques étapes de configuration supplémentaires, certaines se faisant en
tant qu'utilisateur root. Les tests de régression ne seront pas exécutés
par une commande make check
ou make
installcheck
ordinaire ; vous devez faire la configuration
puis appeler le script de test manuellement. Les tests s'exécuteront dans
le répertoire contrib/sepgsql
du répertoire des
sources de PostgreSQL, préalablement configuré. Bien que cela nécessite
un arbre de construction, les tests sont conçus pour être exécutés par un
serveur déjà installé, donc comparable à make installcheck
,
et non pas make check
.
Tout d'abord, configurez sepgsql
dans une base de
données fonctionnelle d'après les instructions comprises dans Section F.37.2. Notez que l'utilisateur du système
d'exploitation doit être capable de se connecter à la base de données en
tant que super-utilisateur sans authentification par mot de passe.
Ensuite, construisez et installez le paquet de politique pour les
tests de régression. Le fichier sepgsql-regtest
est un paquet de politique à but spécial. Il fournit un ensemble de
règles à autoriser pendant les tests de régression. Il doit être
construit à partir du fichier source de politique
sepgsql-regtest.te
, ce qui se fait en utilisant
make
avec un fichier Makefile fourni par SELinux.
Vous aurez besoin de localiser le Makefile approprié sur votre
système ; le chemin affiché ci-dessous est seulement un exemple.
(Ce fichier Makefile est habituellement fourni avec le RPM
selinux-policy-devel
ou
selinux-policy
.)
Une fois construit, installez ce paquet de politique en utilisant la
commande
semodule
, qui charge les paquets de politique fournis
dans le noyau. Si ce paquet est correctement
installé,
doit lister
semodule
-lsepgsql-regtest
comme un paquet de politique disponible :
$ cd .../contrib/sepgsql $ make -f /usr/share/selinux/devel/Makefile $ sudo semodule -u sepgsql-regtest.pp $ sudo semodule -l | grep sepgsql sepgsql-regtest 1.07
Pour des raisons de sécurité, les règles de sepgsql-regtest
ne sont pas activés par défaut. Le paramètre
sepgsql_regression_test_mode
active les
règles pour le lancement des tests de régression. Il peut être
activé en utilisant la commande setsebool
:
$ sudo setsebool sepgsql_regression_test_mode on $ getsebool sepgsql_regression_test_mode
Ensuite, vérifiez que votre shell est exécuté dans le domaine
unconfined_t
:
$ ./test_sepgsql
Ce script tentera de vérifier que vous avez fait correctement toutes
les étapes de configuration, puis il lancera les tests de régression
du module sepgsql
.
Une fois les tests terminés, il est recommandé de désactiver le
paramètre sepgsql_regression_test_mode
:
$ sudo setsebool sepgsql_regression_test_mode off
Vous pouvez préférer supprimer complètement la politique
sepgsql-regtest
:
$ sudo semodule -r sepgsql-regtest
sepgsql.permissive
(boolean
)
Ce paramètre active sepgsql pour
qu'il fonctionne en mode permissif, quelque soit la configuration
du système. La valeur par défaut est off.
Ce paramètre es configurable dans le fichier
postgresql.conf
et sur la ligne de commande.
Quand ce paramètre est activé, sepgsql fonctionne en mode permissif, même si SELinux fonctionne en mode forcé. Ce paramètre est utile principalement pour des tests.
sepgsql.debug_audit
(boolean
)Ce paramètre active l'affichage de messages d'audit quelque soit la configuration de la politique. La valeur par défaut est off, autrement dit les messages seront affichés suivant la configuration du système.
La politique de sécurité de SELinux a aussi des règles pour contrôler la trace des accès. Par défaut, les violations d'accès sont tracées, contrairement aux accès autorisés.
Ce paramètre force l'activation de toutes les traces, quelque soit la politique du système.
Le modèle de sécurité SELinux décrit toutes
les règles de contrôle d'accès comme des relations entre une entité
sujet (habituellement le client d'une base) et une entité objet
(tel que l'objet base de données). Les
deux sont identifiés par un label de sécurité. Si un accès à un
objet sans label est tenté, l'objet est traité comme si le label
unlabeled_t
lui est affecté.
Actuellement, sepgsql
autorise l'affectation
de label de sécurité aux schémas, tables, colonnes, séquences, vues
et fonctions. Quand sepgsql
est en cours
d'utilisation, des labels de sécurité sont automatiquement affectés
aux objets de la base au moment de leur création. Ce label est appelé
un label de sécurité par défaut et est configuré par la politique de
sécurité du système, qui prend en entrée le label du créateur, le
label affecté à l'objet parent du nouvel objet et en option le nom de
l'objet construit.
Un nouvel objet base de données hérite en gros du label de sécurité de l'objet parent, sauf quand la politique de sécurité a des règles spéciales, connues sous le nom de règles de transition, auquel cas un label différent est affecté. Pour les schémas, l'objet parent est la base de données ; pour les tables, séquences, vues et fonctions, il s'agit du schéma ; pour les colonnes, il s'agit de la table.
Pour les tables, db_table:select
, db_table:insert
,
db_table:update
ou db_table:delete
sont vérifiés pour toutes les tables cibles référencées, suivant l'ordre
de l'instruction. De plus, db_table:select
est
aussi vérifié pour toutes les tables qui contiennent des colonnes
référencées dans la clause WHERE
ou
RETURNING
, comme source de données d'un
UPDATE
, et ainsi de suite.
Les droits au niveau colonne seront aussi vérifiés pour chaque colonne référencée.
column_db:select
est vérifié sur les colonnes lues en utilisant
SELECT
, mais aussi celles référencées dans d'autres instructions
DML ; column_db:update
ou column_db:insert
sear aussi vérifié pour les colonnes modifiées par UPDATE
ou
INSERT
.
Bien sûr, il vérifie aussi db_column:update
ou
db_column:insert
sur la colonne en cours de
modification par UPDATE
ou INSERT
.
Par exemple :
UPDATE t1 SET x = 2, y = func1(y) WHERE z = 100;
Ici, column_db:update
sera vérifié pour
t1.x
car elle est mise à jour,
column_db:{select update}
sera vérifié pour
t1.y
car elle est à la fois mise à jour et référencée, et
column_db:select
sera vérifié pour t1.z
car elle est référencée.
db_table:{select update}
vérifiera aussi la table.
Pour les séquences, db_sequence:get_value
est
vérifié quand nous référençons un objet séquence en utilisant
SELECT
; néanmoins, notez que nous ne vérifions
pas les droits d'exécution sur les fonctions correspondantes, par
exemple lastval()
.
Pour les vues, db_view:expand
devrait être
vérifié, et ensuite tous les autres droits des objets dus à
l'aplatissement de la vue, individuellement.
Pour les fonctions, db_procedure:{execute}
sera vérifié
quand un utilisateur essaie d'exécuter une fonction dans une requête ou en
utilisant l'appel « fast-path ». Si cette fonction est déclarée comme étant
de confiance, il vérifie aussi le droit
db_procedure:{entrypoint}
pour s'assurer qu'il peut
s'exécuter comme un point d'entrée d'une procédure de confiance.
Pour accéder à tout objet d'un schéma, le droit
db_schema:search
est requis sur le schéma contenant
l'objet. Quand un objet est référencé sans le nom du schéma, les schémas
qui n'ont pas ce droit ne seront pas recherchés (exactement le même
comportement que l'absence du droit USAGE
sur le schéma).
Si une qualification explicite du schéma est présent, une erreur surviendra
si l'utilisateur n'a pas le droit requis sur le schéma nommé.
Le client doit être autorisé à accéder à toutes les tables et colonnes référencées, même si elles proviennent de vues qui ont été aplaties, pour pouvoir appliquer des règles de contrôles d'accès cohérentes indépendamment de la manière dont le contenu des tables est référencé.
Le système des droits de la base, par défaut, autorise les
super-utilisateurs de la base à modifier les catalogues systèmes en
utilisant des commandes DML, et de référencer ou modifier les tables
TOAST. Ces opérations sont interdites quand
sepgsql
est activé.
SELinux définit plusieurs droits pour contrôler les opérations standards pour chaque type d'objet : création, modification, suppression et changement du label de sécurité. De plus, certains types d'objet ont des droits spéciaux pour contrôler leur opérations caractéristiques : ajout ou suppression d'entrées dans un schéma particulier.
Créer un objet de bases de données nécessite le droit create
.
SELinux acceptera ou refusera ce droit en se
basant sur le label de sécurité du client et sur le label de sécurité proposé
pour le nouvel objet. Dans certains cas, des droits supplémentaires sont
demandés :
CREATE DATABASE
requiert en plus le droit
getattr
pour la base de données source ou modèle.
Créer un schéma requiert en plus le droit add_name
sur
le schéma parent.
Créer une table requiert en plus le droit de créer chaque colonne de la table, tout comme si chaque colonne de la table était un objet séparé de haut-niveau.
Créer une fonction marquée LEAKPROOF
requiert en plus
le droit install
. (Ce droit est aussi vérifié quand
LEAKPROOF
est configuré pour une fonction existante.)
Quand la commande DROP
est exécutée,
drop
sera vérifié sur l'objet qui doit être supprimé.
Les droits seront aussi vérifiés pour les objets supprimés indirectement
via CASCADE
. La suppression des objets contenus dans un
schéma particulier (tables, vues, séquences et fonctions) nécessite
habituellement remove_name
sur le schéma.
Quand la commande ALTER
est exécutée,
setattr
sera vérifié sur l'objet en cours de modification
pour chaque type d'objet, sauf pour les objets sous-jacents comme les index
ou les triggers d'une table. Pour ces derniers, les droits sont vérifiés sur
l'objet parent. Dans certains cas, des droits supplémentaires sont
réclamés :
Déplacer un objet vers un nouveau schéma réclame en plus le droit
remove_name
sur l'ancien schéma et le droit
add_name
sur le nouveau schéma.
Configurer l'attribut LEAKPROOF
sur une fonction
requiert le droit install
.
Utiliser SECURITY
LABEL
sur un objet requiert en
plus le droit relabelfrom
pour l'objet en conjonction
avec son ancien label et le droit relabelto
pour l'objet
en conjonction avec son nouveau label. (Dans les cas où plusieurs
fournisseurs de label sont installés et que l'utilisateur essaie de
configurer un label de sécurité mais qui est géré par
SELinux, seul setattr
peut
être vérifié ici. Cela ne peut pas se faire actuellement à cause des
restrictions de l'implémentation.)
Les procédures de confiance sont similaires aux fonctions dont la sécurité est définie à la création ou aux commandes set-uid. SELinux propose une fonctionnalité qui permet d'autoriser un code de confiance à s'exécuter en utilisant un label de sécurité différent de celui du client, généralement pour donner un accès hautement contrôlé à des données sensibles (par exemple, des lignes peuvent être omises ou la précision des valeurs stockées peut être réduite). Que la fonction agisse ou pas comme une procédure de confiance est contrôlé par son label de sécurité et la politique de sécurité du système d'exploitation. Par exemple :
postgres=# CREATE TABLE customer ( cid int primary key, cname text, credit text ); CREATE TABLE postgres=# SECURITY LABEL ON COLUMN customer.credit IS 'system_u:object_r:sepgsql_secret_table_t:s0'; SECURITY LABEL postgres=# CREATE FUNCTION show_credit(int) RETURNS text AS 'SELECT regexp_replace(credit, ''-[0-9]+$'', ''-xxxx'', ''g'') FROM customer WHERE cid = $1' LANGUAGE sql; CREATE FUNCTION postgres=# SECURITY LABEL ON FUNCTION show_credit(int) IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0'; SECURITY LABEL
Les opérations ci-dessus doivent être réalisées par un utilisateur administrateur.
postgres=# SELECT * FROM customer; ERROR: SELinux: security policy violation postgres=# SELECT cid, cname, show_credit(cid) FROM customer; cid | cname | show_credit -----+--------+--------------------- 1 | taro | 1111-2222-3333-xxxx 2 | hanako | 5555-6666-7777-xxxx (2 rows)
Dans ce cas, un utilisateur standard ne peut pas faire référence à
customer.credit
directement mais une procédure de
confiance comme show_credit
lui permet d'afficher
le numéro de carte de crédit des clients, avec quelques chiffres
masqués.
Il est possible d'utiliser la fonctionnalité de transition de domaine
dynamique de SELinux pour basculer le label de sécurité du processus
client, le domaine client, vers un nouveau contexte, s'il s'avère que
c'est autorisé par la politique de sécurité. Le domaine client a besoin
du droit setcurrent
ainsi que du droit
dyntransition
de l'ancien domaine vers le nouveau
domaine.
Les transitions de domaine dynamique doivent être considérées avec
attention car elles permettent aux utilisateurs de basculer leur label, et
du coup leur droits, quand ils le souhaitent, plutôt que (dans le cas d'une
procédure de confiance) lorsque c'est demandé par le système. Du coup, le
droit dyntransition
est seulement considéré sûr quand il
est utilisé pour basculer vers un domaine avec un plus petit ensemble de
droits que le domaine original. Par exemple :
regression=# select sepgsql_getcon(); sepgsql_getcon ------------------------------------------------------- unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 (1 row) regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c4'); sepgsql_setcon ---------------- t (1 row) regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c1023'); ERROR: SELinux: security policy violation
Dans l'exemple ci-dessus, nous sommes autorisés à basculer du gros intervalle MCS
c1.c1023
vers l'intervalle c1.c4
beaucoup plus
petit. Par contre, la bascule inverse est interdite.
Une combinaison de transition de domaine dynamique et de procédure de
confiance permet un cas d'utilisation intéressant qui correspond au
cycle de vie typique d'un processus pour un logiciel de pooling de
connexions. Même si votre pooler de connexions n'est pas autorisé à
exécuter la plupart des commandes SQL, vous pouvez l'autoriser à
basculer le label de sécurité du client en utilisant la fonction
sepgsql_setcon()
à l'intérieur d'une procédure de
confiance. Après cela, cette session aura les droits de l'utilisateur
cible plutôt que ceux du pooler de connexions. Le pooler de connexions
peut ensuite annuler le changement du label de sécurité en utilisant
de nouveau sepgsql_setcon()
avec l'argument
NULL
, encore une fois en l'appelant à partir d'une
procédure de confiance avec les droits appropriés. Le point ici est que
seule la procédure de confiance a réellement le droit de modifier le
label de sécurité en cours et ne le fait que si autorisé. Bien sûr,
pour un traitement sécurisé, le stockage des autorisations (table,
définition de procédure, ou autres) doit être protégé des accès non
autorisés.
Nous rejetons la commande LOAD
car tout module chargé pourrait facilement court-circuiter la politique de
sécurité.
Tableau F.30 affiche la liste des fonctions disponibles.
Tableau F.30. Fonctions Sepgsql
Fonction Description |
---|
Renvoie le domaine client, le label de sécurité actuel du client. |
Bascule le domaine client de la session actuelle sur un autre domaine,
si cela est autorisé par la politique de sécurité. Cette fonction
accepte aussi |
Traduit l'intervalle MLS/MCS donné en un format brut si le démon mcstrans est en cours d'exécution. |
Traduit l'intervalle MCS/MCS brut donné en son format qualifié si le démon mcstrans est en cours d'exécution. |
Configure les labels de sécurité initiaux pour tous les objets à l'intérieur de la base de données actuelle. L'argument peut être NULL ou le nom d'un specfile à utiliser comme alternative du fichier système par défaut. |
Dû aux restrictions d'implémentations, certaines opérations DDL ne vérifient pas les droits.
Dû aux restrictions d'implémentations, les droits DCL ne vérifient pas les droits.
PostgreSQL propose le contrôle d'accès au
niveau ligne. Cependant, sepgsql
ne le supporte
pas.
sepgsql
n'essaie pas de cacher
l'existence d'un objet particulier, même si l'utilisateur n'est
pas autorisé à y accéder. Par exemple, nous pouvons inférer
l'existence d'un objet invisible suite à un conflit de clé primaire,
à des violations de clés étrangèes et ainsi de suite, même si nous
ne pouvons pas accéder au contenu de ces objets. L'existence d'une
table secrète ne peut pas être caché. Nous ne faisons que
verrouiller l'accès à son contenu.
Cette page wiki fournit un bref aperçu, le concept de la sécurité, l'architecture, l'administration et les fonctionnalités futures.
Ce document fournit une connaissance large pour administrer SELinux sur vos systèmes. Il cible principalement les systèmes d'exploitation Red Hat mais n'y est pas limité.
Ce document répond aux questions fréquemment posées sur SELinux. Il cible principalement Fedora mais n'y est pas limité.
KaiGai Kohei <kaigai@ak.jp.nec.com>