面 和毅
Using ACL FILE: /etc/lids/lids.conf
LIST
effective capability = 0x00000000
Subject ACCESS inherit time Object
----------------------------------------------------------------------------
Any file READONLY: 0 0000-0000 /sbin 0
Any file READONLY: 0 0000-0000 /bin 0
Any file READONLY: 0 0000-0000 /boot 0
Any file READONLY: 0 0000-0000 /lib 0
Any file READONLY: 0 0000-0000 /usr 0
Any file READONLY: 0 0000-0000 /var 0
Any file READONLY: 0 0000-0000 /tmp 0
Any file READONLY: 0 0000-0000 /etc 0
Any file DENY: 0 0000-0000 /etc/lids 0
Any file DENY: 0 0000-0000 /etc/shadow 0
Any file APPEND: 0 0000-0000 /var/log 0
Any file WRITE: 0 0000-0000 /var/log/wtmp 0
/bin/login READONLY: 0 0000-0000 /etc/shadow 0
/bin/su READONLY: 0 0000-0000 /etc/shadow 0
Any file READONLY: 0 0000-0000 /usr/local/etc 0
/bin/su GRANT: 0 0000-0000 CAP_SETUID 0
/bin/su GRANT: 0 0000-0000 CAP_SETGID 0
Any file READONLY: 0 0000-0000 /root 0
Any file READONLY: 0 0000-0000 /root/.bash_history 0
/bin/login WRITE: 0 0000-0000 /var/log/wtmp 0
/bin/login WRITE: 0 0000-0000 /var/log/lastlog 0
/sbin/init GRANT: 0 0000-0000 CAP_KILL 0
/etc/rc.d/init.d/halt GRANT: 1 0000-0000 CAP_KILL 0
/etc/rc.d/init.d/halt GRANT: 1 0000-0000 CAP_NET_ADMIN 0
/etc/rc.d/init.d/halt GRANT: 1 0000-0000 CAP_SYS_ADMIN 0
Any file READONLY: 0 0000-0000 /home/omok 0
/bin/bash APPEND: 0 0000-0000 /home/omok/.bash_history 0
となっています。この状態で、次の簡単なテストスクリプトを走らせます。
----------------------------/tmp/testwrite.sh------------------------ #!/bin/sh cp /tmp/tmpfile /var/tmp ----------------------------------------------------------------------
# lidsadm -S -- -LIDS_GLOBALで、LFS に移動し
lfs# lidsconf -A -s /tmp/tempwrite.sh -o /var/tmp -j WRITEとします。
lfs# lidsconf -Lとすると、一番最後の行(最後に加えたACL が最下段に表示されます)に
/tmp/testwrite.sh WRITE: 0 0000-0000 /var/tmp 0
が追加されます。
これで/tmp/testwrite.sh が正常に走るのでしょうか? 実行してみましょう。
lfs# lidsadm -S -- +LIDS_GLOBAL # /tmp/testwrite.sh cp: cannot create regular file `/var/tmp/tmpfile': Operation not permittedというエラーが出て来ます。/var/log/messages を見てみると
Jan 28 01:00:28 nemesis kernel: LIDS: cp (dev 3:68 inode 289112) pid 1301 ppid 1300 uid/gid (0/0) on (pts) : Attempt to open /var/tmp/tmpfile for writing,flag=32834このログから、/tmp/testwrite.sh のシェルスクリプト内にあるcp コマンドが呼び出された時に、 /var/tmp/tmpfile という宛先にファイルを書き込みすることができない(書き込みの許可が与えられていない)ことが分かります。 つまり、元のプログラム(Subject)に対してACL を与えても、そのプログラムから呼び出される子プロセスに対しては、今の場合ACL が適用されないということになります。 これを解決させるためには、どうすれば良いでしょうか? /bin/cp にも/var/tmp にたいして書き込み権限を与えると言うのが、ひとつの方法です。 しかし、それですと、不適切なプログラムから/bin/cp が呼び出された時にも、 /var/tmp に書き込みを行ってしまいます。 この問題を解決するために、LIDS ではACL の継承という概念が導入されています。
LIDS でセットアップしたACL は、親プロセスがプログラム中で子プロセスを生成した時に、
lfs# lidsconf -D -s /tmp/tempwrite.sh -o /var/tmp代わりに
lfs# lidsconf -A -s /tmp/tempwrite.sh -o /var/tmp -i 1 -j WRITEとします。-i は「inherit(継承)」を表し、上の例では「継承レベル 1 」を示します。「継承レベル」とは、何世代目までのプロセスがACL を継承できるかを表すものです。「継承レベル 1 」では、子プロセス(第一世代)までがACL を継承できますが、孫プロセス(第二世代)には継承されません。 lidsconf -L の出力を見てみると
Using ACL FILE: /etc/lids/lids.conf
LIST
effective capability = 0x00000000
Subject ACCESS inherit time Object
----------------------------------------------------------------------------
Any file READONLY: 0 0000-0000 /sbin 0
Any file READONLY: 0 0000-0000 /bin 0
Any file READONLY: 0 0000-0000 /boot 0
Any file READONLY: 0 0000-0000 /lib 0
Any file READONLY: 0 0000-0000 /usr 0
Any file READONLY: 0 0000-0000 /var 0
Any file READONLY: 0 0000-0000 /tmp 0
Any file READONLY: 0 0000-0000 /etc 0
Any file DENY: 0 0000-0000 /etc/lids 0
Any file DENY: 0 0000-0000 /etc/shadow 0
Any file APPEND: 0 0000-0000 /var/log 0
Any file WRITE: 0 0000-0000 /var/log/wtmp 0
/bin/login READONLY: 0 0000-0000 /etc/shadow 0
/bin/su READONLY: 0 0000-0000 /etc/shadow 0
Any file READONLY: 0 0000-0000 /usr/local/etc 0
/bin/su GRANT: 0 0000-0000 CAP_SETUID 0
/bin/su GRANT: 0 0000-0000 CAP_SETGID 0
Any file READONLY: 0 0000-0000 /root 0
Any file READONLY: 0 0000-0000 /root/.bash_history 0
/bin/login WRITE: 0 0000-0000 /var/log/wtmp 0
/bin/login WRITE: 0 0000-0000 /var/log/lastlog 0
/sbin/init GRANT: 0 0000-0000 CAP_KILL 0
/etc/rc.d/init.d/halt GRANT: 1 0000-0000 CAP_KILL 0
/etc/rc.d/init.d/halt GRANT: 1 0000-0000 CAP_NET_ADMIN 0
/etc/rc.d/init.d/halt GRANT: 1 0000-0000 CAP_SYS_ADMIN 0
Any file READONLY: 0 0000-0000 /home/omok 0
/bin/bash APPEND: 0 0000-0000 /home/omok/.bash_history 0
/tmp/testwrite.sh WRITE: 1 0000-0000 /var/tmp 0
となり、「inherit」の項目に1 が設定されています。
この状態で、設定ファイルを再読み込みしてテストします。
lfs# lidsconf -U lfs# lidsadm -S -- +RELOAD_CONF lfs# lidsadm -S -- + # /tmp/testwrite.sh #となり、/var/tmp を見てみると
# ls /var/tmp tmpfile #tmpfile がきちんとコピーされています。
----------------------------/tmp/test2.sh------------------------ #!/bin/sh /tmp/tmptestwrite.sh ----------------------------------------------------------------------として、先程のスクリプトを呼び出す、新しいスクリプトを作ります。 先程のtestwrite.sh に関するACL を削除して、
lfs# lidsconf -D -s /tmp/tempwrite.sh -o /var/tmp新たに
lfs# lidsconf -A -s /tmp/test2.sh -o /var/tmp -i 1 -j WRITEとします。継承レベルを1 に設定しています。 ここで、/tmp/test2.sh を動作させると
cp: cannot create regular file `/var/tmp/tmpfile': Operation not permittedと、/var/tmp/tmpfile に書き込む権限が無いと言うアラートが出て来ます。 これは、継承レベルを1 に設定したため、test2.sh から直接起動されるプロセス (testwrite.sh) にはACL が継承されますが、そのtestwrite.sh から起動されるcp コマンドに関しては、test2.sh から見て孫に当たりますので、ACL が継承されていないと言う事です。 したがって、このtest2.sh がきちんと動くためには
lfs# lidsconf -A -s /tmp/test2.sh -o /var/tmp -i 2 -j WRITEとして継承レベル2 (孫) にしてあげる必要があります。 継承レベルを-1 に設定すると、無制限にACL を継承していきます。システムの設定を思考錯誤している時には継承レベルを無制限にしておき、正常に動くようになった後に継承レベルを正しく設定していく方法が良いでしょう。
----------------------------lids.ssh.sh--------------------------- #!/bin/sh lidsconf -A -s /usr/sbin/sshd -o CAP_CHOWN -j GRANT lidsconf -A -s /usr/sbin/sshd -o CAP_FOWNER -j GRANT lidsconf -A -s /usr/sbin/sshd -o CAP_SYS_CHROOT -j GRANT lidsconf -A -s /usr/sbin/sshd -o CAP_SETGID -j GRANT lidsconf -A -s /usr/sbin/sshd -o CAP_SETUID -j GRANT lidsconf -A -s /usr/sbin/sshd -o CAP_DAC_OVERRIDE -j GRANT lidsconf -A -s /usr/sbin/sshd -o CAP_DAC_READ_SEARCH -j GRANT lidsconf -A -s /usr/sbin/sshd -o CAP_SYS_TTY_CONFIG -j GRANT lidsconf -A -s /usr/sbin/sshd -o /etc/shadow -j READONLY lidsconf -A -s /usr/sbin/sshd -o /var/log/lastlog -j WRITE --------------------------------End--------------------------------
./configure --prefix=/usr/local/apache --sysconfdir=/etc/httpdで、httpd.conf で
ログファイル : /var/log/httpdにしてあります。
#!/bin/sh lidsconf -A -s /root/apachectl -i 1 -o CAP_SETUID -j GRANT lidsconf -A -s /root/apachectl -i 1 -o CAP_SETGID -j GRANT lidsconf -A -s /root/apachectl -i 1 -o CAP_DAC_OVERRIDE -j GRANT lidsconf -A -s /root/apachectl -i 1 -o CAP_NET_BIND_SERVICE 80,443 -j GRANT lidsconf -A -o /usr/local/apache -j DENY lidsconf -A -o /etc/httpd -j DENY lidsconf -A -s /root/apachectl -i 1 -o /etc/httpd -j READONLY lidsconf -A -s /root/apachectl -i 1 -o /usr/local/apache -j READONLY lidsconf -A -s /root/apachectl -i 1 -o /usr/local/apache/htdocs -j READONLY lidsconf -A -s /root/apachectl -i 1 -o /usr/local/apache/cgi-bin -j READONLY lidsconf -A -s /root/apachectl -i 1 -o /var/log/httpd/access_log -j APPEND lidsconf -A -s /root/apachectl -i 1 -o /var/log/httpd/error_log -j APPEND lidsconf -A -s /root/apachectl -i 1 -o /var/log/httpd -j WRITE lidsconf -A -s /root/apachectl -i 1 -o /usr/local/apache/bin/httpd -j READONLY lidsconf -A -s /root/apachectl -i 1 -o /usr/local/apache/bin/envvars -j READONLYまた、このときにはhttpd から起動ができますが、apachectl からはexport している関連で起動ができません。直接httpd を起動するか、apachectl を書き換えてPATH の部分を直接記入してください。
lidsconf -D -s XXX -o XXXとして、一つ一つ削除して行くか、あるいは
/etc/lids/lids.confを直接編集して削除してから
lidsconf -Uでアップデートしましょう。
[root@nemesis root]# lidsconf -A -o /var -j READONLY
Using ACL FILE: /etc/lids/lids.conf
ADD
effective capability = 0x00000000
[root@nemesis root]# lidsconf -A -o /var/tmp -j DENY
Using ACL FILE: /etc/lids/lids.conf
ADD
effective capability = 0x00000000
lidsconf: the type is less than default permssion, this rule is useless
このように、デフォルトのパーミッションよりも、新しく設定するパーミッションの方が厳しくなる(小さくなる)場合には、上述のエラーが出て設定が出来ません。
したがって、このようにACL を設定する場合には、/var/tmp をDENY に設定した後に/var をREADONLY に設定します。
または、直接lids.conf ファイルを編集する事により実現できます。上の例ですと、/var/tmp のinode 番号などが必要になりますので、
/etc/lids/lids.confファイルをコピーしてから、lidsconf -Z で全削除した後に、
lidsconf -A -o /var/tmp -j DENYとしたあとに、/etc/lids/lids.conf として保存された行を、元のファイルに付け加えて
lidsconf -Uとすれば良いでしょう。