Slpsql: различия между версиями

Материал из ALT Linux Wiki
Нет описания правки
м (источник неправильного написания названия дистрибутива, в т.ч. и в википедии)
 
(не показано 8 промежуточных версий 3 участников)
Строка 1: Строка 1:
== СУБД PostgresSQL в ALTLinux с мандатным уровнем доступа ==
== СУБД PostgresSQL в ALT Linux с мандатным уровнем доступа ==


== Дополнительная информация ==
== Дополнительная информация ==
Строка 8: Строка 8:
* Методы над каждым объектом(классом):
* Методы над каждым объектом(классом):
http://wiki.postgresql.org/wiki/SEPostgreSQL_References
http://wiki.postgresql.org/wiki/SEPostgreSQL_References
* Модуль SeLinux для PostgreSQL:
http://www.postgresql.org/docs/9.3/static/sepgsql.html
* Понятия DML и  DLL
*: [[enwp:Data_manipulation_language]]
*: [[enwp:Data_definition_language]]
* Страница руководства
$ man sepgsql_contexts


== Введение ==
== Введение ==
Строка 13: Строка 23:
Данный документ предполагает что администратор имеет необходимые знания для администрировании СУБД PostgreSQL.
Данный документ предполагает что администратор имеет необходимые знания для администрировании СУБД PostgreSQL.


Политика SeLinux была написана для PostgreSQL 9.3
 
 
Основное отличие от RefPolicy:
Основное отличие от RefPolicy:
* убрано разделение объектов СУБД по различным доменам SeLinux для пользователей и администраторов.
* убрано разделение объектов СУБД по различным доменам SeLinux для пользователей и администраторов.
* логически SeLinux менеджер различает 2 домена SeLinux подключаемых пользователей: обычные пользователи, офицер безопасности.
* логически, pgsql различает два домена подключаемых пользователей: обычные пользователи, офицер безопасности
 
Стандартная система разграничения доступа PostgresSQL на основе назначений ролей и прав сохраняется.
 
Мандатная система доступа, накладываемая SeLinux, является дополнительной, и работает в согласовании с глобальными метками пользователей в ОС.
Ключевые моменты:
Таким образом, даже при авторизации в СУБД от имени владельца database в кластере PostgreSQL, будет сохранен его системный мандатный уровень доступа,
# Политика SeLinux написана для PostgreSQL 9.3
который будет принимать участие в решении вопросов доступа. Т.е. возможен такой сценарий:
# Стандартная система разграничения прав доступа PostgresSQL на основе ролей и прав сохраняется.
* В ОС ALTLinux авторизуется пользователь test.
# Мандатная система доступа, накладываемая SeLinux, является дополнительной, и работает в согласовании с глобальными мандатными метками SeLinux пользователей ОС.
* ОС назначает мандатные права пользователю test в рамках открытой сессии.
# Предполагается что клиент и сервер находятся в рамках одного узла.
* Пользователь сменяет свой системный идентификатор пользователя на root: su -
# При необходимости, можно расширить для работы в сети, где клиент и сервер находятся на различных узлах в ОС ALT Linux. Данная схема не тестировалась.
* Манданые права пользователя остаются прежние.
# Для поддержки SeLinux сервер PostgreSQL должен быть изъят из chroot, или в chroot необходимо будет пробрасывать файловую систему в chroot.
* Авторизуется в СУБД как владелец некой БД.
 
В итоге получается, что даже при таком раскладе он ограничен в своих действиях, так как первоначальный мандатный уровень назначенный пользователю test при открытии сессии сохранился.
 
Концепция работы:
# Контекст безопасности клиента проверяется при соединении с сокетом сервера PostgreSQL.
# Ограничение действий в СУБД осуществляет сам сервер PostgreSQL согласно политике SeLinux.
# Ключевой момент состоит в том, что не ядро ОС пресекает запрещенные действия а сервер СУБД.
# В СУБД PostgreSQL встроен менеджер. Данный менеджер работает в пространстве пользователя ОС.
# Менеджер обращается к ядру с использованием libselinux для проверки действий.
# Аналогичным образом работает система Xorg: http://taiga.selinuxproject.org/~rhaines/diagrams/26-x-windows.png


Предполагается что клиент и сервер находятся в рамках одного узла.
При необходимости, можно расширить для работы в сети, где клиент и сервер находятся на различных узлах в ОС ALTLinux.
Но данная схема не была протестирована. Контекст безопасности клиента проверяется при соединении с сокетом сервера PostgreSQL.


Замечание: для поддержки SeLinux сервер PostgreSQL должен быть изъят из chroot, или в chroot необходимо будет пробрасывать файловую систему в chroot.


Ограничение действий в СУБД осуществляет сам сервер PostgreSQL согласно политике SeLinux.
При авторизации в СУБД от имени владельца database в кластере PostgreSQL, будет сохранен его системный мандатный уровень доступа, который будет принимать участие в решении вопросов доступа.
Ключевой момент состоит в том, что не ядро ОС пресекает запрещенные действия а сервер СУБД.
Т.е. возможен такой сценарий:
В СУБД PostgreSQL встроен менеджер. Данный менеджер работает в пространстве пользователя ОС.
# В ОС авторизуется пользователь test.
Менеджер обращается к ядру с использованием libselinux для проверки действий.
# ОС назначает мандатные права пользователю test в рамках открытой сессии.
Аналогичным образом работает система Xorg: http://taiga.selinuxproject.org/~rhaines/diagrams/26-x-windows.png
# Пользователь меняет свой системный идентификатор пользователя на root: su -
# Манданые права пользователя остаются прежние.
# Авторизуется в СУБД как владелец некой БД.
В итоге получается: даже при таком раскладе он ограничен в своих действиях, так как первоначальный мандатный уровень назначенный пользователю test при открытии сессии сохранился.


