audit2allowなしでnginxがUNIXソケットにアクセスすることをSELinuxに許可するにはどうすればよいですか?


9

私はでUnixソケットを介してgunicornにnginx転送要求があります/run/gunicorn/socket。デフォルトでは、この動作はSELinuxでは許可されていません。

grep nginx /var/log/audit/audit.log
type=SERVICE_START msg=audit(1454358912.455:5390): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=nginx comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
type=AVC msg=audit(1454360194.623:7324): avc:  denied  { write } for  pid=9128 comm="nginx" name="socket" dev="tmpfs" ino=76151 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=sock_file
type=SYSCALL msg=audit(1454360194.623:7324): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=1f6fe58 a2=6e a3=7ffee1da5710 items=0 ppid=9127 pid=9128 auid=4294967295 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1454361591.701:13343): avc:  denied  { connectto } for  pid=9128 comm="nginx" path="/run/gunicorn/socket" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:initrc_t:s0 tclass=unix_stream_socket
type=SYSCALL msg=audit(1454361591.701:13343): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=1f6fe58 a2=6e a3=7ffee1da5950 items=0 ppid=9127 pid=9128 auid=4294967295 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)

私が見ているすべての場所(たとえば、ここここ)で、これを有効にしてnginxにリクエストを送信し、SELinuxによってリクエストが拒否され、その後のaudit2allowリクエストを許可するために実行されます。この動作を明示的に許可するコマンドchconsemanageコマンドを理解できません。

これが唯一の方法ですか?最初に試行を拒否せずに拒否されたものを有効にするツールを実行せずにnginxがソケットに書き込むことを許可するポリシーを設定できないのはばかげているようです。何が有効になっているのかを正確に知るにはどうすればよいですか?自動でマシンをセットアップする場合、これはどのように機能するはずですか?

CentOS 7を使用しています。


AVC拒否メッセージを表示する必要があります。実行しているOSとバージョンも知っておくとよいでしょう。
user9517 2016年

@lain良い点。
Drs 2016年

回答:


23

最初に試行を拒否せずに拒否されたものを有効にするツールを実行せずにnginxがソケットに書き込むことを許可するポリシーを設定できないのはばかげているようです。

いいえ、SELinuxは必須アクセス制御であり、デフォルトでは拒否され、明示的に許可する必要があります。ポリシー作成者が特定の(franken)スタックを考慮していない場合、またはデーモンの作成者がそれをSELinux対応にしていないため、ポリシーを記述していない場合は、ご自分で判断してください。サービスが何をしているか、どのようにSELinuxと相互作用しているかを分析し、それを許可するための独自のポリシーを考え出す必要があります。audit2whyaudit2allowなどの支援に利用できるツールがあります。

...これが唯一の方法ですか?

いいえ、しかし、それはあなたが何をしようとしているのか、そしてどのような解決策をしようとしているかに依存します。たとえば、nginx(httpd_t)をポート8010(unreserved_port_t)にバインドすることができます。nginxを起動すると失敗する

Starting nginx: nginx: [emerg] bind() to 0.0.0.0:8010 failed (13: Permission denied)

そして、最終的には監査ログを調べて見つけます

type=AVC msg=audit(1457904756.503:41673): avc:  denied  { name_bind } for
pid=30483 comm="nginx" src=8010 scontext=unconfined_u:system_r:httpd_t:s0
tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket

これをaudit2alllowで実行し、その結果を単純に受け入れる場合があります。

allow httpd_t port_t:tcp_socket name_bind;

これにより、httpd_tが任意のTCPポートに接続できるようになります。これはあなたが望むものではないかもしれません。

sesearchを使用してポリシーを調査し、httpd_tがどのポートタイプにname_bindを実行できるかを確認できます。

sesearch --allow -s httpd_t | grep name_bind
...
allow httpd_t http_port_t : tcp_socket name_bind ;
allow httpd_t http_port_t : udp_socket name_bind ;
...

他のタイプの中でも、http_tはhttp_port_tにバインドできます。これで、semanageを使用して少し深く掘り下げることができます。

