tftpのルートディレクトリが変更できない?

vmserver(仮想マシンのホストマシン名)のルートファイルシステムの大きさは7GBしかない。現在約50%を使って残り3GBちょっとは残っているが、フンダンにあるわけではないので /ftfpboot を /home/TFTPboot へ引っ越そうと思った。簡単に出来る....
筈だった。

ディレクトリを用意しておいて、/etc/xinetd.d/tftp でルートパスを設定すればいい。

# default: off
# description: The tftp server serves files using the trivial file transfer \
#       protocol.  The tftp protocol is often used to boot diskless \
#       workstations, download configuration files to network-aware printers, \
#       and to start the installation process for some operating systems.
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -v -s /home/TFTPboot # ←ここを変更
        disable                 = no
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}

これで xinetdを再起動するだけで終わる筈だった。
ところが、また、上手く動かない。DHCPでアドレスは取得できるが、TFTPでPEXローダをダウンロードできない。
SELinuxが文句を言っている。SELinuxは本当に鬼門だ。今までSELinuxを避けて通って来たが、今回は無理そうだったので、仕方なくSELinuxについて調べてみた。(「第一人者がやさしく教える新SELinux入門」を参照した。私にとってはちょっと難しかったが。)

tftpdプロセスには tftpd_t というドメインが割り振られているが、どうもSELinuxのログによると /homeディレクトリの home_root_t というタイプにアクセスできないといっている。tftpd には /home ではなく /home/TFTPboot を指定しているのに。念のため /home/TFTPboot のラベルを確認してみると tftpdir_t となっていて、このタイプが割り振ってあれば tftpd_t からアクセスできる筈なのに。

# ls -aZ /home/TFTPboot/
drwxr-xr-x  root root system_u:object_r:tftpdir_t:s0   .
drwxr-xr-x  root root system_u:object_r:home_root_t:s0 ..
drwxr-xr-x  root root system_u:object_r:tftpdir_t:s0   bishop

tftpdがchrootをする際に、行き成り与えられたパスではなく、上位のディレクトリの情報を読んでいるらしい。

/homeのタイプをtftpdir_tにするわけにもいかない。(実験的に変えてみたが、するとtftpは使えてもsambaもvmwareもアクセスできなくなってしまった。)bool設定でも回避できない。あと残る手段としては、

  1. SELinuxを「enforcing」から「permissive」に変更する。
  2. tftpd_tドメインがhome_root_tタイプにアクセスできるようにローカルポリシーを設定する。

しかなさそうだ。おうちサーバだからセキュリティはそれ程高くする必要はない。しかしSELinuxをpermissiveにするのは、Linuxオタクとしては屈辱的である。ということで、初めてポリシーの作成したみた。

まず、適当な作業ディレクトリでTEファイルを作成する。一旦、SELinuxをpermissiveにしてtftpをかけて警告をださせる。その後でaudit2allowコマンドでTEファイルを作る。

# audit2allow -a -l -m vmserver > vmserver.te

# cat vmserver.te
module vmserver 1.0;

require {
        type home_root_t;
        type tftpd_t;
        class dir search;
}

#============= tftpd_t ==============
allow tftpd_t home_root_t:dir search;

tftpdが/home直下のファイルに対して自由に読み書きできるようになるのは宜しくないので、/homeというディレクトリの情報だけを読める(searchできる)ように設定する。

このTEファイルからバイナリのポリシーファイルを作成する。

# ls
vmserver.te

# make -f /usr/share/selinux/devel/Makefile
Compiling targeted vmserver module
/usr/bin/checkmodule:  loading policy configuration from tmp/vmserver.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 6) to tmp/vmserver.mod
Creating targeted vmserver.pp policy package
rm tmp/vmserver.mod.fc tmp/vmserver.mod

# ls
tmp  vmserver.fc  vmserver.if  vmserver.pp  vmserver.te

つぎにこのローカルポリシーvmserver.ppをシステムに登録する。

# semodlue -i vmserver.pp

さて、SELinuxをEnforcingに設定して、tftpをかけてみると見事に成功した。