Дополнительную информацию можно получить из следующих источников:
# man sepgsql_contexts




Строка 49: Строка 64:
* Авторизоваться в ОС от имени root.
* Авторизоваться в ОС от имени root.


* Убедится что ОС назначила root права офицера безопасности:
# runcon
officer_u:officer_r:officer_t:s0-s15:c0.c31


* Убедитесь что политика SeLinux содержит модуль psql, в котором присутствуют необходимые правила.
* Убедится что ОС назначила root мандатные права офицера безопасности:
# semodule -l | grep sql
# runcon
psql 1.0.4
officer_u:officer_r:officer_t:s0-s15:c0.c31
 


* Проверить что установлен сервер СУБД PostgreSQL версии 9.3
* Убедитесь что политика SeLinux содержит модуль psql, в котором присутствует необходимый набор правил:
# rpm -q postgresql9.3-server
# semodule -l | grep sql
postgresql9.3-server-9.3.4-alt2
psql 1.0.4
а также установлен пакет postgresql9.3-contrib




* Если сервер postgresql запущен его необходимо временно выключить.
* Проверить что установлен сервер СУБД PostgreSQL версии 9.3, а также установлен пакет postgresql9.3-contrib
# service postgresql status
# rpm -q postgresql9.3-server postgresql9.3-contrib
postgres is running
postgresql9.3-server-9.3.4-alt0.M70P.1
# service postgresql stop
postgresql9.3-contrib-9.3.4-alt0.M70P.1
postgres is running


* В случае если кластер СУБД не инициализирован его необходимо инициализировать:
# service postgresql initdb
Кластер будет создан по адресу: /var/lib/pgsql/data


* Далее в конфигурационный файл кластера необходимо внести дерективу, которая будет указывать использовать SeLinux менеджер.
* Если сервер postgresql запущен, тогда его необходимо временно выключить:
Для этого отредактируйте файл /var/lib/pgsql/data/postgresql.conf, и установите:
# service postgresql status
shared_preload_libraries = 'sepgsql'
postgres is running
sepgsql.permissive = off
# service postgresql stop
sepgsql.debug_audit = on
postgres is running


Внимание: категорически не рекомендуется отключать опцию: sepgsql.permissive = off, так как срабатывание denied происходит только один раз.
Для последующих запросов всегда будет срабатывать «allow». Таким образом эта опция становится бесполезной для отладки.


Опция sepgsql.debug_audit = on указывает протоколировать результат проверки на разрешенность для каждого действия.
* В случае если кластер СУБД не инициализирован его необходимо инициализировать:
Если не указано другое, логи сохраняются в /var/lib/pgsql/pgstartup.log
# service postgresql initdb
В случае возникновения непонятных ситуаций, анализ данного фала позволяет установить причину запрета доступа.
Кластер будет создан по адресу: '''/var/lib/pgsql/data'''


* Следующим шагом будет установка SQL-функций которые неоходимы для работы с мандатными метками.
Данные функции описаны в файле:
# cat /usr/share/pgsql/contrib/sepgsql.sql
LOAD '$libdir/sepgsql';
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_getcon() RETURNS text AS '$libdir/sepgsql', 'sepgsql_getcon' LANGUAGE C;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_setcon(text) RETURNS bool AS '$libdir/sepgsql', 'sepgsql_setcon' LANGUAGE C;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_mcstrans_in(text) RETURNS text AS '$libdir/sepgsql', 'sepgsql_mcstrans_in' LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_mcstrans_out(text) RETURNS text AS '$libdir/sepgsql', 'sepgsql_mcstrans_out' LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_restorecon(text) RETURNS bool AS '$libdir/sepgsql', 'sepgsql_restorecon' LANGUAGE C;
SELECT sepgsql_restorecon(NULL);


* В конфигурационный файл кластера необходимо внести директиву, которая будет указывать использовать SeLinux менеджер. Для этого отредактируйте файл /var/lib/pgsql/data/postgresql.conf, и установите:
shared_preload_libraries = 'sepgsql'
sepgsql.permissive = off
sepgsql.debug_audit = on
Внимание: категорически не рекомендуется отключать опцию: '''sepgsql.permissive = off''', так как срабатывание '''denied''' происходит только один раз. Для последующих запросов всегда будет срабатывать '''allow'''. Таким образом эта опция становится бесполезной для отладки.
Опция '''sepgsql.debug_audit = on''' указывает протоколировать результат проверки для каждого действия.
Если не указано другое, логи сохраняются в '''/var/lib/pgsql/pgstartup.log'''.
В случае возникновения непонятных ситуаций, анализ данного фала позволяет установить причину запрета доступа.


О назначение каждой из функций расказано на официальном сайте:


http://www.postgresql.org/docs/9.3/static/sepgsql.html
* Следующим шагом будет установка SQL-функций которые неоходимы для работы с мандатными метками.
Данные функции описаны в файле:
# cat /usr/share/pgsql/contrib/sepgsql.sql
LOAD '$libdir/sepgsql';
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_getcon() RETURNS text AS '$libdir/sepgsql', 'sepgsql_getcon' LANGUAGE C;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_setcon(text) RETURNS bool AS '$libdir/sepgsql', 'sepgsql_setcon' LANGUAGE C;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_mcstrans_in(text) RETURNS text AS '$libdir/sepgsql', 'sepgsql_mcstrans_in' LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_mcstrans_out(text) RETURNS text AS '$libdir/sepgsql', 'sepgsql_mcstrans_out' LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_restorecon(text) RETURNS bool AS '$libdir/sepgsql', 'sepgsql_restorecon' LANGUAGE C;
SELECT sepgsql_restorecon(NULL);
О назначение каждой из функций расказано на официальном сайте: http://www.postgresql.org/docs/9.3/static/sepgsql.html


