RHEL6もβが公開とかで、そろそろRBACが真っ当に使えるようなSELinuxの標準ポリシーが出てきそうな今日この頃。先んじて設定方法をまとめておく。
一応、標準ではwebコンテンツ管理者ロールというのが入っているが、私の興味分野的にアレなので、DB管理者ロールを定義して、特定のユーザがDB管理者ロールの時にだけDB起動/再起動などを行えるようにしたい。
まず、ポリシーモジュールを書く。
既にアップストリームに統合済みのポリシーも含まれているので、後々のFedoraではconflictする事もあるやと。その場合は、適宜重複分を削ってほしい。
policy_module(dbadm, 1.1.0)
########################################
#
# Declarations
#
## <desc>
## <p>
## Allow dbadm to manage files in users home directories
## </p>
## </desc>
gen_tunable(dbadm_manage_user_files, false)
## <desc>
## <p>
## Allow dbadm to read files in users home directories
## </p>
## </desc>
gen_tunable(dbadm_read_user_files, false)
role dbadm_r;
userdom_base_user_template(dbadm)
########################################
#
# database admin local policy
#
allow dbadm_t self:capability { dac_override dac_read_search sys_ptrace };
files_dontaudit_search_all_dirs(dbadm_t)
files_manage_generic_locks(dbadm_t)
files_list_var(dbadm_t)
selinux_get_enforce_mode(dbadm_t)
logging_send_syslog_msg(dbadm_t)
userdom_dontaudit_search_user_home_dirs(dbadm_t)
tunable_policy(`dbadm_manage_user_files',`
userdom_manage_user_home_content_files(dbadm_t)
userdom_read_user_tmp_files(dbadm_t)
userdom_write_user_tmp_files(dbadm_t)
')
tunable_policy(`dbadm_read_user_files',`
userdom_read_user_home_content_files(dbadm_t)
userdom_read_user_tmp_files(dbadm_t)
')
optional_policy(`
mysql_admin(dbadm_t, dbadm_r)
')
optional_policy(`
postgresql_admin(dbadm_t, dbadm_r)
')
optional_policy(`
staff_role_change_to(dbadm_r)
')
#
# Hotfix in type_transition rules and permissions to execute
# system defined procedures.
# (memo: this fix was already upstreamed at Mon Apr 12 2010)
#
gen_require(`
class db_database all_db_database_perms;
class db_table all_db_table_perms;
class db_procedure all_db_procedure_perms;
class db_column all_db_column_perms;
class db_tuple all_db_tuple_perms;
class db_blob all_db_blob_perms;
attribute sepgsql_admin_type;
attribute sepgsql_database_type;
type sepgsql_db_t;
type sepgsql_table_t;
type sepgsql_proc_exec_t;
type sepgsql_blob_t;
')
type_transition sepgsql_admin_type sepgsql_admin_type:db_database sepgsql_db_t;
type_transition sepgsql_admin_type sepgsql_database_type:db_table sepgsql_table_t;
type_transition sepgsql_admin_type sepgsql_database_type:db_procedure sepgsql_proc_exec_t;
type_transition sepgsql_admin_type sepgsql_database_type:db_blob sepgsql_blob_t;
allow sepgsql_admin_type sepgsql_proc_exec_t:db_procedure execute;これをビルドしてインストール
$ vi dbadm.te $ make -f /usr/share/selinux/devel/Makefile dbadm.pp find: `~.doc': No such file or directory Compiling targeted dbadm module /usr/bin/checkmodule: loading policy configuration from tmp/dbadm.tmp /usr/bin/checkmodule: policy configuration loaded /usr/bin/checkmodule: writing binary representation (version 10) to tmp/dbadm.mod Creating targeted dbadm.pp policy package rm tmp/dbadm.mod tmp/dbadm.mod.fc $ su Password: # semodule -i dbadm.pp # semodule -l | grep dbadm dbadm 1.1.0
OK。これで下準備は終わり。
後々のFedora/RedHatELのアップデートでは、この辺の下準備は必要なくなると思う。
次いで、SELinuxユーザとロールとの関連付けを行う。
SELinuxユーザというのは、UNIXユーザとロールに対してN:Mの対応付けを行うための抽象的な識別子で、あるロールの組(例:foo_r var_r baz_r)に対してUNIXユーザ(例:hoge monu)を対応させる場合に、1個のSELinuxユーザを定義してfoo_r var_r baz_rを紐付け、そこにhogeとmonuを関連付けてやる。
ここでは、sepgsql_uというSELinuxユーザを作成し、staff_r/dbadm_r/system_rを紐付けている。
- Rオプション以外はひとまず"おまじない"だと思ってほしい。
# semanage user -a -R "staff_r dbadm_r system_r" -P user \
-r s0-s0:c0.c1023 -L s0-s0:c0.c1023 sepgsql_u
次に、sepgsqlというUNIXユーザを、先ほど定義したsepgsql_uに関連付ける。
# semanage login -a -s sepgsql_u -r s0-s0:c0.c1023 sepgsql
最後に、sepgsql_uユーザがログイン時に利用するロールを指定する設定ファイルをコピーする。
今回の場合は、staff_uと全く同じなので編集の必要はなし。
# cp /etc/selinux/targeted/contexts/users/staff_u \ /etc/selinux/targeted/contexts/users/sepgsql_u
では、sepgsqlユーザでログインしてみよう。
[root@masu ~]# ssh sepgsql@localhost sepgsql@localhost's password: Last login: Sat Apr 24 11:32:56 2010 from localhost [sepgsql@masu ~]$ id -Z sepgsql_u:staff_r:staff_t:s0-s0:c0.c1023
OK、sepgsqlでログインすると、SELinuxユーザはsepgsql_uで、ロール/ドメインはstaff_rになっている。
続いて、sepostgresqlデーモンを起動/停止するためのsudoを設定する。
echo "sepgsql ALL=(ALL) ROLE=dbadm_r TYPE=dbadm_t NOPASSWD:/sbin/service" >> /etc/sudoers
ROLE= とか TYPE= はSELinux用の拡張で、sudoする時にロールやドメインを切り替える。この場合、dbadm_r/dbadm_tに切り替える。
では、sepostgresqlを初期化/起動してみる。
[sepgsql@masu ~]$ sudo service sepostgresql initdb Initializing database: [ OK ] [sepgsql@masu ~]$ sudo service sepostgresql start Starting sepostgresql service: [ OK ] [sepgsql@masu ~]$ ps -AZ | grep sepostgres sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19695 ? 00:00:01 sepostgres sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19697 ? 00:00:00 sepostgres sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19698 ? 00:00:00 sepostgres sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19699 ? 00:00:00 sepostgres sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19700 ? 00:00:00 sepostgres sepgsql_u:system_r:postgresql_t:s0-s0:c0.c1023 19701 ? 00:00:00 sepostgres
OK、無事に起動しているのがわかる。
定義済み boolean の設定しだいでは、dbadm_u ロールにはユニークな権限を持たせることができる。その辺の解説はまた後日。