Opened 2 weeks ago

Closed 2 weeks ago

#2372 closed enhancement (wontfix)

nginx -t does not indicate potential permissions error for SSL certificates

Reported by: cricalix@… Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.18.x
Keywords: Cc:
uname -a: Linux www 5.15.0-41-generic #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 3.0.2 15 Mar 2022
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -ffile-prefix-map=/build/nginx-9P0wNJ/nginx-1.18.0=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-compat --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --add-dynamic-module=/build/nginx-9P0wNJ/nginx-1.18.0/debian/modules/http-geoip2 --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_sub_module

Description

nginx -h states that '-t' tests the configuration.

Given a configuration of (deliberately truncated to relevant parts)

ssl.conf:

    ssl_certificate /etc/letsencrypt/live/$ssl_server_name/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$ssl_server_name/privkey.pem;

nginx.conf:

user www-data;
http {
  server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;
    include ssl.conf;
  }
}

'nginx -t' will state that this configuration is fine.

However, at runtime, handshaking fails with

[error] 26787#26787: *1 cannot load certificate 
"/etc/letsencrypt/live/example.com/fullchain.pem": 
BIO_new_file() failed (SSL: error:8000000D:system library::Permission denied:calling fopen(
  /etc/letsencrypt/live/example.com/fullchain.pem, r) 
error:10080002:BIO routines::system lib) while SSL handshaking, 
client: 10.68.0.1, server: 0.0.0.0:443

'nginx -t' already validates that it can find the certificates when the path does not contain a variable. Referencing paths that don't exist will result in a "no such file or directory" error.

As such, it would be nice if nginx would check variable paths as if it were the unprivileged user and report the same permission denied error at test time instead of at request-handling time.

Change History (1)

comment:1 by Maxim Dounin, 2 weeks ago

Resolution: wontfix
Status: newclosed

When you are using variables in the certificate file name, the name is only known at runtime, and hence nginx cannot load and validate the certificate (if it is available or not, and if it is actually a certificate) while testing the configuration. That's one of the reasons why static configuration is preferred unless you have to use variables.

While it is theoretically possible to extract static prefix from the certificate path and try to test if the relevant directories exists and searchable, it does not look like it worth the effort. Further, it might be seen as incorrect: the certificate is expected to exists and be available during an SSL handshake, and there are no reasons to reject the configuration if some directories do not exists before the actual handshake happens.

Note: See TracTickets for help on using tickets.