tanke25616429のアウトプット

IT技術の基本を勉強したことをアウトプットします。Linux、Kubernetes、クラウド中心です。百番煎じくらいだけど誰かの役に立てばそれはそれでうれしい。

SELinuxの基本

SELinuxとは

Linuxのセキュリティ機構。通常のLinuxパーミッションの仕組みより細かい権限管理を集中管理でできるようにしている。

権限管理は、何(権限管理対象)に対して、誰(識別方法)が、どのようなことができる(操作)かを規定する。この観点で、パーミッションSELinuxの比較は以下。

  • パーミッション
    • 権限管理の対象 : ファイルとプロセス等
    • 識別方法 : uid, gid
    • 操作 : r (read), w (write), x(execute)
  • SELinux
    • 権限管理の対象 : オブジェクトクラス(ファイル、プロセス、ソケット、 TCP/UDP ポート、共有メモリ、パイプ等のOS が提供するリソースやSELinux 対応アプリケーションが管理するdbus, systemd のサービス等のリソース)
    • 識別方法 : タイプ(ファイル、ディレクトリ、デバイスといったシステムリソースに付与されるラベル)*1
    • 操作:オブジェクトクラスごとに定義された細かい操作

セキュリティコンテキスト

セキュリティコンテキストとはファイル、プロセス、ユーザといったリソースに付与されるラベルのこと。ユーザ識別子:ロール識別子:タイプ(ドメイン)識別子:レベルというフォーマットで示される。lsidps等のコマンドに-Zを付与することで確認できる。

[root@kvm-centos8 ~]# ls -lZ /etc/bashrc
-rw-r--r--. 1 root root system_u:object_r:etc_t:s0 3019 May 15  2020 /etc/bashrc

動作モード

SELinuxには3つの動作モード、Enforcing, Permissive, Disabledがある。

  • Enforcing SELinuxが有効であり、アクセス制御に違反する操作は拒否されるモード。監査ログにも記録される。

  • Permissive SELinuxが有効であるが、アクセス制御に違反する操作は監査ログに記録されるのみで拒否されない。

  • Disabled SELinuxが無効の状態である。

現在のモードはgetenforceコマンドで確認できる。一時的にモードを変更する場合(例えばSELinuxトラブルシューティングのためEnforcing→Permissiveと変更する等)は、setenforceコマンドを使う。

[root@kvm-centos8 ~]# getenforce
Enforcing
[root@kvm-centos8 ~]# setenforce
usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]
[root@kvm-centos8 ~]# setenforce 0
[root@kvm-centos8 ~]# getenforce
Permissive

再起動後も永続的にモードを変更したい場合は、/etc/selinux/configSELINUX=の行を書き換える。反映にはシステム再起動が必要。

[root@kvm-centos8 ~]# vi /etc/selinux/config
[root@kvm-centos8 ~]# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
#SELINUX=permissive
# SELINUXTYPE= can take one of these three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

論理パラメータ

ある目的に必要なルールを 1 つにまとめた2値のパラメータで*2、これを変更することでポリシーが適用できる範囲を調整できる。例えば、Webサーバにおいてユーザのホームディレクトリを公開する際のケースを考える。その場合、Apache HTTP Serverのプロセスがユーザーのホームディレクトリにアクセスしてよいかどうか、というポリシー(httpd_enable_homedirs)がありこれが論理パラメータの1つの例である。 SELinuxのルールでこれが禁止されている場合は、たとえパーミッションで許可されていてもアクセスは許可されない。

以下に操作例を示す。SELinuxにおいて、Apache HTTP Serverがホームディレクトリにアクセスすることが許可されていれば特定のファイル(/home/testuser/www/index.html)が表示され、アクセスが許可されていなければデフォルトのファイルが表示されるというシナリオを考える。

準備

ホームディレクトリの配下に以下のファイルを用意する。

[root@nuc-centos8 ~]# vi /home/testuser/www/index.html
[root@nuc-centos8 ~]# cat /home/testuser/www/index.html
Httpd process can access homedir!

Apache HTTP Serverの設定を書き換える。

[root@nuc-centos8 ~]# cat /etc/httpd/conf/httpd.conf
(省略)
#DocumentRoot "/var/www/html"
DocumentRoot "/home/testuser/www"

#
# Relax access to content within /var/www.
#
#<Directory "/var/www">
<Directory "/home/testuser/www"> # 書き換え
    AllowOverride None
    # Allow open access:
    Require all granted
