CentOS 6.6 with Nginx 1.6.2 – 突然无法重启nginx – nginx: open()“/ usr / share / nginx / on”失败(13:Permission denied)

这是一个新的安装,其中nginx先前正常启动和停止。 我相信这个错误是在启用testing成功的服务器模块(nginx -t)之后出现的。 然后我尝试重新启动nginx并收到此错误:

nginx: [emerg] open() "/usr/share/nginx/on" failed (13: Permission denied) 

在尝试重新启动之前,文件“on”不存在。 它刚刚创build,是空的。 当我重新启动php-fmp(成功),然后尝试再次重新启动nginx时,错误更改为:

 nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied) nginx: configuration file /etc/nginx/nginx.conf test failed 

但是,当我运行nginx -t时,testing成功:

 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 

我认为这可能是一个用户问题,但一切似乎很好:

 # ps -elf | grep nginx 5 S nginx 2774 2773 0 80 0 - 234152 skb_re 22:07 ? 00:00:00 php-fpm: pool www 5 S nginx 2775 2773 0 80 0 - 234152 skb_re 22:07 ? 00:00:00 php-fpm: pool www 5 S nginx 2776 2773 0 80 0 - 234152 skb_re 22:07 ? 00:00:00 php-fpm: pool www 5 S nginx 2777 2773 0 80 0 - 234152 skb_re 22:07 ? 00:00:00 php-fpm: pool www 5 S nginx 2778 2773 0 80 0 - 234152 skb_re 22:07 ? 00:00:00 php-fpm: pool www 0 R root 2940 2472 0 80 0 - 25811 - 22:18 pts/0 00:00:00 grep nginx 

即使Nginx没有运行,nginx.pid文件仍然保留,所以我删除了它。 这样做只是简单地将错误信息更改回:

nginx: [emerg] open() "/usr/share/nginx/on" failed (13: Permission denied) nginx: configuration file /etc/nginx/nginx.conf test failed.

无论我如何尝试重新启动系统,包括$ sudo /etc/init.d/nginx restart$ sudo /etc/init.d/nginx reload都收到此错误。 我删除了没有任何区别的空的“开”文件。 当我使用$ getenforce ,它返回Enforcing

回复@ǝɲǝɲbρɯͽ:

