編集者 – 「NGINX: 「RHEL 6.6 / CentOS 6.6 へのアップグレード時の SELinux の変更」はここにリダイレクトされます。 この記事では、最新かつ一般的な情報を提供します。
最新の Red Hat Enterprise Linux (RHEL) および関連ディストリビューションの Security-Enhanced Linux (SELinux) のデフォルト設定は非常に厳格で、利便性よりもセキュリティが優先されることがあります。 デフォルト設定では、NGINX Open Source と NGINX Plus の機能が制限されることはありませんが、SELinux で明示的に許可しない限り、構成するその他の機能がブロックされる可能性があります。 この記事では、考えられる問題と、それを解決するための推奨される方法について説明します。
[編集者 – この記事は、NGINX Open Source と NGINX Plus の両方に適用されます。 読みやすくするために、全体を通じて「NGINX」という用語が使用されています。
CentOS は、もともと RHEL から派生した関連ディストリビューションであり、NGINX および NGINX Plus によってサポートされています。 さらに、NGINX Plus は関連する Amazon Linux および Oracle Linux ディストリビューションをサポートしています。 デフォルトの SELinux 設定は CentOS や RHEL とは異なる場合があります。ベンダーのドキュメントを参照してください。
SELinuxの概要
最新の RHEL および CentOS サーバーでは、SELinux がデフォルトで有効になっています。 各オペレーティング システム オブジェクト (プロセス、ファイル記述子、ファイルなど) には、オブジェクトが実行できる権限と操作を定義する SELinux コンテキストのラベルが付けられます。 RHEL 6.6/CentOS 6.6 以降では、NGINX はhttpd_tコンテキストでラベル付けされます。
# ps auZ | grep nginxunconfined_u:system_r:httpd_t:s0 3234 ? Ss 0:00 nginx: master process /usr/sbin/nginx \
-c /etc/nginx/nginx.conf
unconfined_u:system_r:httpd_t:s0 3236 ? Ss 0:00 nginx: worker process
httpd_tコンテキストにより、NGINX は一般的な Web サーバー ポートをリッスンし、 /etc/nginx内の設定ファイルにアクセスし、標準の docroot の場所 ( /usr/share/nginx ) 内のコンテンツにアクセスできるようになります。 アップストリームの場所へのプロキシやソケットを介した他のプロセスとの通信など、他の多くの操作は許可されません。
httpd_tコンテキストの SELinux 制限を一時的に無効にして、NGINX が非 SELinux OS と同じ操作をすべて実行できるようにするには、 httpd_tコンテキストを許可ドメインに割り当てます。 詳細については次のセクションを参照してください。
# semanage permissive -a httpd_t
SELinux は、 enforcing モード、 permissiveモード、またはdisabledモード (ドメインとも呼ばれます) で実行できます。 デフォルトの (厳格な) 権限に違反する可能性がある NGINX 構成変更を行う前に、テスト環境 (使用可能な場合) または実稼働環境で SELinux を強制モードから許可モードに変更できます。 許可モードでは、SELinux はすべての操作を許可しますが、強制モードではセキュリティ ポリシーに違反する操作をログに記録します。
許可ドメインのリストにhttpd_t を追加するには、次のコマンドを実行します。
# semanage permissive -a httpd_t
許可ドメインのリストからhttpd_t を削除するには、次のコマンドを実行します。
# semanage permissive -d httpd_t
モードをグローバルにpermissiveに設定するには、次のコマンドを実行します。
# setenforce 0
モードをグローバルにenforcingに設定するには、次のコマンドを実行します。
# setenforce 1
SELinux セキュリティ例外の解決
許可モードでは、セキュリティ例外はデフォルトの Linux 監査ログ/var/log/audit/audit.logに記録されます。 NGINX が強制モードで実行されている場合にのみ発生する問題が発生した場合は、許可モードで記録された例外を確認し、それらを許可するようにセキュリティ ポリシーを更新します。
デフォルトでは、SELinux 構成では、次のような監査ログ メッセージで示されるように、NGINX がリモート HTTP、FastCGI、またはその他のサーバーに接続することを許可しません。
type=AVC msg=audit(1415714880.156:29): avc: denied { name_connect } for pid=1349 \
comm="nginx" dest=8080 scontext=unconfined_u:system_r:httpd_t:s0 \
tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket
type=SYSCALL msg=audit(1415714880.156:29): arch=c000003e syscall=42 success=no \
exit=-115 a0=b \a1=16125f8 a2=10 a3=7fffc2bab440 items=0 ppid=1347 pid=1349 \
auid=1000 uid=497 gid=496 euid=497 suid=497 fsuid=497 egid=496 sgid=496 fsgid=496 \
tty=(none) ses=1 comm="nginx" exe="/usr/sbin/nginx" \
subj=unconfined_u:system_r:httpd_t:s0 key=(null)
Audit2whyコマンドはメッセージ コード ( 1415714880.156:29 ) を解釈します。
# grep 1415714880.156:29 /var/log/audit/audit.log | audit2whytype=AVC msg=audit(1415714880.156:29): avc: denied { name_connect } for pid=1349 \
comm="nginx" dest=8080 scontext=unconfined_u:system_r:httpd_t:s0 \
tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket
Was caused by:
One of the following booleans was set incorrectly.
Description:
Allow httpd to act as a relay
Allow access by executing:
# setsebool -P httpd_can_network_relay 1
Description:
Allow HTTPD scripts and modules to connect to the network using TCP.
Allow access by executing:
# setsebool -P httpd_can_network_connect 1
Audit2whyからの出力は、 httpd_can_network_relayとhttpd_can_network_connectブール オプションの 1 つまたは両方を有効にすることで、NGINX がプロキシ接続を確立できるようにできることを示しています。 これらは一時的に有効にすることも、永続的に有効にすることもできます。永続的に有効にする場合は、出力に示すように、 ‑Pフラグを追加します。
sesearchコマンドはブール オプションに関する詳細情報を提供します。このコマンドは、 setoolsパッケージ ( yum install setools ) をインストールすると使用できます。 ここでは、 httpd_can_network_relayおよびhttpd_can_network_connectオプションの出力を示します。
httpd_can_network_relayブールオプションhttpd_can_network_relayオプションに関するsesearchコマンドの出力は次のとおりです。
# sesearch -A -s httpd_t -b httpd_can_network_relayFound 10 semantic av rules:
allow httpd_t gopher_port_t : tcp_socket name_connect ;
allow httpd_t http_cache_client_packet_t : packet { send recv } ;
allow httpd_t ftp_port_t : tcp_socket name_connect ;
allow httpd_t ftp_client_packet_t : packet { send recv } ;
allow httpd_t http_client_packet_t : packet { send recv } ;
allow httpd_t squid_port_t : tcp_socket name_connect ;
allow httpd_t http_cache_port_t : tcp_socket name_connect ;
allow httpd_t http_port_t : tcp_socket name_connect ;
allow httpd_t gopher_client_packet_t : packet { send recv } ;
allow httpd_t memcache_port_t : tcp_socket name_connect ;
この出力は、 httpd_can_network_relay が、 httpd_tコンテキスト (NGINX など) でラベル付けされたプロセスが、 http_port_tタイプを含むさまざまなタイプのポートに接続することを許可することを示しています。
# semanage port -l | grep http_port_thttp_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
ポートを追加するには(ここでは、8082 ) をhttp_port_tに許可されるポートのセットに追加するには、次を実行します。
# semanage port -a -t http_port_t -p tcp 8082
次の例のように、このコマンドの出力にポートがすでに定義されていると表示される場合は、そのポートが別のセットに含まれていることを意味します。 他のサービスに悪影響を与える可能性があるため、 http_port_tに再割り当てしないでください。
# semanage port -a -t http_port_t -p tcp 8080
/usr/sbin/semanage: Port tcp/8080 already defined
# semanage port -l | grep 8080
http_cache_port_t tcp 3128, 8080, 8118, 8123, 10001-10010
httpd_can_network_connectブールオプションhttpd_can_network_connectオプションに関するsesearchコマンドの出力は次のとおりです。
# sesearch -A -s httpd_t -b httpd_can_network_connectFound 1 semantic av rules:
allow httpd_t port_type : tcp_socket name_connect ;
この出力は、 httpd_can_network_connect が、 httpd_tコンテキスト (NGINX など) でラベル付けされたプロセスがport_type属性を持つすべての TCP ソケット タイプに接続することを許可することを示しています。 一覧表示するには、次のコマンドを実行します。
# seinfo -aport_type -x
デフォルトでは、SELinux 設定により、NGINX は既知の承認済み場所以外のファイルにアクセスすることができません。これは、次のような監査ログ メッセージで示されます。
type=AVC msg=audit(1415715270.766:31): avc: denied { getattr } for pid=1380 \
comm="nginx" path="/www/t.txt" dev=vda1 ino=1084 \
scontext=unconfined_u:system_r:httpd_t:s0 \
tcontext=unconfined_u:object_r:default_t:s0 tclass=file
Audit2whyコマンドはメッセージ コード ( 1415715270.766:31 ) を解釈します。
# grep 1415715270.766:31 /var/log/audit/audit.log | audit2whytype=AVC msg=audit(1415715270.766:31): avc: denied { getattr } for pid=1380 \
comm="nginx" path="/www/t.txt" dev=vda1 ino=1084 \
scontext=unconfined_u:system_r:httpd_t:s0 \
tcontext=unconfined_u:object_r:default_t:s0 tclass=file
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.
ファイルへのアクセスが禁止されている場合、2 つのオプションがあります。
NGINX ( httpd_tコンテキストでラベル付けされたプロセス) がファイルにアクセスできるように、ファイル ラベルを変更します。
# chcon -v --type=httpd_sys_content_t /www/t.txt
デフォルトでは、ファイル システムのラベルが変更されると、この変更は削除されます。 変更を永続的にするには、次のコマンドを実行します。
# semanage fcontext -a -t httpd_sys_content_t /www/t.txt
# restorecon -v /www/t.txt
ファイル グループのファイル ラベルを変更するには、次のコマンドを実行します。
# semanage fcontext -a -t httpd_sys_content_t '/www(/.*)?'# restorecon -Rv /www
httpd_tドメイン権限を拡張する追加のファイルの場所へのアクセスを許可するには、 httpd_tのポリシーを拡張します。
# grep nginx /var/log/audit/audit.log | audit2allow -m nginx > nginx.te# cat nginx.te
module nginx 1.0;
require {
type httpd_t;
type default_t;
type http_cache_port_t;
class tcp_socket name_connect;
class file { read getattr open };
}
#============= httpd_t ==============
allow httpd_t default_t:file { read getattr open };
#!!!! This avc can be allowed using one of these booleans:
# httpd_can_network_relay, httpd_can_network_connect
allow httpd_t http_cache_port_t:tcp_socket name_connect;
コンパイルされたポリシーを生成するには、 -Mオプションを含めます。
# grep nginx /var/log/audit/audit.log | audit2allow -M nginx
ポリシーをロードするには、 semodule -iを実行し、 semodule -lで成功を確認します。
# semodule -i nginx.pp
# semodule -l | grep nginx
nginx 1.0
この変更は再起動後も維持されます。
デフォルトでは、SELinux 設定により、NGINX はhttp_port_tタイプで許可リストされているデフォルトのポート以外の TCP ポートまたは UDP ポートをリッスン ( bind() ) できません。
# semanage port -l | grep http_port_thttp_port_t tcp 80, 443, 488, 8008, 8009, 8443
NGINX を許可リストに登録されていないポートで listen するように設定しようとすると (NGINX 設定のhttp 、 stream 、またはmailコンテキストでlistenディレクティブを使用)、NGINX 設定を検証 ( nginx -t ) または再ロードすると、次の NGINX ログ エントリに示すようにエラーが発生します。
YYYY/MM/DD hh:mm:ss [emerg] 46123#0: bind() to 0.0.0.0:8001 failed (13: Permission denied)
semanageを使用して、必要なポート (ここでは 8001) をhttp_port_tタイプに追加できます。
# semanage port -a -t http_port_t -p tcp 8001
新しい設定で NGINX をリロードします。
# nginx -s reload
開いているファイルが多すぎますエラー開いているファイルの数の制限 ( RLIMIT_NOFILE ) を超えると、エラー ログに次のメッセージが表示されます。
Too many files are open
ほとんどの場合、NGINX ワーカー プロセスがこのエラーを報告しますが、エラー ログと監査ログの次のメッセージに報告されているように、SELinux はsetrlimit()システム コールを許可しないため、NGINX worker_rlimit_nofileディレクティブを使用して制限を増やすことはできません。
CentOS/RHEL 7.4 以降の/var/log/nginx/error.logの場合:
YYYY/MM/DD hh:mm:ss [alert] 12066#0: setrlimit(RLIMIT_NOFILE, 2342) failed (13: Permission denied)
CentOS/RHEL 8.0 以降の/var/log/nginx/error.logの場合:
YYYY/MM/DD hh:mm:ss [alert] 3327#0: setrlimit(RLIMIT_NOFILE, 65535) failed (1: Operation not permitted)
CentOS/RHEL 7.4+ の場合は/var/log/audit/audit.log、CentOS/RHEL 8.0+ の場合は/var/log/messagesに次の内容が記録されます。
type=AVC msg=audit(1437731200.211:366): avc: denied { setrlimit } for pid=12066 \ comm="nginx" scontext=system_u:system_r:httpd_t:s0 \
tcontext=system_u:system_r:httpd_t:s0 tclass=process
制限を増やすには、代わりにrootユーザーとして次のコマンドを実行します。
$ setsebool -P httpd_setrlimit 1
NGINX マスター プロセスがエラーを報告する場合は、NGINX のsystemdユニットファイルを更新する必要があります。これにより、マスター プロセスとワーカー プロセスの両方のファイル記述子の制限が設定されます。
nginx.service設定用のディレクトリを作成します。
$ mkdir /etc/systemd/system/nginx.service.d
/etc/systemd/system/nginx.service.d/nofile_limit.confに次の行を追加します。
[Service]LimitNOFILE=65535
systemd デーモンの設定を再読み込みし、NGINX を再起動します。
$ systemctl daemon-reload$ systemctl restart nginx.service
追加リソース
SELinux は、オペレーティング システムの権限を管理するための複雑かつ強力な機能です。 追加情報は、以下のドキュメントで参照できます。
「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 q。"