Дозволяє шифрувати із зворотним проксі-сервером nginx


45

Вступ

У мене є сервер розробників (на даний момент працює Ubuntu 14.04 LTS), який я вже деякий час використовую для розміщення різних інструментів розробки на різних портах. Оскільки порти важко запам’ятати, я вирішив використовувати порт 80 для всіх своїх послуг і робити переадресацію портів внутрішньо, виходячи з імені хоста.

Замість того, щоб писати домен.com:5432, я можу просто отримати доступ до нього через sub.domain.com

Наприклад, додаток X, який використовує порт 7547 і працює на sub.domain.com, має таку конфігурацію nginx:

upstream sub {
    server 127.0.0.1:7547;
}

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    access_log /var/log/nginx/sub.log combined;
    location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:7547;
            proxy_set_header Authorization "";
    }
}

Питання

З огляду на поточну структуру конфігурації, яку я вибрав, чи можна використовувати letsencrypt та запускати різні сервіси під https?


3
Я написав повідомлення в блозі на цю тему: tom.busby.ninja/letsecnrypt-nginx-reverse-proxy-no-downtime
Tom Busby

Відповіді:


81

Так, ви можете мати запити проксі-сервера nginx до серверів HTTP, а потім відповідати клієнтам через HTTPS. Роблячи це, ви хочете бути впевнені, що nginx <-> проксі-з'єднання навряд чи буде понюхано тим, хто є вашим очікуваним зловмисником. Досить безпечні підходи можуть включати:

  • доступ до того ж хоста (як і ви)
  • доступ до інших хостів за вашим брандмауером

Шлях до іншого хоста в загальнодоступному Інтернеті навряд чи буде достатньо безпечним.

Ось інструкції щодо отримання сертифіката Let Encrypt за допомогою того самого веб-сервера, який ви використовуєте як проксі.

Запит початкового сертифіката від Let’s Encrypt

Змініть serverположення, щоб дозволити подання підкаталогу .well-knownз локального каталогу, наприклад:

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    […]
    location /.well-known {
            alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here
        […]
    }
}

http://sub.domain.com/.well-known саме там сервери Let’s Encrypt шукатимуть відповіді на проблеми, які вона викликає.

Потім ви можете використовувати клієнт certbot, щоб запитувати сертифікат у Let's Encrypt за допомогою плагіну webroot (як root):

certbot certonly --webroot -w /var/www/sub.domain.com/ -d sub.domain.com -d www.sub.domain.com

Ваш ключ, сертифікат та ланцюжок сертифікатів тепер будуть встановлені в /etc/letsencrypt/live/sub.domain.com/

Налаштування nginx для використання вашого сертифіката

Спочатку створіть новий серверний пункт так:

server {
    listen 443 ssl;

    # if you wish, you can use the below line for listen instead
    # which enables HTTP/2
    # requires nginx version >= 1.9.5
    # listen 443 ssl http2;

    server_name sub.domain.com www.sub.domain.com;

    ssl_certificate /etc/letsencrypt/live/sub.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sub.domain.com/privkey.pem;

    # Turn on OCSP stapling as recommended at 
    # https://community.letsencrypt.org/t/integration-guide/13123 
    # requires nginx version >= 1.3.7
    ssl_stapling on;
    ssl_stapling_verify on;

    # Uncomment this line only after testing in browsers,
    # as it commits you to continuing to serve your site over HTTPS
    # in future
    # add_header Strict-Transport-Security "max-age=31536000";

    access_log /var/log/nginx/sub.log combined;

    # maintain the .well-known directory alias for renewals
    location /.well-known {
        alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here as in your port 80 configuration
        […]
    }
}

Перезавантажити nginx:

service nginx reload

Переконайтеся , що HTTPS тепер працює за адресою https://sub.domain.comі https://www.sub.domain.comв Вашому браузері (і інші браузери ви спеціально хочете підтримати) і перевірити , що вони не повідомляють про помилки сертифікатів.

Рекомендовано: також перегляньте raymii.org: Сильна безпека SSL на nginx і протестуйте конфігурацію в лабораторіях SSL .

(Рекомендовано) Перенаправлення HTTP-запитів на HTTPS

Після того, як ви підтвердите, що ваш сайт працює з https://версією URL-адреси, замість того, щоб деякі користувачі подавали незахищений вміст, оскільки вони перейшли http://sub.domain.com, перенаправляйте їх на HTTPS-версію сайту.

Замініть весь serverпункт 80 порта на:

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    rewrite     ^   https://$host$request_uri? permanent;
}

Тепер вам також слід відмітити цей рядок у конфігурації порту 443, щоб браузери пам'ятали навіть не пробувати HTTP-версію сайту:

add_header Strict-Transport-Security "max-age=31536000";

Автоматично поновіть ваш сертифікат

Ви можете використовувати цю команду (як root) для відновлення всіх сертифікатів, відомих certbot, та перезавантаження nginx за допомогою нового сертифіката (який матиме той самий шлях, що і ваш існуючий сертифікат):

certbot renew --renew-hook "service nginx reload"

certbot намагатиметься поновити сертифікати, старші за 60 днів, тому безпечно (і рекомендується!) виконувати цю команду дуже регулярно та автоматично, якщо це можливо. Наприклад, ви можете ввести таку команду /etc/crontab:

# at 4:47am/pm, renew all Let's Encrypt certificates over 60 days old
47 4,16   * * *   root   certbot renew --quiet --renew-hook "service nginx reload"

Ви можете протестувати оновлення за допомогою "сухого запуску", який зв’яжеться з сервісами "Давайте шифруємо", щоб зробити справжній тест на зв'язок з вашим доменом, але отримані сертифікати не зберігатимуться:

certbot --dry-run renew

Або ви можете змусити скоріше відновити:

certbot renew --force-renew --renew-hook "service nginx reload"

Примітка. Ви можете запускати сухий пробіг стільки разів, скільки вам потрібно, але реальні оновлення залежать від обмежень швидкості Let’s Encrypt .


Здається, ваш солютон не працює на мене. У мене в основному однакова конфігурація. Вона працює для goopen.tk, але не www.goopen.tk
Alko

3
@Alko, вказівки відповіді правильні та висвітлюють це питання. Використовуючи certbotчи будь-який інший інструмент, ви не можете забути вказати свій домен у форматі www і не www.
Paulo Coghi

Під location /.well-known, вам потрібно залишити .well-knownшлях. Використовуйте alias /var/www/sub.domain.com, неalias /var/www/sub.domain.com/.well-known
gldraphael

1
Хтось може мені пояснити, чому ви хочете використовувати "переписати ^ https: // $ host $ request_uri? Permanent;" тут замість "повернути 301 https: // $ server_name $ request_uri;"
ZaxLofful

Я виявив, що мені потрібні цитати навколо шляху в розташуванні. location '/.well-known' {. Не впевнений, чи це версія з версією чи просто моя установка, але у випадку, якщо хтось інший застряг.
Франк V

2

Так, ви можете використовувати nginxяк кінцеву точку https та співпрацювати з backends через http. Наприклад, моя конфігурація:

server {
        server_name host;
        listen 443 ssl;
...
 location /svn/ {
            auth_ldap off;

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            proxy_pass http://localhost:1080/svn/;
            proxy_redirect http://localhost:1080/ https://host/;
        }
...
}

Але, як я знаю, за допомогою шифрування ви повинні вказати всі субдомени, коли отримаєте сертифікат, і якщо це проблема, то ви виберете URL https://host/serviceзамістьhttps://service.host

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.