semanage port -l | grep http_port_t
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
...

ポート8010は表示されません。nginxをポート8010にバインドしたいので、http_port_tリストに追加することは不合理ではありません

semanage port -a -t http_port_t -p tcp 8010

これで、nginxは、上記のようにすべてのtcpポートではなく、ポート8010にname_bindすることができます。

何が有効になっているのかを正確に知るにはどうすればよいですか?

ポリシーの変更は非常に読みやすく、上記のメッセージをaudit2allowで実行すると、

allow httpd_t httpd_sys_content_t:sock_file write;
allow httpd_t initrc_t:unix_stream_socket connectto;

かなり自明のようです。

それらの最初は、inum 76151のファイルを参照しています。findを使用してその名前を取得し(find / -inum 76151)semanage fcontext -a -t ...、ポリシーを変更してrestoreconを使用してコンテキストを修正できます。

2つ目/run/gunicorn/socketは、どちらが間違ったコンテキストを持つかに関係しています。sesearchを使用すると、http_tが(特に)http_tタイプのunix_stream_socketsに接続できることがわかります。たとえば、状況に応じてコンテキストを変更できます

semanage fcontext -a -t httpd_t "/run/gunicorn(/.*)?"
restorecon -r /run

これは/ run / gunicornとツリーのコンテキストを設定します| その下のファイルをhttpd_tに。

自動でマシンをセットアップする場合、これはどのように機能するはずですか?

システムを分析し、テストに適切な変更を加える必要があります。次に、自動化ツールを使用して変更をデプロイします。人形とansibleはこれをサポートします。

もちろん、SElinuxをpermissiveに設定すれば、すべて本番環境で実行できます。すべてのメッセージを収集し、分析して変更を決定し、それらを展開します。

SELinuxについて知っておくべきことはまだまだたくさんありますが、それが私のスキルの限界です。マイケルハンプトンの方が優れており、マシューイフェの方がはるかに優れています。


1
あなたのアドバイスは徹底的であり、私はこれらの問題を私自身で解決するのにずっと近づきますが、それでも私は少し不足しています。 allow httpd_t httpd_sys_content_t:sock_file write;あなたが望んだほど私には説明が必要です。そのファイルのポリシーを変更する必要があると言っているのは何ですか(つまり、コマンドの後-tに何が続くのsemanageですか?
drs

また、semanageコマンドを直接使用すると、使用方法の説明が表示されます。--add引数を追加する必要があります。
drs '14 / 03/16

実は、私はまたにソケットファイルの種類を変更した後と言うべきでhttpd_var_run_tマイケル・ハンプトンは、以下のように、audit2allow:メッセージがあるallow httpd_t var_run_t:sock_file write;
DRS

設定してvar_run_tいないようですhttpd_var_run_t
user9517 2016年

@lain、うーん。サイコロはありません。今audit2allow言うallow httpd_t var_run_t:sock_file write;
drs

2

使用したいタイプではありませんhttpd_sys_content_t。これは、Webサーバーがユーザーエージェントに提供する静的ファイル用です。

プロセス間通信に使用されるソケットの場合、探しているタイプはhttpd_var_run_tです。

ただし、gunicornを制限なく実行したため、通信に追加の問題が発生する可能性があることに注意してください。


3
ありがとう!これはSELinuxの問題の1つを処理したようです。gunicorn(またはその他のサービス)の設定方法に関する指針は限定されていますか?
drs 2016年

1

私は成功せずに以前の回答を試しましたが、私の場合、Unixソケットを使用してuwsgiアプリケーションのフロントエンドとしてnginxサーバーを使用しています。私のOSはFedoraサーバーです26。

UNIXソケットはディレクトリに作成されます/var/local/myapp

/var/local/myapp/server.sock    
/var/local/myapp/stats.sock

SELinuxを構成するには、コンテキストタイプを追加する必要がありました。 httpd_sys_rw_content_t

semanage fcontext -at httpd_sys_rw_content_t "/var/local/myapp(/.*)?"
restorecon -R -v '/var/local/myapp' 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.