gentoo で selinux を有効化する

以下の前提で始めます。

  • 正常稼働している gentoo をベースとする
  • systemd ではない sysvinit/openrc 環境をベースとする

インストール初っぱなから selinux プロファイルで始めるのは……やり方はあるのかもしれませんが、ちょっとしんどそうだったのでやめましたw また、現状の gentoo の selinux プロファイルはものすごい勢いで systemd をブロックしているため、sysvinit/openrc 環境でないとこれもシンドイと思います。

というワケで、例によって公式 gentoo wiki / SELinux/Installation を参考に進めていきます。

いきなり wiki と順番が違いますが、まず kernel オプションの設定から先にやってしまいます。やることは基本的に wiki にあるとおりです。

まず hardened-sources を emerge します。

# emerge -av hardened-sources

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild  N     ] sys-kernel/hardened-sources-4.8.17-r2:4.8.17-r2::gentoo  USE="-build -deblob -symlink" 0 KiB

Total: 1 package (1 new), Size of downloads: 0 KiB

Would you like to merge these packages? [Yes/No] y

symlink を張り替えます。

# eselect kernel list
Available kernel symlink targets:
  [1]   linux-4.8.17-hardened-r2
  [2]   linux-4.9.16-gentoo *
# eselect kernel set 1

もともと動いている kernel の .config をコピって使います。

# cp /usr/src/linux-4.9.16-gentoo/.config /usr/src/linux/.config
# cd /usr/src/linux
# make menuconfig

General setup

[*] Auditing support

wiki にある Enable system-call auditing support は hardened-sources-4.8.17-r2 の menuconfig では見つけられませんでしたが、/ で検索してみるとどうも有効になってはいるようです。

Symbol: AUDITSYSCALL [=y]
Type  : boolean
  Defined at init/Kconfig:321
  Depends on: AUDIT [=y] && HAVE_ARCH_AUDITSYSCALL [=y]

File systems

ここのオプションについてはとりあえずうちの環境で使用している ext4 の設定のみ有効化しました。

<*> The Extended 4 (ext4) filesystem
[*]   Use ext4 for ext2 file systems
[*]   Ext4 POSIX Access Control Lists
[*]   Ext4 Security Labels
[ ]   Ext4 Encryption
[ ]   EXT4 debugging support

要は Ext4 Security Labels が必要なんだと思います。

Security options

selinux 関連のパラメータを有効化します。

[*] Enable different security models

[*] Socket and Networking Security Hooks

[*] NSA SELinux Support
[ ]   NSA SELinux boot parameter
[ ]   NSA SELinux runtime disable
[*]   NSA SELinux Development Support
[*]   NSA SELinux AVC Statistics
(1)   NSA SELinux checkreqprot default value

    Default security module (SELinux)  --->

お馴染みの手順で kernel のビルドとインストールを実行します。

# make -j5 && make modules_install
# mount /boot
# cp /usr/src/linux/arch/x86_64/boot/bzImage /boot/kernel-4.9.16-gentoo.20170514.01
# grub-mkconfig -o /boot/grub/grub.cfg
# reboot

/etc/portage/make.conf に以下の設定を追記します。

POLICY_TYPES="strict"
USE="${USE} peer_perms open_perms ubac -unconfined"

wiki にあるとおりに /etc/fstab の /tmp と /run のマウントオプションを書き換えます。

tmpfs   /tmp    tmpfs   defaults,noexec,nosuid,rootcontext=system_u:object_r:tmp_t              0 0
tmpfs   /run    tmpfs   mode=0755,nosuid,nodev,rootcontext=system_u:object_r:var_run_t          0 0

それではプロファイルを切り替えます

# eselect profile list
Available profile symlink targets:
  [1]   default/linux/amd64/13.0 *
  [2]   default/linux/amd64/13.0/selinux
  [3]   default/linux/amd64/13.0/desktop
  [4]   default/linux/amd64/13.0/desktop/gnome
  [5]   default/linux/amd64/13.0/desktop/gnome/systemd
  [6]   default/linux/amd64/13.0/desktop/plasma
  [7]   default/linux/amd64/13.0/desktop/plasma/systemd
  [8]   default/linux/amd64/13.0/developer
  [9]   default/linux/amd64/13.0/no-multilib
  [10]  default/linux/amd64/13.0/systemd
  [11]  default/linux/amd64/13.0/x32
  [12]  hardened/linux/amd64
  [13]  hardened/linux/amd64/selinux
  [14]  hardened/linux/amd64/no-multilib
  [15]  hardened/linux/amd64/no-multilib/selinux
  [16]  hardened/linux/amd64/x32
  [17]  hardened/linux/musl/amd64
  [18]  hardened/linux/musl/amd64/x32
  [19]  default/linux/uclibc/amd64
  [20]  hardened/linux/uclibc/amd64

