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

NGINX в качестве обратного прокси перед Apache не работает с включенным SSL

Я прочитал все сообщения, руководства и комментарии на форумах, и, хоть убей, не могу заставить прокси-сервер Nginx работать должным образом после включения SSL с помощью блока сервера Nginx.

Apache полностью настроен с виртуальным хостом для обычного и ssl доступа. Apache прослушивает порт 8081 с помощью ports.conf следующим образом:

NameVirtualHost *:8081
Listen 8081

<IfModule ssl_module>
        Listen 443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 443
</IfModule>

Мой SSL apache vhost выглядит следующим образом:

С включенным nginx и закомментированными настройками ssl, как в следующей конфигурации (см. Ниже), все работает нормально, поскольку я могу правильно получить доступ как к SSL, так и к версиям сайта без SSL.

    server {
        listen 80;
  #      listen 443 ssl;
        server_name foobar.net;

   # ssl on;
   #     ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
   #     ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;

        location / {
            proxy_pass http://104.236.224.53:8081;
            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;
        }
    }

Когда я изменяю указанный выше файл и включаю SSL, не комментируя параметры в блоке сервера, возникает конфликт между Nginx и Apache на порту 443?

Обновленные и не прокомментированные серверные блоки выглядят так:

    server {
        listen 80;
        listen 443 ssl;
        server_name foobar.net;

    ssl on;
        ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;

        location / {
            proxy_pass http://104.236.224.53:8081;
            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;
        }
    }

При попытке запустить nginx возвращается следующая ошибка:

 nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Mon 2017-02-20 18:35:20 EST; 16s ago
  Process: 14505 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS
  Process: 14475 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=0/SUCCESS)
  Process: 14671 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)
  Process: 14652 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
 Main PID: 14328 (code=exited, status=0/SUCCESS)

Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use)
Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] still could not bind()
Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Control process exited, code=exited status=1
Feb 20 18:35:20 foo.foobar.net systemd[1]: Failed to start A high performance web server and a reverse proxy server.
Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Unit entered failed state.
Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Failed with result 'exit-code'.

Что мне здесь не хватает в моей реализации, чтобы обеспечить правильную передачу SSL на Apache из Nginx?


Изменить 1: Чтобы обратиться к положительному моменту @Tim, я отредактирую свое основное намерение - заставить Nginx обрабатывать все запросы.

Я следил за конфигурациями, предложенными DigitalOcean: быстро перейдем к их необязательному шагу 9.

Логически на этом этапе, так же, как у меня есть HTTP-хост на apache, который прослушивает порт 8081 для запросов, передаваемых от nginx, я предполагал, что могу сделать то же самое, а также иметь HTTPS-хост на apache, слушать порт 8081 и изящно передавать заголовки в Apache чтобы справиться с остальным. Эта реализация не работала полностью, так как у меня возникла ошибка 400: the plain http request was sent to https port

Я сделал еще один шаг и предположил, что, возможно, поскольку оба Apache HTTP и HTTPS прослушивают порт 8081 сзади, если я назначу apache HTTP на порт 8081 и HTTPS на порт 1443, все будет работать без проблем. Опять же, это не работает полностью, так как когда я пытаюсь получить доступ к своему блогу worpress через HTTPS с этой реализацией, я получаю ошибку

Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.

На данный момент у меня буквально свежие идеи, хотя кажется, что многие получили правильную реализацию, предложенную цифровым океаном. : - /

Вы сказали Apache и Nginx прослушивать порт 443, я полагаю, на одной машине. Только одно приложение может прослушивать порт.

Возможно, вы могли бы отредактировать свой вопрос, чтобы сообщить нам, почему вы хотите использовать и Nginx, и Apache - вы можете делать большинство вещей с любым из них. Так вы можете получить больше полезных советов.

@Robert, ваше решение работало, но не загружало сертификаты SSL в браузере.

Мое решение следующее:

Измените порт по умолчанию для apache с 80 на 8080

Измените порт SSL по умолчанию для apache с 443 на 444

Ниже моя конфигурация ngnix:

server 
{

listen 80;

    server_name servername.com;

location / {

        proxy_pass http://127.0.0.1:8080;
        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;
        expires off;
    }
}


server {

    listen 443 ssl http2;
    server_name servername.com;
    ssl on;
    ssl_certificate /etc/nginx/ssl/keyname.crt;
    ssl_certificate_key /etc/nginx/ssl/private/keyname.key;

location / {

        proxy_pass https://127.0.0.1:444;
        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;
        expires off;
    }
}

Примечание:

  1. proxy_pass необходимо изменить на https в случае использования SSL.
  2. Это отлично работает, когда nginx служит обратным прокси для apache.
  3. Требуется изменить apache vhost для включения 444 вместо 443 для конфигурации SSL.
  4. Настройте ports.conf в apache на 444 для SSL

Похоже, я наконец получил реализацию благодаря всем отзывам, которые я получил от вас. Спасибо @AlexeyTen и @Tim

  • Сначала я отключил https vhost на apache для домена foobar.net sudo a2dissite foobar.net.cong

  • Я отредактировал файл apache ports.conf, чтобы слушать только порт 8081, и удалил прослушивание порта 443:

NameVirtualHost *:8081

Listen 8081
  • Наконец, я отредактировал серверный блок nginx для прослушивания порта 443 и обязательно закомментировал ssl on. Не делать этого не получилось.
> server {
>     listen 80;
>     listen 443 ssl;
>     server_name foobar.net;
> 
>   # ssl on;
>     ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem;
>     ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem;
> 
>     location / {
>         proxy_pass http://104.236.224.53:8081;
>         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;
>     } }

Эта реализация, похоже, работает нормально и без проблем передает обработку php Apache.