我正在运行 nginx 和 unicorn 来为 Rails 应用程序提供服务。Unicorn
和 Rails 应用程序运行良好,但 nginx 无法打开 rails 公共目录,出现权限错误并返回 502 Bad Gateway。
curl http://localhost/
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.6.1</center>
</body>
</html>
var/log/nginx/error.log
014/09/18 18:16:16 [crit] 16619#0: *1 stat() "/home/rails/public_html/rails_app/current/public//index.html" failed (13: Permission denied), client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "localhost"
2014/09/18 18:16:16 [crit] 16619#0: *1 stat() "/home/rails/public_html/rails_app/current/public/" failed (13: Permission denied), client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "localhost"
2014/09/18 18:16:16 [crit] 16619#0: *1 connect() to unix:/tmp/unicorn.rails_app.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://unix:/tmp/unicorn.rails_app.sock:/", host: "localhost"
2014/09/18 18:16:16 [crit] 16619#0: *1 stat() "/home/rails/public_html/rails_app/current/public/500.html/index.html" failed (13: Permission denied), client: 127.0.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://unix:/tmp/unicorn.rails_app.sock/", host: "localhost"
2014/09/18 18:16:16 [crit] 16619#0: *1 stat() "/home/rails/public_html/rails_app/current/public/500.html" failed (13: Permission denied), client: 127.0.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://unix:/tmp/unicorn.rails_app.sock/", host: "localhost"
2014/09/18 18:16:16 [crit] 16619#0: *1 connect() to unix:/tmp/unicorn.rails_app.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://unix:/tmp/unicorn.rails_app.sock:/500.html", host: "localhost"
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024; # increase if you have lots of clients
# accept_mutex off; # "on" if nginx worker_processes > 1
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
# tcp_nopush on;
# tcp_nodelay off;
upstream unicorn {
server unix:/tmp/unicorn.rails_app.sock fail_timeout=0;
}
server {
listen 80 default deferred;
# server_name example.com;
root /home/rails/public_html/rails_app/current/public;
try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
}
rails 公共目录的权限为 775 或 775。nginx
由“nginx”用户执行,rails 公共目录归“rails”用户所有。
我尝试过用“rails”用户和 root 用户执行 nginx,但出现了相同的错误。
我不知道这些错误是怎么回事。
如果我将根目录设置为 /usr/share/nginx/html/,nginx 可以正常工作。我的环境是 Vagrant 上的 Centos7 和带有 unicorn gem 4.8.3 的 rails 2.2.2。
[注意]我知道/tmp/unicorn.rails_app.sock需要放在另一个目录中这个问题,但我猜这不是问题。
答案1
nginxnginx
以配置中规定的用户身份运行。您说您的目录归所有root:root
。
确保这件事每一个目录从根目录到 nginx 尝试访问的文件具有权限执行(有可能阅读?) 权限。就你的情况而言,其他权限组(chmod o+(r)x <recursive list of dirs>
)。
如果这还不够,请尝试添加阅读允许其他的在套接字文件上。
正常情况下,现在 nginx 将能够访问stat()
这些文件。
事实上,在 nginxroot
设置下一切运行正常/usr/share/nginx/html
,是因为这些文件是由 nginx 包创建的,并且具有适当的用户/组/权限组合......
现在,我看到另一个(更大的)问题:你尝试使用以 身份运行的 nginx 工作程序nginx:nginx
和 所拥有的文件root:root
,而没有写nginx 的任何权限。因此,nginx 在套接字上进行的任何写入尝试最终都将失败……
你真的应该重新考虑一下你的整个结构。让 nginx 用户/组和目录/文件以某种方式匹配,这样 nginx 就可以打开它需要打开的内容(执行直接在目录上),读取需要读取的内容并写入需要写入的内容,而不依赖于其他权限组基本上允许任何用户做同样的事情。
答案2
我设法解决了这个问题。
问题是 nginx 无法读取 /tmp/unicorn.rails_app.sock,因为 PrivateTmp=true/etc/systemd//system/multi-user.target.wants/nginx.service
这些就是我做的。
为独角兽套接字创建目录
mkdir /var/run/unicorn
chown rails:rails /var/run/unicorn
chmod 755 /var/run/unicorn
修改nginx.conf
upstream unicorn {
server unix:/var/run/unicorn/unicorn.rails_app.sock fail_timeout=0;
}
禁用 SElinux
sudo setenforce 0
永久禁用
在/etc/sysconfig/selinux中
SELINUX=permissive
SELINUXTYPE=targeted
现在运行良好。
答案3
编辑了我的 nginx.conf 并将用户从 nginx 更改为 deployer(我的 capistrano 部署用户和 wheel 组成员),现在一切正常!
答案4
要检查 SELinux 中是否存在这种情况,您可以禁用它
sudo setenforce 0
但关闭它并不安全,当你重新启动时问题会再次出现
很好的详细文章https://nts.strzibny.name/allowing-nginx-to-use-a-pumaunicorn-unix-socket-with-selinux/
简而言之,您需要执行命令并将输出保存到 nginx.te 文件中
sudo grep nginx /var/log/audit/audit.log | audit2allow -m nginx
module nginx 1.0;
require {
type httpd_t;
type initrc_t;
class unix_stream_socket connectto;
}
#============= httpd_t ==============
allow httpd_t initrc_t:unix_stream_socket connectto;
然后检查、编译并减去
sudo checkmodule -M -m -o nginx.mod nginx.te
sudo semodule_package -o nginx.pp -m nginx.mod
sudo semodule -i nginx.pp