いま [1] のいたって普通のプロファイルが選択されているので、これを selinux のプロファイルに切り替えます。

# eselect profile set 2

確認します。

# eselect profile list
Available profile symlink targets:
  [1]   default/linux/amd64/13.0
  [2]   default/linux/amd64/13.0/selinux *
  [3]   default/linux/amd64/13.0/desktop
  [4]   default/linux/amd64/13.0/desktop/gnome
  [5]   default/linux/amd64/13.0/desktop/gnome/systemd
  [6]   default/linux/amd64/13.0/desktop/plasma
  [7]   default/linux/amd64/13.0/desktop/plasma/systemd
  [8]   default/linux/amd64/13.0/developer
  [9]   default/linux/amd64/13.0/no-multilib
  [10]  default/linux/amd64/13.0/systemd
  [11]  default/linux/amd64/13.0/x32
  [12]  hardened/linux/amd64
  [13]  hardened/linux/amd64/selinux
  [14]  hardened/linux/amd64/no-multilib
  [15]  hardened/linux/amd64/no-multilib/selinux
  [16]  hardened/linux/amd64/x32
  [17]  hardened/linux/musl/amd64
  [18]  hardened/linux/musl/amd64/x32
  [19]  default/linux/uclibc/amd64
  [20]  hardened/linux/uclibc/amd64

wiki に記載あるとおりにします。

# emerge -av -1 checkpolicy policycoreutils

どんどん行きます。

# FEATURES="-selinux" emerge -av -1 selinux-base

ここで FEATURES="-selinux" とするのは、いまはまだ導入段階で selinux 環境になっていないから……だと思います。

selinux の設定ファイル

/etc/selinux/config なんてファイルができています。

# This file controls the state of SELinux on the system on boot.

# 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=permissive

# SELINUXTYPE can take one of these four values:
#       targeted - Only targeted network daemons are protected.
#       strict   - Full SELinux protection.
#       mls      - Full SELinux protection with Multi-Level Security
#       mcs      - Full SELinux protection with Multi-Category Security
#                  (mls, but only one sensitivity level)
SELINUXTYPE=strict

とりあえず特に変更をせず、このままで行きます。もしここで設定を変更した場合は、もう一度 selinux-baseemerge する必要があるようです。

# FEATURES="-selinux -sesandbox" emerge -av -1 selinux-base

続いていきます。

# FEATURES="-selinux -sesandbox" emerge -av selinux-base-policy

ここまでで selinux の環境はセットアップ完了なんだと思います。次は各ソフトウェアを selinux に対応させます。