sudo grep -vR '^$\|^\s*\#' /etc/nginx/conf.d/* | grep -v ";"sudo grep -vR '^$\|^\s*\#' /etc/nginx/nginx.conf* | grep -v ";" sudo grep -vR '^$\|^\s*\#' /etc/nginx/nginx.conf* | grep -v ";" 没有产生缺失的分号。

命令sudo grep -ER "on|/usr/share" /etc/nginx/*几乎打印出nginx中每一个文件的每一行,所以我不确定我会从这些信息中学到什么。 顺便说一下, /usr/shar/nginx只包含空文件,没有别的。

sudo ausearch -m avc -ts recent -c nginx返回了<no matches>

不用说,我是服务器问题的新手,但我认为命令service --status-all (下)可能会产生有用的信息。 当然,我们已经知道一个pid文件存在,即使nginx已经死了,但是master (pid 1924) is running吗? 另外,iptables中有没有什么可以负责防止nginx重新启动?

 atd (pid 1995) is running... auditd (pid 1405) is running... crond (pid 1982) is running... htcacheclean is stopped Table: filter Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all ::/0 ::/0 state RELATED,ESTABLISHED 2 ACCEPT icmpv6 ::/0 ::/0 3 ACCEPT all ::/0 ::/0 4 ACCEPT udp ::/0 fe80::/64 state NEW udp dpt:546 5 ACCEPT tcp ::/0 ::/0 state NEW tcp dpt:22 6 REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited Chain OUTPUT (policy ACCEPT) num target prot opt source destination Table: filter Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80 5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 6 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited 7 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 8 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) num target prot opt source destination iscsi is stopped iscsid is stopped lvmetad is stopped mdmonitor (pid 1445) is running... multipathd is stopped mysqld is stopped netconsole module not loaded Configured devices: lo bond0 em1 em2 Currently active devices: lo em1 em2 bond0 nginx dead but pid file exists php-fpm is stopped master (pid 1924) is running... rdisc is stopped restorecond is stopped rsyslogd (pid 1425) is running... sandbox is stopped saslauthd is stopped snmpd is stopped snmptrapd is stopped openssh-daemon (pid 1486) is running... svnserve is stopped 

/ usr / share / nginx / …是默认webroot所在的位置; 你可能已经设置了一些“开”,并意外触及该文件。 既然你的testing工作,它也可能已经解决,但是当nginx崩溃(或者像kill -9的东西)它不会摆脱它的PID文件。

我没有使用php-fpm的经验,但是看起来你的nginx主进程没有运行。 您可以通过以下方式确认:

 $ ps axu | grep `cat /var/run/nginx.pid` 

那些反引号(`)而不是撇号(')。 如果没有运行,请删除pid文件:

 $ sudo rm /var/run/nginx.pid 

并重新启动nginx。 在许多系统上,这是:

 $ sudo /etc/init.d/nginx restart 

在正常情况下,您不想在现场进行此操作。 有更好的方法,包括:

  • $ sudo /etc/init.d/nginx重新加载
  • 优雅的控制选项

一旦你重新启动nginx,你应该看到这样的东西:

 $ ps axu | grep nginx ... worker threads ... 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf 

你也可以:

 $ /etc/init.d/nginx status nginx (pid 1111) is running... 

**编辑:从评论诊断**

1.configuration

  • 仔细看看你的改变。 当缺less分号时,nginx是脆弱的。 几乎每一行都必须结束;
    • 如果你错过了一些,nginx会处理额外的行,就好像它们是同一个指令的一部分一样。 例如(它可能比这更糟糕),这两行被处理为相同的指令: root /var/nginx/..... # no semicolon sendfile on;
    • nginx并不是nginx的责任,所以不能保证nginx能够在尝试启动worker之前检测到这个错误,而SELinux(正确)会在这个exception的进程动作上跑步。

为了更容易find这些行¹:

 $ sudo grep -vR '^$\|^\s*\#' /etc/nginx/conf.d/* | grep -v ";" 

或带有“on”或“/ usr / share”的行:

 $ sudo grep -ER "on|/usr/share" /etc/nginx/conf.d/* 

您可能需要修复其中的一个(不要将分号添加到{}行),然后:

 $ sudo rm /usr/share/nginx/on /var/run/nginx.pid $ sudo /etc/init.d/nginx restart 

2.元数据:certificateSELinux的参与(或不)

这仅供参考。 它总是在编辑中出现,并且是我们/未来访问者的枢纽。 假设nginx仍然是坏的(你还没有修复configuration):

 $ sudo /etc/init.d/nginx start $ sudo ausearch -m avc -ts recent -c nginx 

虽然我们正在过滤nginx(可能有其他拒绝),但如果您看到以下内容,SELinux可能不会被指示:

 <no matches> 

SELinux用AVC表示,类似于:

 type=AVC msg=audit(timestamp:123): avc: denied { getattr } for pid=1234 comm="nginx" path="/usr/share/nginx/on" dev=sda ino=123456 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:var_t:s0 tclass=file 

问题是,在启动过程中的某个时刻,文件是在不同于nginx或其工作人员(切换安全上下文)的上下文中创build的,因此是不允许触摸的。 当有意的时候,通过在许多命令中添加-Z可以看到上下文,通过chcon(更改上下文)修复,并且可以很容易的find问题 。

¹grep 信用

你有一个期望的path属性,但提供了一个布尔值,例如

 access_log on; 

access_log期待一个path,但是它提供了一个布尔值。 您可以通过仔细阅读错误来确认:

 nginx: [emerg] open() "/usr/share/nginx/on" failed (13: Permission denied) 

注意相对于你的nginx基本path。