Архитектура PostgreSQL предполагает наличие трех баз данных:
Архитектура PostgreSQL предполагает наличие трех баз данных:
* postgres - начальная БД, создается при initdb, в случае необходимости можно смело удалить.
# postgres - начальная БД, создается при initdb, в случае необходимости можно смело удалить.
* template1 - БД-образец, которая будет взята за основу для вновь создаваемых БД. Сюда администратор ОС может внести нужны изменения, которые будут применимы для всех вновь создаваемых БД.
# template1 - БД-образец, которая будет взята за основу для вновь создаваемых БД. Сюда администратор ОС может внести нужны изменения, которые будут применимы для всех вновь создаваемых БД.
* template0 - БД-образец, которая является образцом БД без каких либо модификаций со стороны администратора.
# template0 - БД-образец, которая является образцом БД без каких либо модификаций со стороны администратора.
 


Установку функций необходимо осуществлять когда сервер СУБД выключен, в режиме --single
Установку функций необходимо осуществлять когда сервер СУБД выключен, в режиме '''--single'''
В системе серевер PostgreSQL выполняется от имени пользователя postgres
В системе серевер PostgreSQL выполняется от имени пользователя '''postgres'''. Поэтому переключимся на него:
Поэтому переключимся на него:
# su -l postgres -s /bin/bash
# su -l postgres -s /bin/bash
Укажим где находится кластер:
Укажим где находится кластер:
$ export PGDATA=/var/lib/pgsql/data
$ export PGDATA=/var/lib/pgsql/data


Для каждой из выше-перечисленных БД установим необходмые функции:
Для каждой из выше-перечисленных БД установим необходмые функции:
$ postgres --single -F -c exit_on_error=true template0 < /usr/share/pgsql/contrib/sepgsql.sql
$ postgres --single -F -c exit_on_error=true template1 < /usr/share/pgsql/contrib/sepgsql.sql
$ postgres --single -F -c exit_on_error=true postgres < /usr/share/pgsql/contrib/sepgsql.sql


$ postgres --single -F -c exit_on_error=true template0 < /usr/share/pgsql/contrib/sepgsql.sql
Завершим сеанс пользователя '''postgres'''.
$ postgres --single -F -c exit_on_error=true template1 < /usr/share/pgsql/contrib/sepgsql.sql
$ postgres --single -F -c exit_on_error=true postgres < /usr/share/pgsql/contrib/sepgsql.sql


Завершим сеанс пользователя postgres.
Также можно выполнять команду в другой вариации:
su -l postgres -s /bin/sh -c "/usr/bin/pg_ctl -D /var/lib/pgsql/data stop -mf"


Также можно выполнять команду в другой вариации:
su -l postgres -s /bin/sh -c "/usr/bin/pg_ctl -D /var/lib/pgsql/data stop -mf"


* Убедитесь что сервер будет запускаться автоматически при старте системы:
* Убедитесь что сервер будет запускаться автоматически при старте системы:
# chkconfig postgresql on
или
# systemctl enable postgresql


# chkconfig postgresql on
* Запустите сервис СУБД:
 
# service postgresql start
или
или
# systemctl enable postgresql
# systemctl start postgresql
 
 
* Далее производите настройку кластера с учетом ваших требований. Например задайте пароль для владельца БД postgres:
# ALTER USER postgres with password '123’;
/var/lib/pgsql/data/pg_hba.conf trust -> md5
 
http://scratching.psybermonkey.net/2009/06/postgresql-how-to-reset-user-name.html
 
* Убедится что менеджер политики в СУБД находится в активном состоянии:
postgres=# SHOW sepgsql.permissive;
  sepgsql.permissive
--------------------
off
(1 строка)
 
или из командной строки:
 
$ psql -U postgres -t -c 'SHOW sepgsql.permissive'
show all; — показать все настройки СУБД;
 


* Запустите севис СУБД:
* Следует убедится что сам сервер получит необходимые права SeLinux. Т.е. он правильно запущен:
# ps aZx | grep postgres
officer_u:officer_r:postgresql_t:s0-s5:c0.c15 23438 pts/0 S  0:00 /usr/bin/postgres -D /var/lib/pgsql/data


# service postgresql start
или
# systemctl start postgresql


* Убедитесь что сервер СУБД работает с учетом мандатных прав доступа:
== Мандатные метки и объекты ==


# psql -U postgres postgres


postgres=# SELECT sepgsql_getcon();
* Текущий контекст пользователя можно узнать командой:
# psql -U postgres postgres
postgres=# SELECT sepgsql_getcon();
               sepgsql_getcon                 
               sepgsql_getcon                 
---------------------------------------------
---------------------------------------------
officer_u:officer_r:officer_t:s0-s15:c0.c31
  officer_u:officer_r:officer_t:s0-s15:c0.c31
(1 строка)
(1 строка)
 
 
* Количество объектов в БД о которых знает SeLinux:
# SELECT count(*) FROM pg_catalog.pg_seclabels;
count
-------
  3582
(1 строка)
 
 
* В схеме pg_catalog присутствует две дополнительные таблицы:
Связывает ID объекта в БД с его меткой
# select * from pg_catalog.pg_seclabel;
    99 |    2615 |        0 | selinux  | generic_u:object_r:sepgsql_schema_t:s0
  11215 |    2615 |        0 | selinux  | generic_u:object_r:sepgsql_schema_t:s0
  ...
 
# \d+ pg_catalog.pg_seclabel
objoid  | oid    | NOT NULL    | plain    |                    |
classoid | oid    | NOT NULL    | plain    |                    |
objsubid | integer | NOT NULL    | plain    |                    |
provider | text    |              | extended  |                    |
label    | text    |              | extended  |                    |
 
