家庭用カレンダーunicale2の構築とSELinux

家族用のカレンダーを作る。クラウド使うのが良いのだけど、ここは家庭内ローカル環境で構築。

入れるのは、unicale2
ググって見つけて、シンプルで良いかなって思った。

導入を簡単に、紹介

ちなみにSELinuxが有効な状態のまま進めます。

# getenforce
Enforcing

■unicale2の入手とyum update

# wget http://www.unicale.com/downloads/unicale_204
# llw-r--r--. 1 root root  287635  9月  6 21:46 unicale_204

zipなので一応名称を変更しておく
# mv unicale_204 unicale_204.zip
# unzip unicale_204.zip
# ll
drwxr-xr-x. 9 root root    4096  2月 27  2014 unicale_204
-rw-r--r--. 1 root root  287635  9月  6 21:46 unicale_204.zip

unicaleのマニュアルから、Webサーバへunicaleのフォルダをコピーということで、/var/wwwを確認
# cd /var/www
bash: cd: /var/www: そのようなファイルやディレクトリはありません

がーん、入ってなかった。
そういえば、最近アップデートしてないので、yum updateをすることに(脱線するなぁ)

カーネルとかアップしたくないので、ちょっと編集
# vi /etc/yum.conf
で、下記を追加
exclude=kernle* centos*
# uname -a
Linux mfileserver 4.3.3-1.el7.elrepo.x86_64 #1 SMP Tue Dec 15 11:18:19 EST 2015 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core) 
# rpm -qa | grep "^kernel" | sort
kernel-3.10.0-514.10.2.el7.x86_64
kernel-headers-3.10.0-514.26.2.el7.x86_64
kernel-ml-4.3.3-1.el7.elrepo.x86_64
kernel-ml-devel-4.3.3-1.el7.elrepo.x86_64
kernel-tools-3.10.0-514.10.2.el7.x86_64
kernel-tools-libs-3.10.0-514.10.2.el7.x86_64
# yum clean all
# yum -y update
  検証中                  : 1:oci-systemd-hook-0.1.4-9.git671c428.el7.x86_64                                    195/195 

minimumインストールなのに195も更新される。いろいろ入ってるなぁ

# uname -a
Linux mfileserver 4.3.3-1.el7.elrepo.x86_64 #1 SMP Tue Dec 15 11:18:19 EST 2015 x86_64 x86_64 x86_64 GNU/Linux
# uname -ayum -y updateclean allrpm -qa | grep "^kernel" | sortcat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

アップデートするとおかしくなるwifiも確認。一応OKそう。
# nmcli d
デバイス    タイプ    状態      接続
docker0     bridge    接続済み  docker0
virbr0      bridge    接続済み  virbr0
enp3s0      ethernet  接続済み  enp3s0
wlp2s0      wifi      接続済み  nuc5ppyh-1
lo          loopback  管理無し  --
virbr0-nic  tun       管理無し  --

そして、念のためリブートしてから、やっとhttpdのインストール
# yum install -y httpd
# cd /var/www
# ls
cgi-bin  html
# pwd
/var/www
# systemctl start httpd

■ファイアウォール設定追加

ところが、他のPCからWebサーバへのアクセスができない。

こういう時の原因調査のとっかかりは、(最初に確認した有効無効関係なく)SELinuxとファイアウォールと決まってる。
SELinuxがEnforcingなのをgetenforceで確認して、ログ参照。※PermissiveならSELinuxは関係ない。
audit.logには、拒否メッセージがなかったので、SELinux、ではなくて、firewalld が原因でしょう。

ということで、http アクセスの許可を追加
# firewall-cmd --permanent --zone=public --add-service=http
success
# firewall-cmd --reloa
succes

これで、httpdへのアクセスはできるようになった。

■SELinuxのセキュリティポリシー設定追加

そろそろ面倒くさくなってきたので、超はしおって、メモ記録
/var/www/html/unicale に /root/unicale_204 をコピー
/var/www/html/unicale以下のファイルに対して、httpdのアクセス権限が存在しないのでエラーとなる。つまり、(SELinuxで使う)ファイルコンテキストがおかしい。単純にコピー、じゃなくて、mvしたらこうなる、いい例。
# ausearch -m AVC | grep 'php' | audit2allow -a
#============= httpd_t ============== 

#!!!! The file '/var/www/html/unicale/index.php' is mislabeled on your system.
#!!!! Fix with $ restorecon -R -v /var/www/html/unicale/index.php
allow httpd_t admin_home_t:file { getattr read }; 
# ls -alZ
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 .
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 ..
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 MyController.php
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 cheeta
・・・

