Назад | Перейти на главную страницу

Конфигурация nginx с использованием переменной в пути ssl_certificate вызывает ошибку разрешений

Блок сервера конфигурации nginx:

localhost:/etc/nginx$ cat nginx.conf | grep -B 3 -A 6 '$ssl_server_name'
  server {
    listen 443 ssl http2 default_server;

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

    location / {
      include /etc/nginx/snippets/set-headers.conf;
      proxy_pass http://localhost:8080;
    }
  }

Это используя переменную $ ssl_server_name в директивах сертификата, который поддерживается начиная с nginx 1.15.9. Соответствующая часть документы nginx.

Конфигурация передает nginx -t и загружается без проблем, но страница не загружается в браузере, и есть ошибка с отказом в разрешениях при открытии сертификата в error.log, даже если nginx работает как root:

localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/error.log
2019/06/19 18:51:47 [error] 5676#5676: *251 cannot load certificate "/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem','r') error:2006D002:BIO routines:BIO_new_file:system lib) while SSL handshaking, client: [IP ADDRESS REDACTED], server: 0.0.0.0:443
localhost:/etc/nginx$ ps -ef | grep nginx | grep -v grep
www-data  5676 24653  0 18:49 ?        00:00:00 nginx: worker process
root     24653     1  0 15:08 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
localhost:/etc/nginx$ sudo ls -l /etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem
lrwxrwxrwx 1 root root 56 Apr 17 18:53 /etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem -> ../../archive/[DOMAIN NAME REDACTED]/fullchain1.pem
localhost:/etc/nginx$ sudo ls -l /etc/letsencrypt/archive/[DOMAIN NAME REDACTED]/fullchain1.pem
-rw-r--r-- 1 root root 3591 Apr 17 18:53 /etc/letsencrypt/archive/[DOMAIN NAME REDACTED]/fullchain1.pem
localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/error.log
2019/06/19 18:51:47 [error] 5676#5676: *251 cannot load certificate "/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem','r') error:2006D002:BIO routines:BIO_new_file:system lib) while SSL handshaking, client: [IP ADDRESS REDACTED], server: 0.0.0.0:443
localhost:/etc/nginx$ ps -ef | grep nginx | grep -v grep
www-data  5676 24653  0 18:49 ?        00:00:00 nginx: worker process
root     24653     1  0 15:08 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
localhost:/etc/nginx$ sudo ls -l /etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem
lrwxrwxrwx 1 root root 56 Apr 17 18:53 /etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem -> ../../archive/[DOMAIN NAME REDACTED]/fullchain1.pem
localhost:/etc/nginx$ sudo ls -l /etc/letsencrypt/archive/[DOMAIN NAME REDACTED]/fullchain1.pem
-rw-r--r-- 1 root root 3591 Apr 17 18:53 /etc/letsencrypt/archive/[DOMAIN NAME REDACTED]/fullchain1.pem
localhost:/etc/nginx$ openssl
OpenSSL> version
OpenSSL 1.0.2g  1 Mar 2016
OpenSSL> ^C
localhost:/etc/nginx$ nginx -v
nginx version: nginx/1.17.0

Когда я заменяю $ ssl_server_name на имя домена в конфигурации nginx, тогда нет ошибки разрешений при чтении того же самого файла сертификата, и страница загружается в браузере.

Почему использование переменной в пути сертификата не работает?

ОБНОВИТЬ:

Я обновил группу папок архива до www-data, но все еще вижу ошибку разрешений:

localhost:/etc/nginx$ sudo chgrp -R www-data /etc/letsencrypt/archive
localhost:/etc/nginx$ sudo namei -l /etc/letsencrypt/archive/[DOMAIN NAME REDACTED]/fullchain1.pem
f: /etc/letsencrypt/archive/[DOMAIN NAME REDACTED]/fullchain1.pem
drwxr-xr-x root root     /
drwxr-xr-x root root     etc
drwxr-xr-x root root     letsencrypt
drwx------ root www-data archive
drwxr-xr-x root www-data [DOMAIN NAME REDACTED]
-rw-r--r-- root www-data fullchain1.pem
localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/error.log
2019/06/20 07:18:58 [error] 4897#4897: *6 cannot load certificate "/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem','r') error:2006D002:BIO routines:BIO_new_file:system lib) while SSL handshaking, client: [IP ADDRESS REDACTED], server: 0.0.0.0:443

ОБНОВЛЕНИЕ 2:

Добавлены групповые права на чтение и выполнение для папки архива, при этом ошибка разрешений все еще сохраняется:

