Nginx cannot access upstream .sock file and public folder

phil pirozhkov asked:

Given: fresh Archlinux VPS box on DigitalOcean. I created a user, ‘app’, and there’s a file, /home/app/webapp.sock created by the binary started by systemd:

[Unit]
Description=Web application server
After=network.target

[Service]
Type=forking
User=app
PIDFile=/home/app/webapp.pid
ExecStart=/home/app/.gem/ruby/2.0.0/bin/thin -d --user app -e production --chdir /home/app/app --socket /home/app/webapp.sock --pid /home/app/webapp.pid --log /home/app/log/webapp.log start
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -QUIT $MAINPID

[Install]
WantedBy=multi-user.target

Don’t want to run this app as http user, since at some point of time I may decide to run another web server on that machine under a different user, exposing only its .sock file to http user. Rails is known to have security flaws, so I would like to avoid the ‘app’ user from getting anywhere out of his home folder and its own data.

I have a sudo user, ‘sudoer’, and there’s no way to read even a pid file:

[sudoer@host ~]$ cat /home/app/webapp.pid
cat: /home/app/webapp.pid: Permission denied
[sudoer@host ~]$ sudo su - app
[app@host ~]$ ls -l webapp.pid
-rw-r--r-- 1 app app 5 Dec  7 19:33 webapp.pid

It has ‘r’ rights for ‘others’, why is that ‘sudoer’ cannot ‘cat’ it?

I assume this is the reason for the following nginx errors too.
Static file:

2013/12/07 18:58:05 [error] 18114#0: *2 open() "/home/app/app/public/favicon.ico" failed (13: Permission denied), client: 183.89.50.151, server: host.com, request: "GET /favicon.ico HTTP/1.1", host: "host.com"

Dynamic content:

2013/12/07 20:49:00 [crit] 21581#0: *1 connect() to unix:/home/app/webapp.sock failed (13: Permission denied) while connecting to upstream, client: 183.89.50.151, server: host.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://unix:/home/app/webapp.sock:/favicon.ico", host: "host.com"

Excerpt from nginx config:

upstream webapp {
  server unix:/home/app/webapp.sock fail_timeout=0;
}
server {
  listen 80;
  root /home/app/app/public;

Is that strengthened security? SELinux? CGroups? What am I doing wrong?

My answer:


You must check the permission, not only of the socket (file) but of all the parent directories. If any of them deny access, your request will fail.

For instance:

# ls -ld /home/app
drwx------. 8 root root 4096 Dec 7 21:33 /home/app

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.