さるへい備忘録

さるへいのやったことを綴っているブログです。基本的にテクノロジーの話題です。

SELinuxが原因の通信遮断の原因判定から、audit2allowでnginxなどを許可するまで。

外部と通信しているアプリケーションの場合、通信できない原因はSELinuxを疑ってみると原因がSELinuxであることが多々あります。
でもSELinuxってなかなか難しいですよね。
web上を探してもあんまり資料が落ちてないし、そもそも疑うエラーログからは全然SELinuxが原因であることがわからない上に理由もわからないみたいなことばっかりです。

SELinuxでの原因判定方法

なんとなくSELinuxのせいかな?なんて思った場合は、一回SELinuxを切って確認してみると良いです。

まず、SELinuxが可動しているか確認してみましょう。

$ getenforce
Enforcing

上記のように Enforcing と出た場合はSELinuxが有効であることの証拠です。
Enforcing と出ない場合はSELinuxが可動していないので、エラーの原因は他にあります。

$ setenforce 0
$ getenforce
Permissive

上記のようにSELinuxを無効にすることができます。 その後、稼働状態を確認して、 Permissive であることを確認しましょう。 この状態でアプリケーションで通信などをしてみて有効状態でできなかった動作が成功した場合はSELinuxが原因であることの証拠です。

確認後はもちろんSELinuxを有効に戻しておきましょう。

$ setenforce 1
$ getenforce
Enforcing

audit2allowでSELinuxのポリシーモジュールを作って解決

SELinuxが原因というところまではなんとか辿り着く人もいるのですが、この後どうすればいいかわからないといった人をよく見かけます。
そんな時に便利なのが audit2allow (https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/security-enhanced_linux/sect-security-enhanced_linux-fixing_problems-allowing_access_audit2allow)

こちら、SELinuxの拒否操作ログからSElinuxのポリシーallowルールを作成できるすぐれものです。 ただ、こちらなんでもかんでも許可してしまうとSELinuxの意味がなくなってしまうので、慎重に行うと良いでしょう。

nginxとSELinux

nginxは、SELinuxが原因でsockの書き込み権限などが制限されていて、 sockファイルを使った通信などができません。
以下のようなエラーログが吐き出されている場合はSELinuxが原因である場合があります。

2019/02/25 00:18:15 [crit] xxxxx#0: *xxxx connect() to unix:/path/to/sock.sock failed (13: Permission denied) while connecting to upstream, client: ipアドレス, server: 設定server名, request: "GET / HTTP/1.1", upstream: "サーバアプリ://unix:/path/to/sock.sock:", host: "ホスト名"

こちらをでnginxに対して限定的にSELinuxのポリシーallowルールを作ることでnginxを使った通信が可能となります。  

$ cat /var/log/audit/audit.log | grep nginx | audit2allow -m nginx
module nginx 1.0;

require {
        type unconfined_t;
        type httpd_t;
        type user_home_t;
        class sock_file write;
        class unix_stream_socket connectto;
}

#============= httpd_t ==============
allow httpd_t unconfined_t:unix_stream_socket connectto;
allow httpd_t user_home_t:sock_file write;

上記は、/var/log/audit/audit.logaudit.logが存在していると仮定した場合のコマンドです。
こちらのコマンドで、 nginxへの解決にgrepしてどんなポリシーallowルールが適用されるか確認しましょう。
上記で大丈夫が確認することが大事です。

大丈夫そうだったら下記コマンドで実際にポリシーallowルールをコンパイルして適用するためのバイナリファイルを作成しましょう。

$ cat /var/log/audit/audit.log | grep nginx | audit2allow -M nginx
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i nginx.pp

nginx.pp として作成されるので、下記コマンドで適用しましょう。

$ semodule -i nginx.pp

これで、現在nginxがSELinuxにブロックされていた原因を取り除くことができます。
ただ、ブロックを取り除いた上で更に別のSELinux上のセキュリティ機能にブロックされることもあります。
その場合は、また同じことをしてポリシーallowルールを作成すると良いでしょう。

上記は、nginx以外にもいろいろ使えますが乱用すると非常に危険なコマンドです。
くれぐれも何が起こるかをしっかり見極めて適用していきましょう。