いったん、SELinuxをPermissiveモードに変えて
ラベルの再設定
# setenforce 0
# restorecon -R -v /var/www/html/unicale/*
restorecon reset /var/www/html/unicale/MyController.php context unconfined_u:object_r:admin_home_t:s0->unconfined_u:obje
ct_r:httpd_sys_content_t:s0
・・・ 

SELinuxをEnforcingに戻しておく。ファイルコンテキストを確認する。
# setenforce 1
# getenforce
Enforcing
# ls -alZ
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 . 
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 ..
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 MyController.php
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 cheetan 

ファイルコンテキストが変わっていることがわかる。まぁ、audit2allowの書いてたものと違うけど気にしない。

■コードの修正各PHPファイルを、chmod 666 ではなくて、777で設定。
これで大体動いたけど、PHPの問題?で
&$c とかなっているところを $c にしないと動作しなかったです。

あと、レイアウトやデザイン変更をやったけど、もう書くの疲れたし、忘れたよ(;´・ω・)

(2017/10/1追加)
動いた~と思ったものつかの間、データの追加ができなかった。
/var/www/html/unicale/data/d_data.txt
へhttpd_dが書き込めないというSELinuxのメッセージ。

audit2allow すると、以下の対策。
 #============= httpd_t ==============

#!!!! This avc can be allowed using the boolean 'httpd_unified'
allow httpd_t httpd_sys_content_t:file write;

でもね、なんかWeb系ってこんなことしてたらいけない気がして、Setroubleshootを見てみた。
※こんなこと、ってのは、httpd_sys_content_t のラベルにhttpd_tの書き込み権限を追加するってことは、httpd_sys_content_tのラベルを持つファイル全部(unicale全部とか他のコンテンツ)への書き込みができるようになるってこと。これってhttpdがハックされた書き換えできちゃうってことなので、良くないよね!

# sealert -l 6c17b48a-2ce8-43e2-8942-d34145624c79
SELinux is preventing /usr/sbin/httpd from write access on the file d_data.txt.

*****  Plugin httpd_write_content (92.2 confidence) suggests   ***************

If you want to allow httpd to have write access on the d_data.txt file
Then 'd_data.txt' のラベルを変更する必要があります
Do
# semanage fcontext -a -t httpd_sys_rw_content_t 'd_data.txt'
# restorecon -v 'd_data.txt'
*****  Plugin catchall_boolean (7.83 confidence) suggests   ******************

If allow httpd to unified がしたい
Then 'httpd_unified' boolean を有効にすることにより、 これを SELinux に伝える必要があります。
詳細情報については、'None' man ページをご覧下さい。
Do
setsebool -P httpd_unified 1

*****  Plugin catchall (1.41 confidence) suggests   **************************

If httpd に、 d_data.txt file の write アクセスがデフォルトで許可されるべきです。
Then バグとして報告してください。
ローカルのポリシーモジュールを生成すると、
 このアクセスを許可することができます。
Do
allow this access for now by executing:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd
# semodule -i my-httpd.pp


Additional Information:
Source Context                system_u:system_r:httpd_t:s0
Target Context                unconfined_u:object_r:httpd_sys_content_t:s0
Target Objects                d_data.txt [ file ]
Source                        httpd
Source Path                   /usr/sbin/httpd
Port                          <Unknown>
Host                          mfileserver
Source RPM Packages
Target RPM Packages
Policy RPM                    selinux-policy-3.13.1-102.el7_3.16.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     mfileserver
Platform                      Linux mfileserver 3.10.0-514.26.2.el7.x86_64 #1
                              SMP Tue Jul 4 15:04:05 UTC 2017 x86_64 x86_64
Alert Count                   16
First Seen                    2017-09-06 23:05:24 JST
Last Seen                     2017-10-01 02:31:08 JST
Local ID                      6c17b48a-2ce8-43e2-8942-d34145624c79
Raw Audit Messages
type=AVC msg=audit(1506792668.710:3376): avc:  denied  { write } for  pid=29763 comm="httpd" name="d_data.txt" dev="dm-0" ino=207523170 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:httpd_sys_content_t:s0 tclass=file
 
Hash: httpd,httpd_t,httpd_sys_content_t,file,write

赤字の部分にビビッと来た。こういうのを待っていた。
httpd_sys_content_t は、httpdが書き込みできないコンテンツタイプ
httpd_sys_rw_content_t は、その名前の通り書き込みできるコンテンツタイプ(だと思う)

指示に従って変更、パス名はきちんといれないと設定できない(のを知らずに、何回か失敗したw)

# semanage fcontext -a -t httpd_sys_rw_content_t /var/www/html/unicale/data/d_data.txt

#restorecon -v d_data.txt
restorecon reset /var/www/html/unicale/data/d_data.txt context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_sys_rw_content_t:s0 

 これで、書き込めるようになりました。