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 ロールにはユニークな権限を持たせることができる。その辺の解説はまた後日。