</Directory>

#<Directory "/var/www/html">
<Directory "/home/testuser/www"> # 書き換え
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options
    # for more information.
    #
    Options Indexes FollowSymLinks

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride None

    #
    # Controls who can get stuff from this server.
    #
    Require all granted
</Directory>
(省略)

書き換え後にhttpdをリスタートして設定ファイルを反映しておく。

[root@nuc-centos8 ~]# systemctl restart httpd

また、この時点でのSELinuxがEnforcingになっていることを確認する。

[root@nuc-centos8 ~]# getenforce
Enforcing

動作確認

論理パラメータhttpd_enable_homedirsの値を確認する。

[root@nuc-centos8 ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off

offになっているため、ホームディレクトリへのApache HTTP Serverのアクセスはできない。curlで確認する。文字化けしているが、デフォルトのファイルが表示されていることがわかる。

[root@nuc-centos8 ~]# curl http://localhost
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE HTML>
<html lang="en">
  <head>
    <title>CentOS 提供的 Apache HTTP 服?器???</title>
    <meta charset="utf-8"/>
(省略)

論理パラメータhttpd_enable_homedirsの値を変更する。

[root@nuc-centos8 ~]# setsebool httpd_enable_homedirs on
[root@nuc-centos8 ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on

on に変更したためホームディレクトリに配置したファイルにアクセスできていることがわかる。

[root@nuc-centos8 ~]# curl http://localhost
Httpd process can access homedir!

もう一度、論理パラメータをoffに戻し、今度はSELinuxをPermissiveに変更する。

[root@nuc-centos8 ~]# setsebool httpd_enable_homedirs off
[root@nuc-centos8 ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off
[root@nuc-centos8 ~]# setenforce
usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]
[root@nuc-centos8 ~]# setenforce 0
[root@nuc-centos8 ~]# getenforce
Permissive

SELinuxがPermissiveなので、ルール違反の処理(Apache HTTP Serverのホームディレクトリへのアクセス)があっても拒否はされない。

[root@nuc-centos8 ~]# curl http://localhost
Httpd process can access homedir!

監査ログにはこのアクセスは記録されていることがわかる。

[root@nuc-centos8 ~]# tail -f /var/log/audit/audit.log
(省略)
type=AVC msg=audit(1613982582.096:66562): avc:  denied  { getattr } for  pid=170913 comm="httpd" path="/home/testuser/www/index.html" dev="dm-5" ino=139 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:httpd_user_content_t:s0 tclass=file permissive=1
type=AVC msg=audit(1613982582.096:66563): avc:  denied  { read } for  pid=170913 comm="httpd" name="index.html" dev="dm-5" ino=139 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:httpd_user_content_t:s0 tclass=file permissive=1
(省略)

ポリシータイプ

タイプ(ドメイン)がシステムリソースをどのように利用できるかを定義したアクセス制御のセットをポリシーと呼ぶ。ポリシーには複数の種類がある。以下は例である。

  • targeted ポリシー
  • minimumポリシー
  • mlsポリシー

CentOSではtargetedポリシーがデフォルトで採用されている。それ以外のポリシーを利用する場合は別途インストールするか、自作のポリシーを用意する必要がある。

以下はminimumポリシーを導入する実行例である。 最初の時点ではtargetedポリシーしか存在しない。

[root@virtualbox-centos7 ~]# ls /etc/selinux/
config  final  semanage.conf  targeted  tmp
[root@virtualbox-centos7 ~]# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

後で突き合わせるため、論理パラメータの一覧をテキストに保存しておく。

[root@virtualbox-centos7 ~]# getsebool -a > targeted.txt

minimumモードをインストールし、設定ファイルを書き換え、システムを再起動する。

[root@virtualbox-centos7 ~]# yum install -y selinux-policy-minimum
(省略)
依存性を更新しました:
  selinux-policy.noarch 0:3.13.1-268.el7_9.2
  selinux-policy-targeted.noarch 0:3.13.1-268.el7_9.2

完了しました!
[root@virtualbox-centos7 ~]# vi /etc/selinux/config
[root@virtualbox-centos7 ~]# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
#SELINUXTYPE=targeted
SELINUXTYPE=minimum #書き換え
[root@virtualbox-centos7 ~]# reboot

再起動後、sestatusコマンドでモードを確認する*3

[root@virtualbox-centos7 ~]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             minimum
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      31

minimumモードとtargetedモードで論理パラメータの違いを比較する。on/offの違いのある個所もあるが(httpd_dbus_avahi等)、そもそも論理パラメータの数がtargetedモードのほうが多いことがわかる(+のついている行)。

[root@virtualbox-centos7 ~]# getsebool -a > minimum.txt
[root@virtualbox-centos7 ~]# diff -u minimum.txt targeted.txt
--- minimum.txt 2021-02-22 08:21:28.417891542 +0000
+++ targeted.txt        2021-02-21 21:22:37.463692100 +0000
@@ -1,20 +1,85 @@
+abrt_anon_write --> off
+abrt_handle_event --> off
+abrt_upload_watch_anon_write --> on
+antivirus_can_scan_system --> off
+antivirus_use_jit --> off
 auditadm_exec_content --> on
 authlogin_nsswitch_use_ldap --> off
 authlogin_radius --> off
 authlogin_yubikey --> off
+awstats_purge_apache_log_files --> off
+boinc_execmem --> on
+cdrecord_read_content --> off
+cluster_can_network_connect --> off
+cluster_manage_all_files --> off
+cluster_use_execmem --> off
+cobbler_anon_write --> off
+cobbler_can_network_connect --> off
+cobbler_use_cifs --> off
+cobbler_use_nfs --> off
+collectd_tcp_network_connect --> off
+condor_tcp_network_connect --> off
+conman_can_network --> off
+conman_use_nfs --> off
+container_connect_any --> off
+cron_can_relabel --> off
+cron_system_cronjob_use_shares --> off
+cron_userdomain_transition --> on
+cups_execmem --> off
+cvs_read_shadow --> off
 daemons_dump_core --> off
 daemons_enable_cluster_mode --> off
 daemons_use_tcp_wrapper --> off
 daemons_use_tty --> off
+dbadm_exec_content --> on
+dbadm_manage_user_files --> off
+dbadm_read_user_files --> off
 deny_execmem --> off
 deny_ptrace --> off
 dhcpc_exec_iptables --> off
+dhcpd_use_ldap --> off
 domain_can_mmap_files --> on
 domain_can_write_kmsg --> off
 domain_fd_use --> on
 domain_kernel_load_modules --> off
+entropyd_use_audio --> on
+exim_can_connect_db --> off
+exim_manage_user_files --> off
+exim_read_user_files --> off
+fcron_crond --> off
+fenced_can_network_connect --> off
+fenced_can_ssh --> off
 fips_mode --> on
+ftpd_anon_write --> off
+ftpd_connect_all_unreserved --> off
+ftpd_connect_db --> off
+ftpd_full_access --> off
+ftpd_use_cifs --> off
+ftpd_use_fusefs --> off
+ftpd_use_nfs --> off
+ftpd_use_passive_mode --> off
+ganesha_use_fusefs --> off
+git_cgi_enable_homedirs --> off
+git_cgi_use_cifs --> off
+git_cgi_use_nfs --> off
+git_session_bind_all_unreserved_ports --> off
+git_session_users --> off
+git_system_enable_homedirs --> off
+git_system_use_cifs --> off
+git_system_use_nfs --> off
+gitosis_can_sendmail --> off
+glance_api_can_network --> off
+glance_use_execmem --> off
+glance_use_fusefs --> off
 global_ssp --> off
+gluster_anon_write --> off
+gluster_export_all_ro --> off
+gluster_export_all_rw --> on
+gluster_use_execmem --> off
+gpg_web_anon_write --> off
+gssd_read_tmp --> on
+guest_exec_content --> on
+haproxy_connect_any --> off
 httpd_anon_write --> off
 httpd_builtin_scripting --> on
 httpd_can_check_spam --> off
@@ -28,14 +93,14 @@
 httpd_can_network_memcache --> off
 httpd_can_network_relay --> off
 httpd_can_sendmail --> off
-httpd_dbus_avahi --> on
+httpd_dbus_avahi --> off
 httpd_dbus_sssd --> off
 httpd_dontaudit_search_dirs --> off
 httpd_enable_cgi --> on
 httpd_enable_ftp_server --> off
 httpd_enable_homedirs --> off
 httpd_execmem --> off
-httpd_graceful_shutdown --> off
+httpd_graceful_shutdown --> on
 httpd_manage_ipa --> off
 httpd_mod_auth_ntlm_winbind --> off
 httpd_mod_auth_pam --> off
@@ -57,58 +122,195 @@
 httpd_use_openstack --> off
 httpd_use_sasl --> off
 httpd_verify_dns --> off
-kerberos_enabled --> off
+icecast_use_any_tcp_ports --> off
+irc_use_any_tcp_ports --> off
+irssi_use_full_network --> off
+kdumpgui_run_bootloader --> off
+keepalived_connect_any --> off
+kerberos_enabled --> on
+ksmtuned_use_cifs --> off
+ksmtuned_use_nfs --> off
 logadm_exec_content --> on
 logging_syslogd_can_sendmail --> off
 logging_syslogd_run_nagios_plugins --> off
 logging_syslogd_use_tty --> on
 login_console_enabled --> on
+logrotate_read_inside_containers --> off
+logrotate_use_nfs --> off
+logwatch_can_network_connect_mail --> off
+lsmd_plugin_connect_any --> off
+mailman_use_fusefs --> off
+mcelog_client --> off
+mcelog_exec_scripts --> on
+mcelog_foreground --> off
+mcelog_server --> off
+minidlna_read_generic_user_content --> off
 mmap_low_allowed --> off
-mount_anyfile --> off
+mock_enable_homedirs --> off
+mount_anyfile --> on
+mozilla_plugin_bind_unreserved_ports --> off
+mozilla_plugin_can_network_connect --> off
+mozilla_plugin_use_bluejeans --> off
+mozilla_plugin_use_gps --> off
+mozilla_plugin_use_spice --> off
+mozilla_read_content --> off
+mpd_enable_homedirs --> off
+mpd_use_cifs --> off
+mpd_use_nfs --> off
+mplayer_execstack --> off
+mysql_connect_any --> off
+nagios_run_pnp4nagios --> off
+nagios_run_sudo --> off
+nagios_use_nfs --> off
+named_tcp_bind_http_port --> off
+named_write_master_zones --> off
+neutron_can_network --> off
 nfs_export_all_ro --> on
 nfs_export_all_rw --> on
+nfsd_anon_write --> off
 nis_enabled --> off
+nscd_use_shm --> on
+openshift_use_nfs --> off
+openvpn_can_network_connect --> on
+openvpn_enable_homedirs --> on
+openvpn_run_unconfined --> off
+pcp_bind_all_unreserved_ports --> off
+pcp_read_generic_logs --> off
+piranha_lvs_can_network_connect --> off
+polipo_connect_all_unreserved --> off
+polipo_session_bind_all_unreserved_ports --> off
+polipo_session_users --> off
+polipo_use_cifs --> off
+polipo_use_nfs --> off
 polyinstantiation_enabled --> off
+postfix_local_write_mail_spool --> on
 postgresql_can_rsync --> off
 postgresql_selinux_transmit_client_label --> off
 postgresql_selinux_unconfined_dbadm --> on
 postgresql_selinux_users_ddl --> on
+pppd_can_insmod --> off
+pppd_for_user --> off
+privoxy_connect_any --> on
+prosody_bind_http_port --> off
+puppetagent_manage_all_files --> off
+puppetmaster_use_db --> off
 racoon_read_shadow --> off
+radius_use_jit --> off
+redis_enable_notify --> off
+rpcd_use_fusefs --> off
+rsync_anon_write --> off
+rsync_client --> off
+rsync_export_all_ro --> off
+rsync_full_access --> off
+samba_create_home_dirs --> off
+samba_domain_controller --> off
+samba_enable_home_dirs --> off
+samba_export_all_ro --> off
+samba_export_all_rw --> off
+samba_load_libgfapi --> off
+samba_portmapper --> off
+samba_run_unconfined --> off
+samba_share_fusefs --> off
+samba_share_nfs --> off
+sanlock_enable_home_dirs --> off
+sanlock_use_fusefs --> off
+sanlock_use_nfs --> off
+sanlock_use_samba --> off
+saslauthd_read_shadow --> off
 secadm_exec_content --> on
 secure_mode --> off
 secure_mode_insmod --> off
 secure_mode_policyload --> off
-selinuxuser_direct_dri_enabled --> off
+selinuxuser_direct_dri_enabled --> on
 selinuxuser_execheap --> off
-selinuxuser_execmod --> off
-selinuxuser_execstack --> off
+selinuxuser_execmod --> on
+selinuxuser_execstack --> on
 selinuxuser_mysql_connect_enabled --> off
-selinuxuser_ping --> off
+selinuxuser_ping --> on
 selinuxuser_postgresql_connect_enabled --> off
-selinuxuser_rw_noexattrfile --> off
+selinuxuser_rw_noexattrfile --> on
 selinuxuser_share_music --> off
 selinuxuser_tcp_server --> off
 selinuxuser_udp_server --> off
 selinuxuser_use_ssh_chroot --> off
+sge_domain_can_network_connect --> off
+sge_use_nfs --> off
+smartmon_3ware --> off
+smbd_anon_write --> off
+spamassassin_can_network --> off
+spamd_enable_home_dirs --> on
+spamd_update_can_network --> off
+squid_connect_any --> on
+squid_use_tproxy --> off
 ssh_chroot_rw_homedirs --> off
 ssh_keysign --> off
 ssh_sysadm_login --> off
 staff_exec_content --> on
 staff_use_svirt --> off
+swift_can_network --> off
 sysadm_exec_content --> on
-unconfined_chrome_sandbox_transition --> off
+telepathy_connect_all_ports --> off
+telepathy_tcp_connect_generic_network_ports --> on
+tftp_anon_write --> off
+tftp_home_dir --> off
+tmpreaper_use_cifs --> off
+tmpreaper_use_nfs --> off
+tmpreaper_use_samba --> off
+tomcat_can_network_connect_db --> off
+tomcat_read_rpm_db --> off
+tomcat_use_execmem --> off
+tor_bind_all_unreserved_ports --> off
+tor_can_network_relay --> off
+unconfined_chrome_sandbox_transition --> on
 unconfined_login --> on
-unconfined_mozilla_plugin_transition --> off
+unconfined_mozilla_plugin_transition --> on
 unprivuser_use_svirt --> off
 use_ecryptfs_home_dirs --> off
 use_fusefs_home_dirs --> off
-use_nfs_home_dirs --> on
+use_lpd_server --> off
+use_nfs_home_dirs --> off
 use_samba_home_dirs --> off
 user_exec_content --> on
+varnishd_connect_any --> off
+virt_read_qemu_ga_data --> off
+virt_rw_qemu_ga_data --> off
+virt_sandbox_use_all_caps --> on
+virt_sandbox_use_audit --> on
+virt_sandbox_use_fusefs --> off
+virt_sandbox_use_mknod --> off
+virt_sandbox_use_netlink --> off
+virt_sandbox_use_sys_admin --> off
+virt_transition_userdomain --> off
+virt_use_comm --> off
+virt_use_execmem --> off
+virt_use_fusefs --> off
+virt_use_glusterd --> off
+virt_use_nfs --> off
+virt_use_rawip --> off
+virt_use_samba --> off
+virt_use_sanlock --> off
+virt_use_usb --> on
+virt_use_xserver --> off
+webadm_manage_user_files --> off
+webadm_read_user_files --> off
+wine_mmap_zero_ignore --> off
 xdm_bind_vnc_tcp_port --> off
 xdm_exec_bootloader --> off
 xdm_sysadm_login --> off
 xdm_write_home --> off
+xen_use_nfs --> off
+xend_run_blktap --> on
+xend_run_qemu --> on
+xguest_connect_network --> on
+xguest_exec_content --> on
+xguest_mount_media --> on
+xguest_use_bluetooth --> on
 xserver_clients_write_xshm --> off
 xserver_execmem --> off
 xserver_object_manager --> off
+zabbix_can_network --> off
+zabbix_run_sudo --> off
+zarafa_setrlimit --> off
+zebra_write_config --> off
+zoneminder_anon_write --> off
+zoneminder_run_sudo --> off

参考にしたもの

www.slideshare.net

milestone-of-se.nesuke.com

www.shoeisha.co.jp

milestone-of-se.nesuke.com

CentOS 7 : SELinux : ポリシータイプの設定 : Server World

Apacheで403 Forbiddenが表示された時のチェックポイント5選 | Wedding Park CREATORS Blog

*1:プロセスに付与するラベルはタイプではなくドメインと呼ぶ。

*2:そのため、Booleanとも呼ぶ。

*3:書き換え前に確認するのを忘れてしまった……。