#2470 closed enhancement (invalid)

Add support for the systemd directive OpenFile= for passing UNIX socket FDs to nginx

Reported by: erik.sjolund@… Owned by:
Priority: minor Milestone: nginx-1.23.4
Component: nginx-module Version: 1.23.x
Keywords: Cc: erik.sjolund@…
uname -a:
nginx -V: nginx version: nginx/1.23.3
built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
built with OpenSSL 1.1.1k 25 Mar 2021 (running with OpenSSL 1.1.1n 15 Mar 2022)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -ffile-prefix-map=/data/builder/debuild/nginx-1.23.3/debian/debuild-base/nginx-1.23.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

Description (last modified by erik.sjolund@…)

nginx currently supports specifying a UNIX socket path with the proxy_pass configuration directive

For example

proxy_pass http://unix:/tmp/backend.socket:/uri/;

(reference:
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
)

Instead of specifying a path to the UNIX socket, I would like to pass in a file descriptor for the UNIX socket to nginx via inheritance from the parent process that starts nginx (i.e., systemd).

Feature request:
Add support for specifying a UNIX socket via the new systemd directive

OpenFile=

(see https://www.freedesktop.org/software/systemd/man/systemd.service.html#OpenFile=) which is available in systemd 253 (released 15 February 2023).

systemd connects to the UNIX socket and lets nginx inherit the file descriptor.

I have not yet investigated how systemd sets the environment variable LISTEN_FDNAMES. (I could provide more details later).

Rationale

This new feature would make it possible to set up a systemd system service with the systemd configuration USER=myuser and GROUP=mygroup and use nginx to proxy traffic to a UNIX socket that the user myuser:mygroup does not have file permission access to. The reason myuser:mygroup is able to use the UNIX socket is that systemd (running as root) has already connected to the socket.

Change History (6)

comment:1 by erik.sjolund@…, 13 months ago

Description: modified (diff)

comment:2 by Maxim Dounin, 13 months ago

Instead of specifying a path to the UNIX socket, I would like to pass in a file descriptor for the UNIX socket to nginx via inheritance from the parent process that starts nginx

Note there can be multiple simultaneous requests to the upstream. How do you expect this to be handled with a single file descriptor?

comment:3 by erik.sjolund@…, 13 months ago

The systemd directive OpenFile takes an optional argument for setting the fd-name. The systemd directive OpenFile can be given multiple times. To have multiple backends in nginx we could use different fd-names. These names are provided to nginx via the environment variable LISTEN_FDNAMES. The names would need to be matched against the same names in the nginx configuration. (Some new syntax is required in the nginx configuration).

nginx could use the function

 int sd_listen_fds_with_names(int unset_environment,
                                    char*** names);

to extract the fd-names from the environment variable LISTEN_FDNAMES
(reference:
https://man7.org/linux/man-pages/man3/sd_listen_fds.3.html )

Copy-paste from the description of the systemd directive OpenFile in the systemd.service man page https://www.freedesktop.org/software/systemd/man/systemd.service.html#OpenFile=

Takes an argument of the form "path[:fd-name:options]", where:

"path" is a path to a file or an AF_UNIX socket in the file system;
"fd-name" is a name that will be associated with the file descriptor; the name may contain any ASCII character, but must exclude control characters and ":", and must be at most 255 characters in length; it is optional and, if not provided, defaults to the file name;

comment:4 by erik.sjolund@…, 13 months ago

I forgot to mention that the systemd socket unit configuration

Accept=no

should be used. That means that nginx will be calling accept().
(reference:
https://www.freedesktop.org/software/systemd/man/systemd.socket.html#Accept=
)

Version 0, edited 13 months ago by erik.sjolund@… (next)

comment:5 by erik.sjolund@…, 13 months ago

Note there can be multiple simultaneous requests to the upstream. How do you expect this to be handled with a single file descriptor?

Ok, now I see your point. This feature request will not work. Sorry for the noise.

comment:6 by Maxim Dounin, 13 months ago

Resolution: invalid
Status: newclosed

Thanks for confirming, closing this.

Note: See TracTickets for help on using tickets.