localhost:/etc/nginx$ sudo chmod g+r /etc/letsencrypt/archive
localhost:/etc/nginx$ sudo chmod g+x /etc/letsencrypt/archive
localhost:/etc/nginx$ sudo namei -l /etc/letsencrypt/archive/ [DOMAIN NAME REDACTED]/fullchain1.pem
f: /etc/letsencrypt/archive/[DOMAIN NAME REDACTED]/fullchain1.pem
drwxr-xr-x root root     /
drwxr-xr-x root root     etc
drwxr-xr-x root root     letsencrypt
drwxr-x--- root www-data archive
drwxr-xr-x root www-data  [DOMAIN NAME REDACTED]
-rw-r--r-- root www-data fullchain1.pem
localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/error.log
2019/06/20 07:39:58 [error] 4897#4897: *22 cannot load certificate "/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/etc/letsencrypt/live/ [DOMAIN NAME REDACTED]/fullchain.pem','r') error:2006D002:BIO routines:BIO_new_file:system lib) while SSL handshaking, client: [IP ADDRESS REDACTED], server: 0.0.0.0:443

ОБНОВЛЕНИЕ 3:

Пытался стать www-данными с помощью sudo, но получил ошибку:

localhost:/etc/nginx$ sudo su - www-data
No directory, logging in with HOME=/
This account is currently not available.

Обновление 4:

Я также обновил разрешения для живой папки с символической ссылкой, все еще наблюдая ошибку разрешений:

localhost:/etc/nginx$ ll /etc/letsencrypt | grep live
drwx------   5 root root     4096 Apr 17 18:53 live/
localhost:/etc/nginx$ sudo chgrp www-data /etc/letsencrypt/live
localhost:/etc/nginx$ sudo chmod g+rx /etc/letsencrypt/live
localhost:/etc/nginx$ ll /etc/letsencrypt | grep live
drwxr-x---   5 root www-data 4096 Apr 17 18:53 live/
localhost:/etc/nginx$ sudo namei -l /etc/letsencrypt/live
f: /etc/letsencrypt/live
drwxr-xr-x root root     /
drwxr-xr-x root root     etc
drwxr-xr-x root root     letsencrypt
drwxr-x--- root www-data live
localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/error.log
2019/06/20 07:57:48 [error] 5104#5104: *17 cannot load certificate key "/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/privkey.pem": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/privkey.pem','r') error:2006D002:BIO routines:BIO_new_file:system lib) while SSL handshaking, client: [IP ADDRESS REDACTED], server: 0.0.0.0:443

Обновление 5:

Список разрешений для всех каталогов в пути, включая символические ссылки:

localhost:/etc/nginx$ sudo namei -l /etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem
f: /etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem
drwxr-xr-x root root     /
drwxr-xr-x root root     etc
drwxr-xr-x root root     letsencrypt
drwxr-x--- root www-data live
drwxr-xr-x root root     [DOMAIN NAME REDACTED]
lrwxrwxrwx root root     fullchain.pem -> ../../archive/[DOMAIN NAME REDACTED]/fullchain1.pem
drwxr-x--- root www-data   ..
drwxr-xr-x root root       ..
drwxr-x--- root www-data   archive
drwxr-xr-x root www-data   [DOMAIN NAME REDACTED]
-rw-r--r-- root www-data   fullchain1.pem

Обновление 6:

Пытался временно изменить оболочку для пользователя www-data, стал www-data с помощью sudo и проверил, что чтение сертификата возможно, но ошибка разрешения все еще происходит:

localhost:/etc/nginx$ cat /etc/passwd | grep www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
localhost:/$ cat /etc/passwd | grep www-data
www-data:x:33:33:www-data:/var/www:/bin/bash
localhost:/etc/nginx$ sudo vim /etc/passwd
localhost:/etc/nginx$ sudo su - www-data
No directory, logging in with HOME=/
localhost:01:/$ whoami
www-data
localhost:/$ cat /etc/letsencrypt/live/[DOMAIN NAME REDACTED]/fullchain.pem
-----BEGIN CERTIFICATE-----
[REDACTED CERT]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[REDACTED CERT]
-----END CERTIFICATE-----
localhost:/$ exit
logout
localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/error.log
2019/06/20 08:40:23 [error] 5259#5259: *14 cannot load certificate key "/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/privkey.pem": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/etc/letsencrypt/live/[DOMAIN NAME REDACTED]/privkey.pem','r') error:2006D002:BIO routines:BIO_new_file:system lib) while SSL handshaking, client: [IP ADDRESS REDACTED], server: 0.0.0.0:443

Обновление 7:

Пытался экспортировать сертификаты в другую папку:

localhost:/etc/nginx$ mkdir /tmp/exported-certs
localhost:/etc/nginx$ sudo rsync -razL /etc/letsencrypt/live/ /tmp/exported-certs
localhost:/etc/nginx$ sudo ls -l /tmp/exported-certs/[DOMAIN NAME REDACTED]/fullchain.pem
-rw-r--r-- 1 root www-data 3591 Apr 17 18:53 /tmp/exported-certs/[DOMAIN NAME REDACTED]/fullchain.pem
localhost:/etc/nginx$ sudo ls -l /tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem
-rw------- 1 root www-data 1704 Apr 17 18:53 /tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem
localhost:/etc/nginx$ sudo namei -l /tmp/exported-certs/[DOMAIN NAME REDACTED]/fullchain.pem
f: /tmp/exported-certs/[DOMAIN NAME REDACTED]/fullchain.pem
drwxr-xr-x root root     /
drwxrwxrwt root root     tmp
drwxr-x--- root www-data exported-certs
drwxr-xr-x root root     [DOMAIN NAME REDACTED]
-rw-r--r-- root www-data fullchain.pem
localhost:/etc/nginx$ sudo vim nginx.conf
localhost:/etc/nginx$ cat nginx.conf | grep -B 3 -A 6 '$ssl_server_name'
  server {
    listen 443 ssl http2 default_server;

    ssl_certificate /tmp/exported-certs/$ssl_server_name/fullchain.pem;
    ssl_certificate_key /tmp/exported-certs/$ssl_server_name/privkey.pem;

    location / {
      include /etc/nginx/snippets/set-headers.conf;
      proxy_pass http://localhost:8080;
    }
  }
localhost:/etc/nginx$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
localhost:/etc/nginx$ sudo nginx -s reload
localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/error.log
2019/06/20 10:52:48 [notice] 6250#6250: signal process started
localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/error.log
2019/06/20 10:53:08 [error] 6251#6251: *67 cannot load certificate key "/tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem','r') error:2006D002:BIO routines:BIO_new_file:system lib) while SSL handshaking, client: [IP ADDRESS REDACTED], server: 0.0.0.0:443

Затем решил снова проверить как пользователь www-data, потому что в последний раз я проверял, когда сертификаты находились в папке letsencrypt, также на этот раз я не забыл проверить и сертификат, и ключ:

localhost:/etc/nginx$ cat /etc/passwd | grep www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
localhost:/etc/nginx$ sudo vim /etc/passwd
localhost:/etc/nginx$ cat /etc/passwd | grep www-data
www-data:x:33:33:www-data:/var/www:/bin/bash
localhost:/etc/nginx$ sudo su - www-data
No directory, logging in with HOME=/
localhost:/$ cat /tmp/exported-certs/[DOMAIN NAME REDACTED]/fullchain.pem
-----BEGIN CERTIFICATE-----
[CERT REDACTED]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[CERT REDACTED]
-----END CERTIFICATE-----
localhost:/$ cat /tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem
cat: /tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem: Permission denied   <---- THERE IT IS!
localhost:/$ ls -l /tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem
-rw------- 1 root www-data 1704 Apr 17 18:53 /tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem
localhost:/$ exit
logout
localhost:/etc/nginx$ sudo chmod g+r /tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem
localhost:/etc/nginx$ sudo su - www-data
No directory, logging in with HOME=/
localhost:/$ cat /tmp/exported-certs/[DOMAIN NAME REDACTED]/privkey.pem
-----BEGIN PRIVATE KEY-----
[CERT REDACTED]
-----END PRIVATE KEY-----
localhost:/$ exit
logout
localhost:/etc/nginx$ sudo tail -n 1 /var/log/nginx/access.log
139.162.202.226 - [DOMAIN NAME REDACTED]:443 - [20/Jun/2019:11:04:08 +0100] "GET / HTTP/2.0" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15"

Как только я добавил групповое разрешение на чтение www-данных в privkey.pem, браузер смог загрузить страницу. :)

Спасибо всем, кто прокомментировал этот вопрос.

Хорошо, спасибо за отзыв в комментарии. Позвольте мне поделиться двумя идеями - не прямым решением того, что вы упомянули, но возможными обходными путями ....

подготовить вместо ссылки

Я использую в каком-то конкретном случае certbot (Я думаю так же, как ты) и haproxy. У меня есть задание cron, запускающее certbot с certonly, и в случае выдачи сертификата он объединяет сертификат и ключ (предпочтительнее один файл) и копирует в место, где haproxy ожидайте это в конфигурации. В haproxy после этого перезапускается. В случае, если вы не решите его и вам нужно, чтобы он работал, можно попробовать «подготовить» сертификат для nginx где-нибудь вместо ссылки на "исходное" местоположение ...

запустить certbot как пользователь www-data

вы можете запустить certbot как пользователь, который запускает nginx (www-data), чтобы результат соответствовал этой цели с точки зрения разрешения. В этом случае вам нужно сначала сменить владельца для структуры вокруг - например, /etc/letsencrypt/account....