あずんひの日

あずんひの色々を書き留めるブログ

SELinuxでSambaとコンテナを共存させる

SELinuxの環境下でSambaとコンテナから同じディレクトリを扱う時、samba_share_tcontainer_file_tをそのディレクトリ以下に付ける必要があります。 ただしファイルに複数のラベルを付ける事はできず一筋縄では行きません。

これまではなあなあで対応してたんですが、今回まあまあちゃんと対応してみたので備忘録として残しておきます。

問題の整理

自分の場合は録画サーバーを構築しており、EPGStationで録画したファイルをSambaで共有しています。 EPGStationは令和の世ですからもちろんコンテナを使ってデプロイするわけですが、 コンテナのボリュームとしてマウントするディレクトリ以下にはcontainer_file_tというラベルを付ける必要があります。 同時にSambaで共有するディレクトリ以下にはsamba_share_tというラベルを付ける必要があります。

ただし、残念な事にSELinuxのラベルは複数付ける事ができません。 Sambaをコンテナにすればsamba_share_tの代わりにcontainer_file_tが要求されることになるので手っ取り早く解決はできるんですが、 Sambaのメジャーっぽいコンテナイメージであるdperson/sambaは執筆時点で最終更新が2021年4月でバージョンも4.12.2と古く、 Sambaは継続的に脆弱性が修正されているソフトウェアであることを考えると避けたいところです。 他にも色々イメージはあるようですが、いずれも非公式なためいつ更新が止まってもおかしくないですし、 できるだけディストロが配布しているSambaを使うべきでしょう。

container_file_tでSambaを共有する

と言うわけで、自分でモジュールを書いてSambaとコンテナを共存させます。 ちゃんとやるならsamba_share_tcontainer_file_tと「両対応のラベル」に分けるべきな気もしますが、 どうせ自宅サーバーなのでcontainer_file_tに統一し、Sambaもそれで共有できるようにします。

実際はsemanage permissiveとかausearchとかaudit2allowとか使ってなんやかんやしたんですが面倒なので省略します。 最終的にはFedoraのSELinuxポリシーを元にモジュールを書きました。

まずは以下のファイルをmy-samba.teとして保存します。

module my-samba 1.0;

require {
        type container_file_t;
        type smbd_t;

        class dir { create open getattr setattr read write link unlink rename search add_name remove_name reparent rmdir lock ioctl watch watch_reads };
        class file { create open getattr setattr read write append rename link unlink ioctl lock watch watch_reads map };
        class filesystem { getattr quotaget };
}

# https://github.com/fedora-selinux/selinux-policy/blob/f37/policy/support/obj_perm_sets.spt#L145
allow smbd_t container_file_t:dir { create open getattr setattr read write link unlink rename search add_name remove_name reparent rmdir lock ioctl watch watch_reads };
# https://github.com/fedora-selinux/selinux-policy/blob/f37/policy/support/obj_perm_sets.spt#L179
allow smbd_t container_file_t:file { create open getattr setattr read write append rename link unlink ioctl lock watch watch_reads };

# https://github.com/fedora-selinux/selinux-policy/blob/f37/policy/modules/contrib/samba.te#L330-L331
allow smbd_t container_file_t:file { map };
allow smbd_t container_file_t:filesystem { getattr quotaget };

そして下記コマンドを実行してモジュールをインストールします(RHEL系ならselinux-policy-develが必要)。

make -f /usr/share/selinux/devel/Makefile my-samba.pp
sudo semodule -i my-samba.pp

これでラベルが正しく設定されていればSambaとコンテナで同じディレクトリを扱えるようになるはずです。