nginx proxying to unix sockets: lessons learned

I might classify this article under “rage post”, as it’s 4:30am and tomorrow’s early work prevents me from explaining things properly.

Considering you have an nginx app proxying to /your/app.socket ; then the combination of the user and group and chmod value on the app.socket file itself & the directory containing it (in this example, the /your/ directory), and the user which runs the web process behind nginx (in my case a Node.js application) has a lot to say about whether nginx can successfully connect to that unix socket or not.

I’ve tried so many things that seem they should work in the first place (even the shameful 777-ing of my socket file) to no avail. Eventually, after 2 weeks of non-consecutive work, this is what works for me:

  • nginx runs as nginx:www
  • Node.js process runs as my_user (and listens on the unix socket, of course)
  • unix socket is placed at /my/app.socket
  • The output when I do ls -lah /my/ is:
    • line1: drwxr-sr-x 2 my_user www 4.0K Feb 24 10:30 .
    • line2: srwxrwxr-x 1 my_user www 0 Feb 24 10:30 app.socket

Note that every time I restart the Node.js process, a new app.socket file is generated with the default chmod value of srwxr-xr-x, which blocks nginx from reading it due to the lack of group permission (nginx runs on group www and the file doesn’t have the execute bit for group, even though its group is also www).

I could automate the chmod-ing of the socket file to 775 again. I could also probably force nginx to run as my_user. Those are the small fries. The real beast is that: as soon as the combined conditions above (those bullet points) are not met together, nginx is gonna be a crybaby, denying connection to the socket file while leaving very ambiguous & sometimes downright untrue error messages (e.g. (13: Permission denied) or (2: No such file or directory)).

This was on CentOS 7 (SELinux _not_ enabled) & nginx 1.12.2

Update 1 (March 1st 2020): don’t try to touch (create) the unix domain socket manually, and instead, leave it for the Node.js process to create the unix domain socket as & when it needs. Otherwise, the Node.js HTTP server might not be able to connect to the socket (EACCES error).

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s