Имя объекта, тип объекта, метка
# select * from pg_catalog.pg_seclabels;
  2619 |    1259 |        0 | table    |          11 | pg_statistic
 
 
* Объекту в БД можно назначить новую метку, отличную от той, которую он получает согласно политике в момент создания.
Как правило, этом может сделать только офицер безопасности. Т.е. пользователь имеющий мандатные права '''officer_t'''.
Для изменения метки объекта БД следует использовать команду:
# security label on column s1.t1.c1 is 'officer_u:object_r:sepgsql_table_t:s1';
SECURITY LABEL
Полный синтаксис команды можно посмотреть в руководстве: http://www.postgresql.org/docs/9.3/static/sql-security-label.html
 
 
* Типы объектов в БД которые поддерживаются политикой:
# database
# schemas
# tables
# columns
# sequences
# views
# functions
 
или, список поддерживаемых объектов можно это узнать командой:
# SELECT distinct objtype from pg_catalog.pg_seclabels;
  objtype 
-----------
table
column
schema
database
aggregate
function
view
(7 строк)
 
 
== SePostreSQL В действии ==
 
* Находясь в командной строке psql, полезны следующие команды:
** \? - список сокращенных команд
** \l - список баз данных в кластере
** \ dn - список схем в текущей БД
** \dt s1. - списко таблиц в схеме
** \d+ s1.t1 - описание таблицы
** SELECT * from pg_catalog.pg_namespace; - также список схем
 
* Пример ограничения доступа при попытке удалить колонку.
 
Пользователь с уровнем '''s1''' создает колонку в таблице:
$ newrole -l s1
$ psql -U postgres db1
db1=# SELECT sepgsql_getcon();
                sepgsql_getcon             
--------------------------------------------
  generic_u:generic_r:generic_t:s1-s3:c2.c14
(1 строка)
# alter table s1.t1 add c3 int;
ALTER TABLE
 
Пользователь с уровнем '''s0''' не может ее удалить:
# alter table s1.t1 drop c3;
ОШИБКА:  SELinux: security policy violation
Из лог файла '''/var/lib/pgsql/pgstartup.log''' видно:
ОТМЕТКА:  SELinux: denied { drop } scontext=generic_u:generic_r:generic_t:s0-s3:c2.c14 tcontext=generic_u:object_r:sepgsql_table_t:s1 tclass=db_column name="s1.t1.c3"
ОПЕРАТОР:  alter table s1.t1 drop c3;                                         
ОШИБКА:  SELinux: security policy violation
 
Эту колонку, пользователь с уровнем доступа '''s1''', но он не может удалить колонки которые были созданы на уровне '''s0''':
db1=# alter table s1.t1 drop c2;
ОШИБКА:  SELinux: security policy violation
db1=# alter table s1.t1 drop c3;
ALTER TABLE
 
* Пример роботы с данными в таблице.
 
Пусть есть таблица '''s1.t1''', у таблицы есть две колонки '''s1.t1.c1''' и '''s1.t1.c2''', и уставлены следующие мандатные права:
# select * from pg_seclabels where objname ~ 's1.t1.' and objsubid > 0;
  objoid | classoid | objsubid | objtype | objnamespace | objname  | provider |                label               
--------+----------+----------+---------+--------------+----------+----------+---------------------------------------
  16390 |    1259 |        1 | column  |        16389 | s1.t1.c1 | selinux  | generic_u:object_r:sepgsql_table_t:s0
  16390 |    1259 |        7 | column  |        16389 | s1.t1.c2 | selinux  | generic_u:object_r:sepgsql_table_t:s1
(2 строки)
 
Данные из уровня '''s0''':
 
# SELECT sepgsql_getcon();
                sepgsql_getcon             
--------------------------------------------
  generic_u:generic_r:generic_t:s0-s3:c2.c14
(1 строка)
db1=# INSERT INTO s1.t1 (c1, c2) values (1, 1);
ОШИБКА:  SELinux: security policy violation
db1=# INSERT INTO s1.t1 (c2) values (1);
ОШИБКА:  SELinux: security policy violation
db1=# INSERT INTO s1.t1 (c1) values (1);
INSERT 0 1
db1=# select * from s1.t1;
ОШИБКА:  SELinux: security policy violation
db1=# select c2 from s1.t1;
ОШИБКА:  SELinux: security policy violation
db1=# select c1 from s1.t1;
  c1
----
  1
(1 строка)
db1=# update s1.t1 set c1 = 2, c2 = 2 where c1 = 1;
ОШИБКА:  SELinux: security policy violation
db1=# update s1.t1 set c1 = 2 where c1 = 1;
UPDATE 1
 
 
Данные из уровня '''s1''':
db1=# SELECT sepgsql_getcon();
                sepgsql_getcon             
--------------------------------------------
  generic_u:generic_r:generic_t:s1-s3:c2.c14
(1 строка)
INSERT INTO s1.t1 (c2) values (1);
ОТМЕТКА:  SELinux: denied { insert } scontext=generic_u:generic_r:generic_t:s1-s3:c2.c14 tcontext=generic_u:object_r:sepgsql_table_t:s0 tclass=db_table name="s1.t1"
update s1.t1 set c2 = 2 where c1 = 2;
ОШИБКА:  SELinux: security policy violation
ОТМЕТКА:  SELinux: denied { update } scontext=generic_u:generic_r:generic_t:s1-s3:c2.c14 tcontext=generic_u:object_r:sepgsql_table_t:s0 tclass=db_table name="s1.t1"
 
 
== Различные команды ==
 
SELECT 'system_u:object_r:sepgsql_table_t:s0:c' || id AS security_label, * INTO t FROM drink WHERE id in (2,4,6);
 
 
== Мастер класс SeLinux: правила, атрибуты, классы, домены, итд. ==
 
