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 обрабатывал все запросы.

  • Моим первоначальным намерением было установить Discourse, который сам находится в контейнере Docker, на том же компьютере, где Apache уже использовался в качестве мой основной сервер.
  • Поскольку Discourse требует доступа к порту 80 для правильной работы, рекомендуется предварительно настроить nginx в качестве обратного прокси-сервера для обработки всех входящих запросов, чтобы он передавал их соответствующим образом.
  • Я хочу использовать apache на задней панели для обработки всего динамического содержимого и позволить nginx обрабатывать статические биты. И поэтому я понимаю, что для этого необходимо установить виртуальный хост на apache для каждого экземпляра: запросы http и https. Может, здесь я ошибаюсь?

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

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

. Я пошел дальше и предположил, что опять же, возможно, поскольку оба 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.

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

2
задан 21 February 2017 в 17:07
3 ответа

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

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

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

 NameVirtualHost *: 8081

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

0
ответ дан 3 December 2019 в 11:30

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

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

2
ответ дан 3 December 2019 в 11:30

@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. Требуется изменить vhost apache, чтобы включить 444 вместо 443 для конфигурации SSL.
  4. Настройте ports.conf в apache на 444 для SSL
]
0
ответ дан 3 December 2019 в 11:30

Теги

Похожие вопросы