LINUX.ORG.RU
ФорумAdmin

Let's Encrypt сертификат на связку nginx+apache

 ,


0

1

Есть связка nginx+apache (Centos). Nginx дополнительно выступает в роли балансера, т.е. роутит запросы как на бекэнд c апачем, так и на другие машины с веб-серверами.

Нужно прикрутить сертификат Let's Encrypt к nginx, чтобы nginx слушал не только 80 порт, но и 443, и дальше перенаправлял запросы . Допконфиг для nginx такой (для переадресации на backend):

 upstream backend {
    server 192.168.1.100:8080;
    }

server {
    listen 192.168.1.100:80;
    server_name test1.domen.info www.test1.domen.info;
    server_name test2.domen.info www.test2.domen.info;
    server_name test3.domen.info www.test3.domen.info;


    error_log /var/log/backend-error.log;
    location / {
       proxy_pass http://backend 100;
       proxy_redirect off;
       proxy_set_header Host $host;
    }
}
Чтобы получить сертификат, нужно разрешить сертификационному центру создать временный файл в директории сайта. Но тут сайты лежат в директориях под апачем. Указываю, что директорию /.well-known/acme-challenge создавать в директории nginx и права ему выдаю на его корневую директорию (если я правильно понимаю синтаксис)
/usr/share/nginx/html
. Привожу этот же конфиг к виду:
 upstream backend {
server 192.168.1.100:8080;
}

server  {
   listen 192.168.1.100:80;
    server_name test1.domen.info;
    location / {
       proxy_pass http://backend;
       proxy_redirect off;
       proxy_set_header Host $host;
    }
    location ^~ /.well-known/acme-challenge {
        root /usr/share/nginx/html;
        default_type "text/plain";
        allow all;
    }
    error_log /var/log/backend-error.log;
}
server {
  listen 192.168.1.100:80;
  server_name test2.domen.info www.test2.domen.info;
  access_log /var/log/nginx/test2.domen.info.log;

  location ^~ /.well-known/acme-challenge {
       root /usr/share/nginx/html;
       default_type "text/plain";
       allow all;
       }
location / {
       proxy_pass http://backend;
       proxy_redirect off;
       proxy_set_header Host $host;
    }
    error_log /var/log/backend-error.log;
}
server {
    listen 192.168.1.100:80;
    server_name test3.domen.info;
    location / {
       proxy_pass http://backend;
       proxy_redirect off;
       proxy_set_header Host $host;
    }
    location ^~ /.well-known/acme-challenge {
       root /usr/share/nginx/html;
       default_type "text/plain";
       allow all;
       }
    error_log /var/log/backend-error.log;
}

Из внешки сайты видны.

Certbot ругается, что записать не может в директорию.

