本文共 2241 字,大约阅读时间需要 7 分钟。
在CentOS 7.5配置并启动Nginx后,却总是看到如下异常
Permission denied
查看Nginx的错误日志如下:
[root@mylocal ~]# grep Permission /var/log/nginx/error.log2019/05/30 03:51:21 [crit] 4331#0: *6 " connect() to 127.0.0.1:8080/regression failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://172.18.0.101:8080/", host: "localhost:8080"
分析异常原因,在连接被代理的服务时被拒绝。
首先,排除了Nginx反向代理的配置问题,因为迁移前的同样的配置工作正常。
其次,基本排除了Nginx服务器的问题,systemctl status nginx查看服务运行正常。
最后,只能怀疑是权限真的不足的问题了。比较当前root用户与nginx用户,显然不是Linux用户权限的问题,那就只可能是SELinux的用户权限问题了。
查看SELinux的审计日志:
[root@myloca ~]# grep denied /var/log/audit/audit.logtype=AVC msg=audit(1559031062.594:294): avc: denied { name_connect } for pid=1339 comm="nginx" dest=8080 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket
初步分析SELinux的审计日志,可以看到nginx进程的SELinux scontext type为httpd_t,而被请求对象8080的SELinux tcontext type为http_cache_port_t,两者不匹配,且没有从属关系。
借助于audit2why工具,执行grep 1559031062.594:294 /var/log/audit/audit.log | audit2why命令,让audit2why帮助我们找到解决办法。查看该命令的输出,可以看到我们的初步分析是正确的,而其给出的建议如下:
setsebool -P httpd_can_network_connect 1至此问题基本明了。针对上述异常,我们可以采取如下解决方案。
解决方法一,直接修改SELinux的检查模式为Permissive:
[root@myloac ~]# setenforce Permissive 或 [root@myloac ~]# setenforce 0解决方法二,开启httpd_can_network_connect:
[root@myloac ~]# getsebool httpd_can_network_connect httpd_can_network_connect --> off[root@myloac ~]# setsebool -P httpd_can_network_connect 1
或 [root@myloac ~]# setsebool -P httpd_can_network_connect on解决方法三,创建一个SELinux定制模块mynginx:
grep nginx /var/log/audit/audit.log | audit2allow -M mynginx说明:
该命令将生成/var/log/nginx/mynginx.pp和/var/log/nginx/mynginx.te文件。 其中/var/log/nginx/mynginx.pp是二进制文件,无法阅读。/var/log/nginx/mynginx.te是文本文件,内容如下:module mynginx 1.0; require { type httpd_t; type unreserved_port_t; class tcp_socket { name_bind name_connect }; } #============= httpd_t ============== #!!!! This avc can be allowed using the boolean 'nis_enabled' allow httpd_t unreserved_port_t:tcp_socket { name_bind name_connect };
生成SELinux的mynginx定制模块后,执行semodule -i mynginx.pp命令加载该模块即可。
最后执行semodule -l命令,查看mynginx模块已经生效。转载地址:http://thlai.baihongyu.com/