* Объект в схеме создается сам по себе. Запись в схему не происходит.
* MLS часть для вновь создаваемого объекта, устанавливается исходя и MLS субъекта а не родителя объекта.
 
 
* Офицер безопасности имеет специальный атрибут '''sepgsql_unconfined_type''' который позоволяет производить ему любые операции.
 
# seinfo -tofficer_t -x | grep sql
      sepgsql_unconfined_type
 
# seinfo -ttrusted_t -x | grep sql
      sepgsql_unconfined_type
 
 
* Атрибут "всепозволености" содержат следующие домены:
# seinfo -asepgsql_unconfined_type -x
    sepgsql_unconfined_type
      sepgsql_trusted_proc_t
      officer_t
      trusted_t
 
 
* Атрибует '''sepgsql_client_type''' маркирует обычного пользователя.
# seinfo -tgeneric_t -x | grep sql
      sepgsql_client_type
 
# seinfo -asepgsql_client_type -x
    sepgsql_client_type
      generic_t
 
 
* В качестве модуля (расширения) можно подгружать любые файлы имеющие следующий тип:
# seinfo -tdef_t -x | grep sql
      sepgsql_module_type
 
 
* Типы (домены) SeLinux которые получают объекты БД:
 
# seinfo -asepgsql_database_type -x
    sepgsql_database_type
      sepgsql_db_t
 
# seinfo -asepgsql_schema_type -x
    sepgsql_schema_type
      sepgsql_schema_t
 
# seinfo -asepgsql_table_type -x
    sepgsql_table_type
      sepgsql_sysobj_t
      sepgsql_table_t
      sepgsql_temp_object_t
 
# seinfo -asepgsql_sysobj_table_type -x
    sepgsql_sysobj_table_type
      sepgsql_sysobj_t
 
# seinfo -asepgsql_sequence_type -x
    sepgsql_sequence_type
      sepgsql_seq_t
      sepgsql_temp_object_t
 
# seinfo -asepgsql_view_type -x
    sepgsql_view_type
      sepgsql_view_t
      sepgsql_temp_object_t
 
# seinfo -asepgsql_procedure_type -x
    sepgsql_procedure_type
      sepgsql_proc_exec_t
      sepgsql_trusted_proc_exec_t
      sepgsql_temp_object_t
 
# seinfo -asepgsql_trusted_procedure_type -x
    sepgsql_trusted_procedure_type
      sepgsql_trusted_proc_exec_t
 
 
* Функции которым «все разрешено» это особый вид субъекта
# seinfo -tsepgsql_trusted_proc_t -x
    sepgsql_trusted_proc_t
      sepgsql_unconfined_type
      unconfineddomain
      mlstrustedsubject
      domain
 
 
* Пользователь имеющий роль generic_r может «очутиться» в следующий доменах:
# seinfo -rgeneric_r -x
    generic_r
      Dominated Roles:
          generic_r
      Types:
          sepgsql_trusted_proc_t
          init
          generic_t
          kernel_t
          dbusd_t
          login_t
          postgresql_t
          dolphin_t
          officer_t
          systemd_t
          trusted_t




* Далее производите настройку кластера с учетом ваших требований. Например задайте пароль для владельца БД postgres:
* Пользователь имеющий роль officer_r может «очутиться» в следующий доменах:
# ALTER USER postgres with password '123’;
# seinfo -rofficer_r -x
# /var/lib/pgsql/data/pg_hba.conf trust -> md5
    officer_r
      Dominated Roles:
          officer_r
      Types:
          sepgsql_trusted_proc_t
          init
          generic_t
          kernel_t
          dbusd_t
          login_t
          postgresql_t
          dolphin_t
          officer_t
          systemd_t
          trusted_t




== Внутренности ==
* СУБД выполняется в процессе, который имеет следующие характеристики:
Объект в схеме создается сам по себе. Запись в схему не происходит. create идет только как
# seinfo -tpostgresql_t -x
    postgresql_t
      unconfineddomain
      mlstrustedsubject
      domain






[[Категория:Features]]
[[Категория:Features]]
[[Категория:Admin]]
{{Category navigation|title=Features|category=Features|sortkey={{SUBPAGENAME}}}}
{{Category navigation|title=Features|category=Features|sortkey={{SUBPAGENAME}}}}

Текущая версия от 10:45, 31 мая 2019

СУБД PostgresSQL в ALT Linux с мандатным уровнем доступа

Дополнительная информация

  • Быстрая справка по SQL:

http://www.tutorialspoint.com/postgresql/postgresql_update_query.htm

  • Методы над каждым объектом(классом):

http://wiki.postgresql.org/wiki/SEPostgreSQL_References

  • Модуль SeLinux для PostgreSQL:

http://www.postgresql.org/docs/9.3/static/sepgsql.html

  • Страница руководства
$ man sepgsql_contexts

Введение

Данный документ предполагает что администратор имеет необходимые знания для администрировании СУБД PostgreSQL.


Основное отличие от RefPolicy:

  • убрано разделение объектов СУБД по различным доменам SeLinux для пользователей и администраторов.
  • логически, pgsql различает два домена подключаемых пользователей: обычные пользователи, офицер безопасности


Ключевые моменты:

  1. Политика SeLinux написана для PostgreSQL 9.3
  2. Стандартная система разграничения прав доступа PostgresSQL на основе ролей и прав сохраняется.
  3. Мандатная система доступа, накладываемая SeLinux, является дополнительной, и работает в согласовании с глобальными мандатными метками SeLinux пользователей ОС.
  4. Предполагается что клиент и сервер находятся в рамках одного узла.
  5. При необходимости, можно расширить для работы в сети, где клиент и сервер находятся на различных узлах в ОС ALT Linux. Данная схема не тестировалась.
  6. Для поддержки SeLinux сервер PostgreSQL должен быть изъят из chroot, или в chroot необходимо будет пробрасывать файловую систему в chroot.