# emerge -uavDN @world

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R    ] sys-apps/opentmpfiles-0.1.3::gentoo  USE="(selinux*)" 0 KiB
[ebuild   R    ] sys-apps/sed-4.2.2::gentoo  USE="acl nls (selinux*) -static" 0 KiB
[ebuild   R    ] sys-apps/coreutils-8.25::gentoo  USE="acl nls (selinux*) xattr -caps -gmp -hostname -kill -multicall -static -vanilla" 0 KiB
[ebuild   R    ] app-arch/tar-1.29-r1::gentoo  USE="acl nls (selinux*) xattr -minimal -static" 0 KiB
[ebuild   R    ] sys-apps/findutils-4.6.0-r1::gentoo  USE="nls (selinux*) -static {-test}" 0 KiB
[ebuild   R    ] sys-apps/busybox-1.25.1::gentoo  USE="ipv6 (selinux*) static -debug -livecd -make-symlinks -math -mdev -pam -savedconfig -sep-usr -syslog (-systemd)" 0 KiB
[ebuild   R    ] sys-apps/portage-2.3.5::gentoo  USE="(ipc) native-extensions (selinux*) xattr -build -doc -epydoc" LINGUAS="-ru" PYTHON_TARGETS="python2_7 python3_4 (-pypy) (-python3_5) (-python3_6)" 0 KiB
[ebuild   R    ] sys-process/psmisc-22.21-r3::gentoo  USE="ipv6 nls (selinux*) -X" 0 KiB
[ebuild   R    ] sys-libs/pam-1.2.1::gentoo  USE="berkdb cracklib nls pie (selinux*) -audit -debug -nis {-test} -vim-syntax" ABI_X86="(64) -32 (-x32)" 0 KiB
[ebuild   R    ] sys-auth/pambase-20150213::gentoo  USE="cracklib nullok (selinux*) sha512 -consolekit -debug -gnome-keyring -minimal -mktemp -pam_krb5 -pam_ssh -passwdqc -securetty (-systemd)" 0 KiB
[ebuild   R    ] sys-apps/shadow-4.4-r2::gentoo  USE="acl cracklib nls pam (selinux*) xattr -audit -skey" LINGUAS="ja -cs -da -de -es -fi -fr -hu -id -it -ko -pl -pt_BR -ru -sv -tr -zh_CN -zh_TW" 0 KiB
[ebuild   R    ] app-editors/vim-8.0.0386::gentoo  USE="acl nls (selinux*) -X -cscope -debug -gpm -lua -luajit -minimal -perl -python -racket -ruby -tcl -vim-pager" PYTHON_TARGETS="python2_7 python3_4 (-python3_5) (-python3_6)" 0 KiB
[ebuild  N     ] sec-policy/selinux-openrc-2.20170204-r2::gentoo  0 KiB
[ebuild  N     ] sec-policy/selinux-shutdown-2.20170204-r2::gentoo  0 KiB
[ebuild  N     ] sec-policy/selinux-rpcbind-2.20170204-r2::gentoo  0 KiB
[ebuild  N     ] sec-policy/selinux-rpc-2.20170204-r2::gentoo  0 KiB
[ebuild  N     ] sec-policy/selinux-mandb-2.20170204-r2::gentoo  0 KiB
[ebuild   R    ] sys-apps/sysvinit-2.88-r9::gentoo  USE="(selinux*) (-ibm) -static" 0 KiB
[ebuild   R    ] sys-apps/util-linux-2.28.2::gentoo  USE="cramfs ncurses nls pam readline (selinux*) suid unicode -build -caps -fdformat -kill -python -slang -static-libs (-systemd) {-test} -tty-helpers -udev" ABI_X86="(64) -32 (-x32)" PYTHON_SINGLE_TARGET="python3_4 -python2_7 (-python3_5) (-python3_6)" PYTHON_TARGETS="python2_7 python3_4 (-python3_5) (-python3_6)" 0 KiB
[ebuild   R    ] sys-libs/glibc-2.23-r3:2.2::gentoo  USE="(multilib) rpc (selinux*) -audit -caps -debug -gd -hardened -nscd -profile -suid -systemtap -vanilla" 0 KiB
[ebuild   R    ] sys-apps/openrc-0.24.2::gentoo  USE="ncurses netifrc pam (selinux*) unicode -audit -debug -newnet (-prefix) -static-libs" 0 KiB
[ebuild   R    ] sys-apps/net-tools-1.60_p20160215155418::gentoo  USE="arp hostname ipv6 nls (selinux*) -nis -plipconfig -slattach -static" 0 KiB
[ebuild   R    ] sys-process/procps-3.3.12:0/5::gentoo  USE="kill ncurses nls (selinux*) unicode -modern-top -static-libs (-systemd) {-test}" 0 KiB
[ebuild   R    ] net-nds/rpcbind-0.2.4-r1::gentoo  USE="(selinux*) tcpd -debug (-systemd) -warmstarts" 0 KiB
[ebuild   R    ] sys-apps/man-db-2.7.6.1-r2::gentoo  USE="berkdb gdbm manpager nls (selinux*) zlib -static-libs" 0 KiB
[ebuild   R    ] net-misc/openssh-7.3_p1-r7::gentoo  USE="hpn pam pie (selinux*) ssl -X -X509 -bindist -debug -kerberos -ldap -ldns -libedit (-libressl) -livecd -sctp -skey -ssh1 -static {-test}" 0 KiB
[ebuild   R    ] sys-apps/iproute2-4.4.0::gentoo  USE="berkdb iptables ipv6 (selinux*) -atm -minimal" 0 KiB
[ebuild   R    ] net-fs/nfs-utils-1.3.4::gentoo  USE="ipv6 libmount nfsidmap nfsv4 (selinux*) tcpd uuid -caps -kerberos -nfsdcld -nfsv41" 0 KiB
[ebuild   R    ] dev-libs/glib-2.50.3-r1:2::gentoo  USE="mime (selinux*) xattr -dbus -debug (-fam) -static-libs -systemtap {-test} -utils" ABI_X86="(64) -32 (-x32)" PYTHON_TARGETS="python2_7" 0 KiB
[ebuild   R    ] sys-fs/eudev-3.1.5::gentoo  USE="hwdb kmod (selinux*) -introspection -rule-generator -static-libs {-test}" ABI_X86="(64) -32 (-x32)" 0 KiB

Total: 30 packages (5 new, 25 reinstalls), Size of downloads: 0 KiB

Would you like to merge these packages? [Yes/No] y

また多い……しばし休憩ですw

……というわけで、無事完了したら一度 reboot します。

# reboot

