CentOS 6.6 和 Nginx 1.6.2 - 突然无法重启 nginx - nginx: [emerg] open() "/usr/share/nginx/on" failed (13: Permission denied)

Joh*_*sen 2 nginx centos php-fpm

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

nginx: [emerg] open() "/usr/share/nginx/on" failed (13: Permission denied)
Run Code Online (Sandbox Code Playgroud)

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

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

但同样,当我运行 nginx -t 时,测试成功:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Run Code Online (Sandbox Code Playgroud)

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

# 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
Run Code Online (Sandbox Code Playgroud)

即使 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。我删除了空的“on”文件,这也没有区别。当我使用时$ 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 -ER "on|/usr/share" /etc/nginx/*几乎打印了 nginx 中每个文件的每一行,所以我不确定我会从这些信息中学到什么。顺便说一句,/usr/shar/nginx只包含那个空on文件,没有别的。

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

不用说,我是服务器问题的新手,但我认为命令service --status-all(下面)可能会产生有用的信息。当然,我们已经知道即使 nginx 已经死了,pid 文件仍然存在,但是 pid 文件是什么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
Run Code Online (Sandbox Code Playgroud)

Gaj*_*jus 6

您有一个需要路径的属性,但提供了一个布尔值,例如

access_log on;
Run Code Online (Sandbox Code Playgroud)

access_log需要一个路径,但提供了一个布尔值on。您可以通过仔细阅读错误来确认这一点:

nginx: [emerg] open() "/usr/share/nginx/on" failed (13: Permission denied)
Run Code Online (Sandbox Code Playgroud)

请注意on相对于您的 nginx 基本路径的相对路径。


小智 5

/usr/share/nginx/... 是默认的 webroot 所在的位置;您可能已将某些内容设置为“打开”并意外触及该文件。由于您的测试有效,它可能也已解决,但是当 nginx 崩溃(或类似 kill -9 之类的东西)时,它不会删除其 pid 文件。

我没有使用 php-fpm 的经验,但您的 nginx 主进程似乎没有运行。您可以通过以下方式确定:

$ ps axu | grep `cat /var/run/nginx.pid`
Run Code Online (Sandbox Code Playgroud)

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

$ sudo rm /var/run/nginx.pid
Run Code Online (Sandbox Code Playgroud)

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

$ sudo /etc/init.d/nginx restart
Run Code Online (Sandbox Code Playgroud)

在正常情况下,您不想在实时站点上这样做。有更好的方法,包括:

重新启动 nginx 后,您应该会看到如下内容:

$ ps axu | grep nginx

... worker threads
... 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
Run Code Online (Sandbox Code Playgroud)

你也可以:

$ /etc/init.d/nginx status

nginx (pid  1111) is running...
Run Code Online (Sandbox Code Playgroud)

**编辑:来自评论的诊断**

1. 配置

  • 非常仔细地查看您的更改。nginx 在缺少分号时很脆弱。几乎每一行都必须以 ; 结尾。
    • 如果你错过了一些,nginx 会处理额外的行,就好像它们是同一指令的一部分。例如(并且可能比这更糟糕)这两行被处理为相同的指令: root /var/nginx/..... # no semicolon sendfile on;
    • 为您提供真正好的语法检查器不是 nginx 的责任,因此不能保证 nginx 在尝试启动工作程序之前会检测到此错误,其中 SELinux(正确)踩踏异常进程操作。

为了更容易找到这些行¹:

$ sudo grep -vR '^$\|^\s*\#' /etc/nginx/conf.d/* | grep -v ";"
Run Code Online (Sandbox Code Playgroud)

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

$ sudo grep -ER "on|/usr/share" /etc/nginx/conf.d/*
Run Code Online (Sandbox Code Playgroud)

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

$ sudo rm /usr/share/nginx/on /var/run/nginx.pid
$ sudo /etc/init.d/nginx restart
Run Code Online (Sandbox Code Playgroud)

2. 元数据:证明 SELinux 参与(或不参与)

这仅供参考。它一直在编辑中出现,并且是我们/未来访问者的支点。假设 nginx 仍然损坏(您还没有修复配置):

$ sudo /etc/init.d/nginx start
$ sudo ausearch -m avc -ts recent -c nginx
Run Code Online (Sandbox Code Playgroud)

尽管我们在 nginx 上进行过滤(可能还有其他拒绝),但如果您看到 SELinux,则可能不会指示:

<no matches>
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

问题是在启动过程中的某个时刻,文件是在与 nginx 不同的上下文中创建的,或者它的工作人员(切换安全上下文)正确地不允许触摸。有意时,通过将 -Z 添加到许多命令中,上下文是可见的,用 chcon(更改上下文)修复,并且很容易找到与此相关的问题。

¹ grep 信用