Концепция работы:

  1. Контекст безопасности клиента проверяется при соединении с сокетом сервера PostgreSQL.
  2. Ограничение действий в СУБД осуществляет сам сервер PostgreSQL согласно политике SeLinux.
  3. Ключевой момент состоит в том, что не ядро ОС пресекает запрещенные действия а сервер СУБД.
  4. В СУБД PostgreSQL встроен менеджер. Данный менеджер работает в пространстве пользователя ОС.
  5. Менеджер обращается к ядру с использованием libselinux для проверки действий.
  6. Аналогичным образом работает система Xorg: http://taiga.selinuxproject.org/~rhaines/diagrams/26-x-windows.png


При авторизации в СУБД от имени владельца database в кластере PostgreSQL, будет сохранен его системный мандатный уровень доступа, который будет принимать участие в решении вопросов доступа. Т.е. возможен такой сценарий:

  1. В ОС авторизуется пользователь test.
  2. ОС назначает мандатные права пользователю test в рамках открытой сессии.
  3. Пользователь меняет свой системный идентификатор пользователя на root: su -
  4. Манданые права пользователя остаются прежние.
  5. Авторизуется в СУБД как владелец некой БД.

В итоге получается: даже при таком раскладе он ограничен в своих действиях, так как первоначальный мандатный уровень назначенный пользователю test при открытии сессии сохранился.


Установка и настройка кластера

  • Авторизоваться в ОС от имени root.


  • Убедится что ОС назначила root мандатные права офицера безопасности:
# runcon 
officer_u:officer_r:officer_t:s0-s15:c0.c31


  • Убедитесь что политика SeLinux содержит модуль psql, в котором присутствует необходимый набор правил:
# semodule -l | grep sql
psql	1.0.4


  • Проверить что установлен сервер СУБД PostgreSQL версии 9.3, а также установлен пакет postgresql9.3-contrib
# rpm -q postgresql9.3-server postgresql9.3-contrib
postgresql9.3-server-9.3.4-alt0.M70P.1
postgresql9.3-contrib-9.3.4-alt0.M70P.1


  • Если сервер postgresql запущен, тогда его необходимо временно выключить:
# service postgresql status
postgres is running
# service postgresql stop
postgres is running


  • В случае если кластер СУБД не инициализирован его необходимо инициализировать:
# service postgresql initdb

Кластер будет создан по адресу: /var/lib/pgsql/data


  • В конфигурационный файл кластера необходимо внести директиву, которая будет указывать использовать SeLinux менеджер. Для этого отредактируйте файл /var/lib/pgsql/data/postgresql.conf, и установите:
shared_preload_libraries = 'sepgsql'
sepgsql.permissive = off
sepgsql.debug_audit = on

Внимание: категорически не рекомендуется отключать опцию: sepgsql.permissive = off, так как срабатывание denied происходит только один раз. Для последующих запросов всегда будет срабатывать allow. Таким образом эта опция становится бесполезной для отладки. Опция sepgsql.debug_audit = on указывает протоколировать результат проверки для каждого действия. Если не указано другое, логи сохраняются в /var/lib/pgsql/pgstartup.log. В случае возникновения непонятных ситуаций, анализ данного фала позволяет установить причину запрета доступа.


  • Следующим шагом будет установка SQL-функций которые неоходимы для работы с мандатными метками.

Данные функции описаны в файле:

# cat /usr/share/pgsql/contrib/sepgsql.sql
…
LOAD '$libdir/sepgsql';
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_getcon() RETURNS text AS '$libdir/sepgsql', 'sepgsql_getcon' LANGUAGE C;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_setcon(text) RETURNS bool AS '$libdir/sepgsql', 'sepgsql_setcon' LANGUAGE C;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_mcstrans_in(text) RETURNS text AS '$libdir/sepgsql', 'sepgsql_mcstrans_in' LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_mcstrans_out(text) RETURNS text AS '$libdir/sepgsql', 'sepgsql_mcstrans_out' LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION pg_catalog.sepgsql_restorecon(text) RETURNS bool AS '$libdir/sepgsql', 'sepgsql_restorecon' LANGUAGE C;
SELECT sepgsql_restorecon(NULL);

О назначение каждой из функций расказано на официальном сайте: http://www.postgresql.org/docs/9.3/static/sepgsql.html

Архитектура PostgreSQL предполагает наличие трех баз данных:

  1. postgres - начальная БД, создается при initdb, в случае необходимости можно смело удалить.
  2. template1 - БД-образец, которая будет взята за основу для вновь создаваемых БД. Сюда администратор ОС может внести нужны изменения, которые будут применимы для всех вновь создаваемых БД.
  3. template0 - БД-образец, которая является образцом БД без каких либо модификаций со стороны администратора.

Установку функций необходимо осуществлять когда сервер СУБД выключен, в режиме --single В системе серевер PostgreSQL выполняется от имени пользователя postgres. Поэтому переключимся на него:

# su -l postgres -s /bin/bash

Укажим где находится кластер:

$ export PGDATA=/var/lib/pgsql/data

Для каждой из выше-перечисленных БД установим необходмые функции:

$ postgres --single -F -c exit_on_error=true template0 < /usr/share/pgsql/contrib/sepgsql.sql
$ postgres --single -F -c exit_on_error=true template1 < /usr/share/pgsql/contrib/sepgsql.sql
$ postgres --single -F -c exit_on_error=true postgres < /usr/share/pgsql/contrib/sepgsql.sql

Завершим сеанс пользователя postgres.

Также можно выполнять команду в другой вариации:

su -l postgres -s /bin/sh -c "/usr/bin/pg_ctl -D /var/lib/pgsql/data stop -mf"


  • Убедитесь что сервер будет запускаться автоматически при старте системы:
# chkconfig postgresql on

или

# systemctl enable postgresql


  • Запустите сервис СУБД:
# service postgresql start

или

# systemctl start postgresql


  • Далее производите настройку кластера с учетом ваших требований. Например задайте пароль для владельца БД postgres:
# ALTER USER postgres with password '123’;
/var/lib/pgsql/data/pg_hba.conf trust -> md5

http://scratching.psybermonkey.net/2009/06/postgresql-how-to-reset-user-name.html

  • Убедится что менеджер политики в СУБД находится в активном состоянии:
postgres=# SHOW sepgsql.permissive;
 sepgsql.permissive 
--------------------
off
(1 строка)

или из командной строки:

$ psql -U postgres -t -c 'SHOW sepgsql.permissive'
show all; — показать все настройки СУБД;


  • Следует убедится что сам сервер получит необходимые права SeLinux. Т.е. он правильно запущен:
# ps aZx | grep postgres
officer_u:officer_r:postgresql_t:s0-s5:c0.c15 23438 pts/0 S   0:00 /usr/bin/postgres -D /var/lib/pgsql/data


Мандатные метки и объекты

  • Текущий контекст пользователя можно узнать командой:
# psql -U postgres postgres
postgres=# SELECT sepgsql_getcon();
              sepgsql_getcon                
---------------------------------------------
 officer_u:officer_r:officer_t:s0-s15:c0.c31
(1 строка)


  • Количество объектов в БД о которых знает SeLinux:
# SELECT count(*) FROM pg_catalog.pg_seclabels;
count 
-------
 3582
(1 строка)


  • В схеме pg_catalog присутствует две дополнительные таблицы:

Связывает ID объекта в БД с его меткой

# select * from pg_catalog.pg_seclabel;
    99 |     2615 |        0 | selinux  | generic_u:object_r:sepgsql_schema_t:s0
 11215 |     2615 |        0 | selinux  | generic_u:object_r:sepgsql_schema_t:s0
 ... 
# \d+ pg_catalog.pg_seclabel
objoid   | oid     | NOT NULL     | plain     |                     | 
classoid | oid     | NOT NULL     | plain     |                     | 
objsubid | integer | NOT NULL     | plain     |                     | 
provider | text    |              | extended  |                     | 
label    | text    |              | extended  |                     | 

Имя объекта, тип объекта, метка

# select * from pg_catalog.pg_seclabels; 
  2619 |     1259 |        0 | table     |           11 | pg_statistic


  • Объекту в БД можно назначить новую метку, отличную от той, которую он получает согласно политике в момент создания.

Как правило, этом может сделать только офицер безопасности. Т.е. пользователь имеющий мандатные права officer_t. Для изменения метки объекта БД следует использовать команду:

# security label on column s1.t1.c1 is 'officer_u:object_r:sepgsql_table_t:s1';
SECURITY LABEL

Полный синтаксис команды можно посмотреть в руководстве: http://www.postgresql.org/docs/9.3/static/sql-security-label.html


  • Типы объектов в БД которые поддерживаются политикой:
  1. database
  2. schemas
  3. tables
  4. columns
  5. sequences
  6. views
  7. functions

или, список поддерживаемых объектов можно это узнать командой:

# SELECT distinct objtype from pg_catalog.pg_seclabels;
 objtype  
-----------
table
column
schema
database
aggregate
function
view
(7 строк)


SePostreSQL В действии

  • Находясь в командной строке psql, полезны следующие команды:
    • \? - список сокращенных команд
    • \l - список баз данных в кластере
    • \ dn - список схем в текущей БД
    • \dt s1. - списко таблиц в схеме
    • \d+ s1.t1 - описание таблицы
    • SELECT * from pg_catalog.pg_namespace; - также список схем
  • Пример ограничения доступа при попытке удалить колонку.

Пользователь с уровнем s1 создает колонку в таблице:

$ newrole -l s1
$ psql -U postgres db1
db1=# SELECT sepgsql_getcon();
               sepgsql_getcon               
--------------------------------------------
 generic_u:generic_r:generic_t:s1-s3:c2.c14
(1 строка)
# alter table s1.t1 add c3 int;
ALTER TABLE

Пользователь с уровнем s0 не может ее удалить:

# alter table s1.t1 drop c3;
ОШИБКА:  SELinux: security policy violation

Из лог файла /var/lib/pgsql/pgstartup.log видно:

ОТМЕТКА:  SELinux: denied { drop } scontext=generic_u:generic_r:generic_t:s0-s3:c2.c14 tcontext=generic_u:object_r:sepgsql_table_t:s1 tclass=db_column name="s1.t1.c3"
ОПЕРАТОР:  alter table s1.t1 drop c3;                                           
ОШИБКА:  SELinux: security policy violation

Эту колонку, пользователь с уровнем доступа s1, но он не может удалить колонки которые были созданы на уровне s0:

db1=# alter table s1.t1 drop c2;
ОШИБКА:  SELinux: security policy violation
db1=# alter table s1.t1 drop c3;
ALTER TABLE
  • Пример роботы с данными в таблице.

Пусть есть таблица s1.t1, у таблицы есть две колонки s1.t1.c1 и s1.t1.c2, и уставлены следующие мандатные права:

# select * from pg_seclabels where objname ~ 's1.t1.' and objsubid > 0;
 objoid | classoid | objsubid | objtype | objnamespace | objname  | provider |                 label                 
--------+----------+----------+---------+--------------+----------+----------+---------------------------------------
  16390 |     1259 |        1 | column  |        16389 | s1.t1.c1 | selinux  | generic_u:object_r:sepgsql_table_t:s0
  16390 |     1259 |        7 | column  |        16389 | s1.t1.c2 | selinux  | generic_u:object_r:sepgsql_table_t:s1