再起動後は、ある程度ですが selinux ぽい動作が確認できます。例えば。

# /etc/init.d/sshd restart
Authenticating root.
Password:
 * Stopping sshd ...                                      [ ok ]
 * Starting sshd ...                                      [ ok ]

てな感じでパスワード入力を求められたりします。

全てのデバイスと openrc 関連ファイルに、セキュリティラベルを設定する作業……らしいです。ごめんなさい、まだあんまりよくわかってませんw

/dev と /lib64 (と /lib32?)

まずルートパーティションを bind でマウントします。

# mkdir /mnt/gentoo
# mount -o bind / /mnt/gentoo

/dev と /lib64 下のファイルにラベル付けするようです。恐らく、/etc/selinux/config で SELINUXTYPE=targeted とした場合は、次のコマンドの file_contexts のパスは /etc/selinux/targeted/contexts/files/file_contexts になるものと思います。

また、32bit 環境の場合は /mnt/gentoo/lib64 ではなく /mnt/gentoo/lib を指定するらしいことが wiki に書いてありますね。……これ multilib 環境の場合は /mnt/gentoo/lib32 に対しても実行した方が良いんでしょうか?

# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/dev
# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/lib64
# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/lib32

とりあえずこんな感じで実行しておきました。

# umount /mnt/gentoo

swap ファイル

うちの環境は swap はパーティションを使用しているため wiki に載っているこの手順は実行してません。

#semanage fcontext -a -t swapfile_t "/swapfile"
#restorecon /swapfile

ファイルシステム全体のラベル付け

kernel に設定した Ext4 Security Labels あたりが関連してそうですね……

# rlpkg -a -r
Relabeling filesystem types: btrfs encfs ext2 ext3 ext4 ext4dev f2fs gfs gfs2 gpfs jffs2 jfs lustre xfs zfs
Running /usr/sbin/setfiles -F /etc/selinux/strict/contexts/files/file_contexts / /var /var/tmp /usr/src /root
Scanning for shared libraries with text relocations...
0 libraries with text relocations, 0 not relabeled.
Scanning for PIE binaries with text relocations...
0 binaries with text relocations detected.

……結果的に、うちの環境の場合はやらなくても良かったかもですねw 要は、先の手順で / のファイルシステムにたいしてラベル付けをしました。あとは別のパーティションを切っているファイルシステムに対してもラベル付けをしましょう、ということなのかな。

reboot

ここまでやったらもう一度 reboot します。

# reboot

再起動完了後にポリシールールの変更……すべてのドメインが /dev/urandom に読み取りアクセスできるように変更……するようですw

# setsebool -P global_ssp on

gentoo で selinux を有効化する……という意味では、ここまでで有効になっています。ここから先は selinux そのものの操作になるので、この記事ではここまでにしておきます……というか、筆者も勉強しないとわからないw

ちなみに 本家 wiki ではもうちょっと先の管理者アカウント設定とか、そのへんまで踏み込んでいるので、もう少し先まで設定する場合は本家 wiki を参照してください。

ここまでの状態だと、/etc/selinux/config で SELINUX=permissive としているので、エラーメッセージは出力されますが大抵のことは問題なくできますよね。emerge とか。

そこで SELINUX=enforcing とするとどうなるか……恒久的に変更する場合は /etc/selinux/config の記載内容を変更1)しますが、手っ取り早くコマンドで変更できるようです。

# getenforce
Permissive
# setenforce 1
# getenforce
Enforcing

permissive に戻す場合は setenforce 0 を実行します。ある程度ちゃんと selinux 環境を設定しないと setenforce が打てなくなりますw tty から reboot して元に戻しました……。

さて enforcing の状態で emerge を実行すると……

# emerge -av gentoolkit
Permission denied: '/etc/portage/make.conf'
# ls -Z /etc/portage/make.conf
ls: cannot access '/etc/portage/make.conf': Permission denied

root でもこの有様ですw 対処の方法は本家 wiki の 'Define the administrator accounts' に記載されています。

semanage とかは python2.7 を使わないとうまく動かないようです。

# semanage login -a -s staff_u newuser
libsemanage.dbase_llist_query: could not query record value
OSError: [Errno 0] Error

こんな感じにしたら wiki に載ってる semanage user -m -R "staff_r sysadm_r system_r" root とかも色々動くようになりました。

# eselect python list
Available Python interpreters, in order of preference:
  [1]   python3.4
  [2]   python2.7 (fallback)
# eselect python set 2
# eselect python list
Available Python interpreters, in order of preference:
  [1]   python2.7
  [2]   python3.4
1)
危険です……
https://manimani.cc/lib/plugins/linkback/exe/trackback.php/wiki:linux:gentoo_with_selinux