certbot certonly --webroot -w /usr/share/nginx/html -d test1.domen.info -d www.test1.domen.info -d test2.domen.info -d www.test2.domen.info -d test3.domen.info -d www.test3.domen.info
...
Failed authorization procedure. test1.domen.info (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://test3.domen.info/.well-known/acme-challenge/0k-67znEKgKl8P_Xx_U5m55mlE7wMcpOj0S9osHcASo: "<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">... 

Подскажите, что поправить в допконфиге.

Ответ на: комментарий от Goury

Права ведь только пользователю можно дать? Пользователя certbot нет... или службе без пользователя тоже? Тогда, подскажите как.

cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:997:995:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
nginx:x:996:994:nginx user:/var/cache/nginx:/sbin/nologin
user:x:1001:1001::/home/user:/sbin/nologin/

manik207 ()
Ответ на: комментарий от manik207

Ещё группы есть.
И пользователя чего угодно можно добавить в любую нужную группу.
А от чего оно там запускается — фиг его знает.

99% что или прав не хватает или оно файлы не туда кладёт где ты раздаёшь их.

Goury ★★★★★ ()

Может там каталог .well-known/acme-challenge создать надо? Для dehydrated точно надо. Насчёт certbot не уверен, поскольку им не пользуюсь, так как он каждый раз генерирует новый приватный ключ.

imul ★★★★★ ()
Ответ на: комментарий от Goury

А от чего оно там запускается — фиг его знает.

top показывает, что запускаю я его от root'а (знаю, что неправильно)

1  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  16796 root      20   0  286632  49440   5828 R  1,7  4,9   0:00.71 certbot 
Когда на чистый Nginx ставила, там тоже от root'а, и всё выполнялось.

Нашла, какой командой certbot проверяет доступность

curl -L http://www.test1.domen.info/.well-known/acme-challenge/example.html 

Действительно, not found... Принимаю любые варианты.

manik207 ()
Ответ на: комментарий от imul

Путь прописан, файл example.html туда положен. При запросе

curl -L http://www.test1.domen.info/.well-known/acme-challenge/example.html 
приходит ответ
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.10.2</center>
</body>
</html>

manik207 ()
Ответ на: комментарий от manik207

Посмотри в /var/log/nginx/error.log (или куда логи пишутся) какой файл пытается отдать nginx и почему не отдаёт.

imul ★★★★★ ()
Ответ на: комментарий от imul

Логи error чистые, в по access'у - соединения проходят.

192.168.1.148 - - [03/May/2017:20:41:41 +0300] "GET /.well-known/acme-challenge/ HTTP/1.0" 404 564 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" "-"
192.168.1.148 - - [03/May/2017:20:41:42 +0300] "GET /favicon.ico HTTP/1.0" 404 209 "http://test1.domen.info/.well-known/acme-challenge/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" "-"

Оставила один сайт, чтобы не путаться, test1.domen.info, в локейшн поменяла путь

 location ^~ /.well-known/acme-challenge {
        root /var/www/test1.domen.info;
        default_type "text/plain";
        allow all;
    }
Создаю index.html в директории ./well-known - по ссылке test1.domen.info/.well-known отображается индексное содержимое. А при создании index.html в директории /.well-known/acme-challenge - 404.

Права на файл

[root@comp acme-challenge]# ls -la
итого 12
drwxrwxr-x+ 2 root root 23 май  3 20:41 .
drwxr-xr-x+ 3 root root 44 май  3 20:40 ..
-rw-rw-r--+ 1 root root 24 май  3 20:41 index.html
[root@comp acme-challenge]# pwd
/var/www/test1.domen.info/.well-known/acme-challenge

Буквы перепроверила - все латиница

manik207 ()
Ответ на: комментарий от manik207

Повторил:

location ^~ /.well-known/acme-challenge {
root /var/www/dehydrated/.well-known/acme-challenge;
}

УМВР
В логах по прежнему чисто?
proxy_pass и т.д. закомментированы?

imul ★★★★★ ()
Ответ на: комментарий от imul

proxy_pass - не закомментированы. При комментировании proxy_pass и указании директории root - все работает. Нужно сохранить проксирование на бекэнд.

Нашла на toster'е похожую проблему, указала проксирование для ./well-known/*, теперь индексный файл отображается в директории ./well-known/acme-challenge.

 upstream backend {
server 192.168.1.100:8080;
}

server  {
   listen 192.168.1.100:80;
   server_name test1.domen.info www.test1.domen.info;
   location / {
       proxy_pass http://backend;
       proxy_redirect off;
       proxy_set_header Host $host;
       }
 location /.well-known/* {
      proxy_pass http://backend/;
      proxy_redirect off;
      proxy_set_header Host $host;
      allow all;
      }
   error_log /var/log/backend-error.log;

Но certbot не выдает сертификат, не может он создать свой временный файл в acme-challenge.

В логах - сплошные access. В общем логе nginx - errors'ах ничего, в access.log - старые данные, переадресации не касаются

192.168.1.148 - - [04/May/2017:07:06:20 +0300] "GET /.well-known/acme-challenge/index.html HTTP/1.0" 200 90 "-" "curl/7.29.0" "-"
192.168.1.148 - - [04/May/2017:07:08:36 +0300] "GET /.well-known/acme-challenge/-TF62Ew5lKazsZlieMlP3IHCwlCbew5ZBRsux_0iYqQ HTTP/1.0" 404 268 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"
192.168.1.148 - - [04/May/2017:07:08:36 +0300] "GET /.well-known/acme-challenge/MSCE85T19d2VR72elKBciW-5Xh3eVVJ2vsmwjOuL8mc HTTP/1.0" 404 268 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" "-"

в логе nginx для конкретного проксирования на бекэнд - в errors чисто, в access.log:

192.168.1.148 - - [04/May/2017:07:33:37 +0300] "GET /.well-known/acme-challenge/ HTTP/1.0" 403 229 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
192.168.1.148 - - [04/May/2017:07:33:38 +0300] "GET /favicon.ico HTTP/1.0" 404 209 "http://test1.domen.info/.well-known/acme-challenge/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"
192.168.1.148 - - [04/May/2017:07:41:11 +0300] "GET /.well-known/acme-challenge/dsbzBXXIq7jkeXC8DZOO89eKEt7BgfShu2avLw3hzZQ HTTP/1.0" 404 268 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
192.168.1.148 - - [04/May/2017:07:41:11 +0300] "GET /.well-known/acme-challenge/D5E4DAI4dyL46gLvGli5hCxaYdzvpvKnLyWFxtOwuhQ HTTP/1.0" 404 268 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"

В errors-логах апача, который бекэнд, именно этого сайта - только такая запись, после того, как я удалила из нее index.html (предположила, что наличие любого файла в

[Wed May 03 20:36:14.178641 2017] [autoindex:error] [pid 4383] [client 192.168.1.100:43954] AH01276: Cannot serve directory /var/www/test1.domen.info/.well-known/: No matching DirectoryIndex (index.php,index.html,index.html.var,index.php) found, and server-generated directory index forbidden by Options directive
[Thu May 04 07:33:37.830834 2017] [autoindex:error] [pid 4384] [client 192.168.1.100:44220] AH01276: Cannot serve directory /var/www/test1.domen.info/.well-known/acme-challenge/: No matching DirectoryIndex (index.php,index.html,index.html.var,index.php) found, and server-generated directory index forbidden by Options directive

Что ещё разрешить, чтобы certbot выдал сертификат?

manik207 ()
Ответ на: комментарий от imul

И ошибка только в логах letsencrypt

FailedChallenges: Failed authorization procedure. www.test1.domen.info (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://www.test1.domen.info/.well-known/acme-challenge/D5E4DAI4dyL46gLvGli5hCxaYdzvpvKnLyWFxtOwuhQ: "<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p", test1.domen.info (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://test1.domen.info/.well-known/acme-challenge/dsbzBXXIq7jkeXC8DZOO89eKEt7BgfShu2avLw3hzZQ: "<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p"

manik207 ()
Ответ на: комментарий от deadNightTiger

Привела конфиг к виду:

 upstream backend {
server 192.168.1.100:8080;
}

server  {
   listen 192.168.1.100:80;
   server_name test1.domen.info www.test1.domen.info;
   location / {
       proxy_pass http://backend;
       proxy_redirect off;
       proxy_set_header Host $host;
       }
 location /.well-known/* {
 #     proxy_pass http://backend/;
 #     proxy_redirect off;
  #    proxy_set_header Host $host;
      allow all;
      }
   error_log /var/log/backend-error.log;
}
До вложенных файлов и директорий достукиваюсь, спасибо. А вот как проксированный путь до сайта указать в запросе certbot? Он по умолчанию (если ничего не указывать) ищет в /var/www/html...

В конфиге nginx можно указать как-то алиас, что если спрашивают .well-known, то искать в /var/www... ?

manik207 ()

Г-ди, сколько же проблем с вашим certbot. Ставишь нормальный клиент, конфиг примерно такой:

upstream acmetool {
    # (Change to port 4402 if using non-root mode.)
    server 127.0.0.1:402;
}

server {
    listen 80;
    listen [::]:80;
    server_name domain.com;

    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    access_log /var/log/nginx/homepage_access.log;
    error_log /var/log/nginx/homepage_error.log;

    server_name domain.com;
    root /var/www/domain.com;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /var/lib/acme/live/domain.com/cert;
    ssl_certificate_key /var/lib/acme/live/domain.com/privkey;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # modern configuration. tweak to your needs.
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /var/lib/acme/live/domain.com/fullchain;

    resolver 8.8.4.4;

    location / {
        index index.html;
    }

    location /.well-known/acme-challenge/ {
        proxy_pass http://acmetool;
    }
}

Deleted ()
Ответ на: комментарий от Deleted

Этот нормальный клиент умеет использовать тот же приватный ключ, или тоже постоянно генерирует новый?

imul ★★★★★ ()
Ответ на: комментарий от manik207

Я бы сделал так:

upstream backend {
server 192.168.1.100:8080;
}

server  {
   listen 192.168.1.100:80;
   server_name test1.domen.info www.test1.domen.info;
   location / {
       proxy_pass http://backend;
       proxy_redirect off;
       proxy_set_header Host $host;
       }
location /.well-known {
   root /home/user/certbot; # без разницы, где будет эта директория, но она должна существовать.
}

А затем выполнял бы certbot:

certbot certonly --webroot -w /home/user/certbot -d test1.domen.info # -d и_т_д...

По моему, сертбот создаёт в директории webroot директорию .well-known со своей вложенной структурой. Локейшн на уровне сервера будет при запросе любого бэкенда.

tetramin ()
Ответ на: комментарий от Deleted

Информация о нормальном клиенте принята, установила его командой

 wget --quiet -O /etc/yum.repos.d/hlandau-acmetool-epel-7.repo 'https://copr.fedorainfracloud.org/coprs/hlandau/acmetool/repo/epel-7/hlandau-acmetool-epel-7.repo' && yum install acmetool -y[
Конфиг поправила на ваш, сертификат получила командой
acmetool want test1.domen.info
Только nginx при таком конфиге не проксирует на апач. И сайт цепляет сертификат ssl, но в окне браузера 403 Forbidden от nginx.

manik207 ()
Ответ на: комментарий от Deleted

При добавлении проксирования на apache путем добавления в конфиг в секцию ssl

 location / {
       proxy_pass http://acmetool;
       proxy_redirect off;
       proxy_set_header Host $host;
       index index.html;
       }
  location /.well-known/acme-challenge/ {
      proxy_pass http://acmetool;
}
браузер выдает ошибку

Сайт test1.domen.info выполнил переадресацию слишком много раз.
Удалите файлы cookie..
ERR_TOO_MANY_REDIRECTS

Мне root нужно указать pass_proxy вместо /var/www/test1.domen.info?

manik207 ()
Ответ на: комментарий от tetramin

Спасибо за ответ

Сделала еще раз по вашему варианту. Если я правильно понимаю логику этого конфига, то корневая директория отдает содержимое бекэнда, а всем кто запросит директорию ./well-known - отдать содержимое

без разницы, где будет эта директория, но она должна существовать

На вашем сервере эта логика работает?

Как я проверяю: Это ветка бекэнда

/var/www/test1.domen.info
    |-----/.well-known 
             |----index.html (Содержимое: Это файл /var/www/test1.domen.info/.well-known/index.html)
             |-----/acme-challenge
                     |----index.html (Это файл /var/www/test1.domen.info/.well-known/acme-challenge/index.html)

Это ветка с любой директорией для certbot

/usr/share/nginx/html
     |-----/.well-known 
             |----index.html (Содержимое: Это файл /usr/share/nginx/html/.well-known/index.html)
             |-----/acme-challenge
                        |----index.html (Это файл /usr/share/nginx/html.well-known/acme-challenge/index.html)

При указанном вами конфиге, у меня все переадресует на бекэнд... Проверяю по содержимому индексных файлов.

manik207 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.