(2 строки)

Данные из уровня s0:

# SELECT sepgsql_getcon();
               sepgsql_getcon               
--------------------------------------------
 generic_u:generic_r:generic_t:s0-s3:c2.c14
(1 строка)
db1=# INSERT INTO s1.t1 (c1, c2) values (1, 1);
ОШИБКА:  SELinux: security policy violation
db1=# INSERT INTO s1.t1 (c2) values (1);
ОШИБКА:  SELinux: security policy violation
db1=# INSERT INTO s1.t1 (c1) values (1);
INSERT 0 1
db1=# select * from s1.t1;
ОШИБКА:  SELinux: security policy violation
db1=# select c2 from s1.t1;
ОШИБКА:  SELinux: security policy violation
db1=# select c1 from s1.t1;
 c1 
----
  1
(1 строка)
db1=# update s1.t1 set c1 = 2, c2 = 2 where c1 = 1;
ОШИБКА:  SELinux: security policy violation
db1=# update s1.t1 set c1 = 2 where c1 = 1;
UPDATE 1


Данные из уровня s1:

db1=# SELECT sepgsql_getcon();
               sepgsql_getcon               
--------------------------------------------
 generic_u:generic_r:generic_t:s1-s3:c2.c14
(1 строка)
INSERT INTO s1.t1 (c2) values (1);
ОТМЕТКА:  SELinux: denied { insert } scontext=generic_u:generic_r:generic_t:s1-s3:c2.c14 tcontext=generic_u:object_r:sepgsql_table_t:s0 tclass=db_table name="s1.t1"
update s1.t1 set c2 = 2 where c1 = 2;
ОШИБКА:  SELinux: security policy violation
ОТМЕТКА:  SELinux: denied { update } scontext=generic_u:generic_r:generic_t:s1-s3:c2.c14 tcontext=generic_u:object_r:sepgsql_table_t:s0 tclass=db_table name="s1.t1"


Различные команды

SELECT 'system_u:object_r:sepgsql_table_t:s0:c' || id AS security_label, * INTO t FROM drink WHERE id in (2,4,6);


Мастер класс SeLinux: правила, атрибуты, классы, домены, итд.

  • Объект в схеме создается сам по себе. Запись в схему не происходит.
  • MLS часть для вновь создаваемого объекта, устанавливается исходя и MLS субъекта а не родителя объекта.


  • Офицер безопасности имеет специальный атрибут sepgsql_unconfined_type который позоволяет производить ему любые операции.
# seinfo -tofficer_t -x | grep sql
      sepgsql_unconfined_type
# seinfo -ttrusted_t -x | grep sql
      sepgsql_unconfined_type


  • Атрибут "всепозволености" содержат следующие домены:
# seinfo -asepgsql_unconfined_type -x
   sepgsql_unconfined_type
      sepgsql_trusted_proc_t
      officer_t
      trusted_t


  • Атрибует sepgsql_client_type маркирует обычного пользователя.
# seinfo -tgeneric_t -x | grep sql
      sepgsql_client_type
# seinfo -asepgsql_client_type -x
   sepgsql_client_type
      generic_t


  • В качестве модуля (расширения) можно подгружать любые файлы имеющие следующий тип:
# seinfo -tdef_t -x | grep sql
      sepgsql_module_type


  • Типы (домены) SeLinux которые получают объекты БД:
# seinfo -asepgsql_database_type -x
   sepgsql_database_type
      sepgsql_db_t
# seinfo -asepgsql_schema_type -x
   sepgsql_schema_type
      sepgsql_schema_t
# seinfo -asepgsql_table_type -x
   sepgsql_table_type
      sepgsql_sysobj_t
      sepgsql_table_t
      sepgsql_temp_object_t
# seinfo -asepgsql_sysobj_table_type -x
   sepgsql_sysobj_table_type
      sepgsql_sysobj_t
# seinfo -asepgsql_sequence_type -x
   sepgsql_sequence_type
      sepgsql_seq_t
      sepgsql_temp_object_t
# seinfo -asepgsql_view_type -x
   sepgsql_view_type
      sepgsql_view_t
      sepgsql_temp_object_t
# seinfo -asepgsql_procedure_type -x
   sepgsql_procedure_type
      sepgsql_proc_exec_t
      sepgsql_trusted_proc_exec_t
      sepgsql_temp_object_t
# seinfo -asepgsql_trusted_procedure_type -x
   sepgsql_trusted_procedure_type
      sepgsql_trusted_proc_exec_t


  • Функции которым «все разрешено» это особый вид субъекта
# seinfo -tsepgsql_trusted_proc_t -x
   sepgsql_trusted_proc_t
      sepgsql_unconfined_type
      unconfineddomain
      mlstrustedsubject
      domain


  • Пользователь имеющий роль generic_r может «очутиться» в следующий доменах:
# seinfo -rgeneric_r -x
   generic_r
      Dominated Roles:
         generic_r
      Types:
         sepgsql_trusted_proc_t
         init
         generic_t
         kernel_t
         dbusd_t
         login_t
         postgresql_t
         dolphin_t
         officer_t
         systemd_t
         trusted_t


  • Пользователь имеющий роль officer_r может «очутиться» в следующий доменах:
# seinfo -rofficer_r -x
   officer_r
      Dominated Roles:
         officer_r
      Types:
         sepgsql_trusted_proc_t
         init
         generic_t
         kernel_t
         dbusd_t
         login_t
         postgresql_t
         dolphin_t
         officer_t
         systemd_t
         trusted_t


  • СУБД выполняется в процессе, который имеет следующие характеристики:
# seinfo -tpostgresql_t -x
   postgresql_t
      unconfineddomain
      mlstrustedsubject
      domain