NGINX: SELinux 13:permission denied
2016-04-12 16:24
579 查看
When you upgrade a running system to Red Hat Enterprise Linux (RHEL) 6.6 or CentOS 6.6, the Security Enhanced Linux (SELinux) security permissions that apply to NGINX are relabelled
to a much stricter posture. Although the permissions are adequate for the default configuration of NGINX, configuration for additional features can be blocked and you need to permit them explicitly in SELinux. This article describes the possible issues
and recommended ways to resolve them.
[Editor: Oracle Linux was not supported at the time this article was originally published. Because it is based on RHEL, this article applies to it as well.]
SELinux is enabled by default on RHEL and CentOS servers. Each operating system object (process, file descriptor, file, etc.) is associated with an SELinux context that defines the permissions and operations the object can perform. During an upgrade to RHEL
6.6 or CentOS 6.6, NGINX’s association is changed to the
The
to listen on common web server ports, to access configuration files in /etc/nginx, and to access content
in the standard docroot location (/usr/share/nginx). It does not permit many other operations, such as
proxying to upstream locations or communicating with other processes through sockets.
SELinux can be run in enforcing, permissive, or disabled mode. When you make a configuration change that might breach the current permissions, you
can move SELinux from enforcing to permissive mode, on your test environment (if available) or on production. In permissive mode, SELinux permits all operations, but logs operations that would have breached the security policy in enforcing mode.
To add
domains, run this command:
To delete
of permissive domains, run:
To set the mode globally to permissive, run:
To set the mode globally to enforcing, run:
In permissive mode, security exceptions are logged to /var/log/audit/audit.log.
If you encounter a problem that occurs only when NGINX is in enforcing mode, review the exceptions that
are logged inpermissive mode and update the security policy to permit them.
By default, the SELinux configuration does not allow NGINX to connect to a remote web, fastCGI, or other server, as indicated by an audit log message like the following:
To interpret the message code (
run the
The output from
setting one or more Boolean options. To permit the proxy connect operation, you can enable these Boolean options, either temporarily or permanently (add the
If you install the setools package (
to get more information about the Boolean options. Here we present examples for the
This output indicates that
connection to ports of various types, including type
To add more ports to the set (in this case,
run:
If a message indicates that a port is already defined, as in the following example, it means the port is included in another set. Do not reassign it, because other services might be negatively affected.
The
allows
TCP socket types that have the
To list them, run:
By default, the SELinux configuration does not allow NGINX to access files outside of well-known authorized locations, as indicated by an audit log message like the following:
To interpret the message code (
run the
When file access is forbidden, you have two options.
Modify the file label so that the
can access the file:
By default, this modification is deleted when the file system is relabelled. To make the change permanent, run:
To modify file labels for groups of files, run:
Extend the
access to additional file locations:
To create a compiled policy, include the
To load the policy, run
then verify success with
This change persists across reboots.
SELinux is a complex and powerful facility for managing operating system permissions. Additional information is available at the following locations.
SELinux
Documentation (United States National Security Agency)
Security-Enhanced
Linux User Guide (Fedora project)
Security-Enhanced
Linux User Guide (Red Hat)
SELinux
project home page
SELinux
How-to (CentOS)
to a much stricter posture. Although the permissions are adequate for the default configuration of NGINX, configuration for additional features can be blocked and you need to permit them explicitly in SELinux. This article describes the possible issues
and recommended ways to resolve them.
[Editor: Oracle Linux was not supported at the time this article was originally published. Because it is based on RHEL, this article applies to it as well.]
Overview of SELinux
SELinux is enabled by default on RHEL and CentOS servers. Each operating system object (process, file descriptor, file, etc.) is associated with an SELinux context that defines the permissions and operations the object can perform. During an upgrade to RHEL6.6 or CentOS 6.6, NGINX’s association is changed to the
httpd_tcontext:
# ps auZ | grep nginx unconfined_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
The
httpd_tcontext permits NGINX
to listen on common web server ports, to access configuration files in /etc/nginx, and to access content
in the standard docroot location (/usr/share/nginx). It does not permit many other operations, such as
proxying to upstream locations or communicating with other processes through sockets.
SELinux Modes
SELinux can be run in enforcing, permissive, or disabled mode. When you make a configuration change that might breach the current permissions, youcan move SELinux from enforcing to permissive mode, on your test environment (if available) or on production. In permissive mode, SELinux permits all operations, but logs operations that would have breached the security policy in enforcing mode.
To add
httpd_tto the list of permissive
domains, run this command:
# semanage permissive -a httpd_t
To delete
httpd_tfrom the list
of permissive domains, run:
# semanage permissive -d httpd_t
To set the mode globally to permissive, run:
# setenforce 0
To set the mode globally to enforcing, run:
# setenforce 1
Checking for SELinux Exceptions
In permissive mode, security exceptions are logged to /var/log/audit/audit.log.If you encounter a problem that occurs only when NGINX is in enforcing mode, review the exceptions that
are logged inpermissive mode and update the security policy to permit them.
Example 1: Proxy Connection is Forbidden
By default, the SELinux configuration does not allow NGINX to connect to a remote web, fastCGI, or other server, as indicated by an audit log message like the following: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)
To interpret the message code (
1415714880.156:29),
run the
audit2whycommand:
# grep 1415714880.156:29 /var/log/audit/audit.log | audit2why 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 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
The output from
audit2whyrecommends
setting one or more Boolean options. To permit the proxy connect operation, you can enable these Boolean options, either temporarily or permanently (add the
-Poption).
Understanding Boolean Options
If you install the setools package (yum install setools), you can run the
sesearchcommand
to get more information about the Boolean options. Here we present examples for the
httpd_can_network_relayand
httpd_can_network_connectoptions.
The httpd_can_network_relay
Boolean
Option
# sesearch -A -s httpd_t -b httpd_can_network_relay Found 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 ;
This output indicates that
httpd_can_network_relaypermits
connection to ports of various types, including type
http_port_t:
# semanage port -l | grep http_port_t http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
To add more ports to the set (in this case,
8082),
run:
# semanage port -a -t http_port_t -p tcp 8082
If a message indicates that a port is already defined, as in the following example, it means the port is included in another set. Do not reassign it, because other services might be negatively affected.
# 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
The httpd_can_network_connect
Boolean
Option
# sesearch -A -s httpd_t -b httpd_can_network_connect Found 1 semantic av rules: allow httpd_t port_type : tcp_socket name_connect ;
The
httpd_can_network_connectoption
allows
httpd_tto connect to all
TCP socket types that have the
port_typeattribute.
To list them, run:
# seinfo -aport_type -x
Example 2: File Access is Forbidden
By default, the SELinux configuration does not allow NGINX to access files outside of well-known authorized locations, as indicated by an audit log message like the following: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
To interpret the message code (
1415715270.766:31),
run the
audit2whycommand:
# grep 1415715270.766:31 /var/log/audit/audit.log | audit2why
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
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.
When file access is forbidden, you have two options.
Option 1: Modify the File Label
Modify the file label so that the httpd_tdomain
can access the file:
# chcon -v --type=httpd_sys_content_t /www/t.txt
By default, this modification is deleted when the file system is relabelled. To make the change permanent, run:
# semanage fcontext -a -t httpd_sys_content_t /www/t.txt # restorecon -v /www/t.txt
To modify file labels for groups of files, run:
# semanage fcontext -a -t httpd_sys_content_t /www(/.*)? # restorecon -Rv /www
Option 2: Extend the httpd_t
Domain
Permissions
Extend the httpd_tpolicy to allow
access to additional file locations:
# 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 the these booleans: # httpd_can_network_relay, httpd_can_network_connect allow httpd_t http_cache_port_t:tcp_socket name_connect;
To create a compiled policy, include the
-Moption:
# grep nginx /var/log/audit/audit.log | audit2allow -M nginx
To load the policy, run
semodule -i,
then verify success with
semodule -l:
# semodule -i nginx.pp # semodule -l | grep nginx nginx 1.0
This change persists across reboots.
Additional Resources
SELinux is a complex and powerful facility for managing operating system permissions. Additional information is available at the following locations.SELinux
Documentation (United States National Security Agency)
Security-Enhanced
Linux User Guide (Fedora project)
Security-Enhanced
Linux User Guide (Red Hat)
SELinux
project home page
SELinux
How-to (CentOS)
相关文章推荐
- nginx 缓存路径配置优化
- Nginx上安装phpMyAdmin
- nginx-Brew安装lua模块
- Nginx控制ip访问频率
- Nginx安装部署
- NGINX虚拟主机的创立
- Nginx区分PC或手机访问不同网站
- nginx + keepalived 实现热备负载
- nginx -t 提示proxy_headers_hash_max_size警告的解决方法
- nginx安装lua模块
- nginx rewrite 指令last break区别最详细的解释
- nginx windows No mapping for the Unicode character...
- Nginx的Rewrite正则表达式,匹配非某单词
- 在Nginx服务器中设置多个站点
- Linux(CentOS)系统下设置nginx开机自启动
- Nginx_handler模块发开(hello模块结构解析)
- 深入NGINX:我们如何设计它的性能和扩展性
- NGINX源代码剖析 之 CPU绑定(CPU亲和性)
- centos7 nginx安装
- nginx配置成服务