Дело с nginx 400" простой HTTP-запрос был отправлен на порт HTTPS " ошибка

Я запускаю приложение Sinatra за пассажиром / nginx. Я пытаюсь заставить его отвечать на вызовы http и https. Проблема в том, что когда оба определены в блоке сервера, https-вызовы обычно отвечают, но http дает ошибку 400 "простой HTTP-запрос был отправлен на порт HTTPS". Это для статической страницы, поэтому я предполагаю, что Синатра не имеет к этому никакого отношения. Есть идеи, как это исправить?

вот серверный блок:

server {
        listen 80;
        listen 443  ssl;
        server_name localhost;
        root /home/myhome/app/public;
        passenger_enabled on;

        ssl on;
        ssl_certificate      /opt/nginx/ssl_keys/ssl.crt;
        ssl_certificate_key  /opt/nginx/ssl_keys/ssl.key;
        ssl_protocols        SSLv3 TLSv1;
        ssl_ciphers          HIGH:!aNULL:!MD5;

        location /static {
            root  /home/myhome/app/public;
            index  index.html index.htm index.php;
        }

        error_page 404 /404.html;

        # redirect server error pages to the static page /50x.html
        error_page 500 /500.html;

        access_log /home/myhome/app/logs/access.log;
        error_log /home/myhome/app/logs/error.log;
}

8 ответов


я столкнулся с подобной проблемой. Он работает на одном сервере и не работает на другом сервере с той же конфигурацией Nginx. Нашел решение, которое отвечает Игорь здесь http://forum.nginx.org/read.php?2,1612,1627#МСГ-1627

да. Или вы можете объединить серверы SSL / non-SSL на одном сервере:

server {
  listen 80;
  listen 443 default ssl;

  # ssl on   - remember to comment this out

}

приведенные выше ответы неверны в том, что большинство из них используют тест "является ли это соединение HTTPS", чтобы разрешить обслуживание страниц по http независимо от безопасности соединения.

безопасный ответ, используя страницу ошибки на nginx конкретный код ошибки http 4xx для перенаправления клиента, чтобы повторить тот же запрос на https. (как описано здесь https://serverfault.com/questions/338700/redirect-http-mydomain-com12345-to-https-mydomain-com12345-in-nginx )

OP следует использовать:

server {
  listen        12345;
  server_name   php.myadmin.com;

  root         /var/www/php;

  ssl           on;

  # If they come here using HTTP, bounce them to the correct scheme
  error_page 497 https://$host:$server_port$request_uri;

  [....]
}

ошибка говорит все это на самом деле. Ваша конфигурация сообщает Nginx прослушивать порт 80 (HTTP) и использовать SSL. При наведении браузера на http://localhost, он пытается подключиться через HTTP. Поскольку Nginx ожидает SSL, он жалуется на ошибку.

решение очень простое. Вам нужно два server разделы:

server {
  listen 80;

  // other directives...
}

server {
  listen 443;

  ssl on;
  // SSL directives...

  // other directives...
}

У меня была такая же проблема, у меня такая же конфигурация, как у вашего exemple, и я получил ее, удалив строку:

ssl on;

процитировать doc:

если серверы HTTP и HTTPS равны, один сервер, который обрабатывает запросы HTTP и HTTPS, может быть настроен путем удаления директивы "ssl on" и добавления параметра ssl для порта *:443


по данным статья Википедии о кодах статуса. Nginx имеет пользовательский код ошибки, когда HTTP-трафик отправляется на порт https (код ошибки 497)

и по nginx docs on error_page, вы можете определить URI, который будет отображаться для конкретной ошибки.
Таким образом, мы можем создать uri, на который будут отправляться клиенты при возникновении кода ошибки 497.

nginx.conf

#lets assume your IP address is 89.89.89.89 and also 
#that you want nginx to listen on port 7000 and your app is running on port 3000

server {
    listen 7000 ssl;

    ssl_certificate /path/to/ssl_certificate.cer;
    ssl_certificate_key /path/to/ssl_certificate_key.key;
    ssl_client_certificate /path/to/ssl_client_certificate.cer;

    error_page 497 301 =307 https://89.89.89.89:7000$request_uri;

    location / {
        proxy_pass http://89.89.89.89:3000/;

        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Protocol $scheme;
    }
}

однако если клиент делает запрос через любой другой способ Если вам этот запрос будет сделать. Таким образом, чтобы сохранить метод запроса, который клиент пришел через; Мы используем перенаправление обработки ошибок, как показано в nginx docs on error_page

и именно поэтому мы используем 301 =307 редирект.

использование nginx.conf файл, показанный здесь, мы можем иметь http и https слушать в том же порту


вот пример для config адресу http и HTTPS в том же конфигурационном блоке с протокол IPv6 поддержка. Конфигурация тестируется в Ubuntu Server и NGINX / 1.4.6 но это должно работать со всеми серверами.

server {
    # support http and ipv6
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    # support https and ipv6
    listen 443 default_server ssl;
    listen [::]:443 ipv6only=on default_server ssl;

    # path to web directory
    root /path/to/example.com;
    index index.html index.htm;

    # domain or subdomain
    server_name example.com www.example.com;

    # ssl certificate
    ssl_certificate /path/to/certs/example_com-bundle.crt;
    ssl_certificate_key /path/to/certs/example_com.key;

    ssl_session_timeout 5m;

    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
    ssl_prefer_server_ciphers on;
}

не входить ssl on что может привести к 400 ошибка. Конфигурация выше должна работать для

http://example.com

http://www.example.com

https://example.com

https://www.example.com

надеюсь, что это помогает!


Если использовать phpmyadmin добавить: FASTCGI_PARAM HTTPS on;


на самом деле вы можете сделать это с:

ssl off; 

это решило мою проблему в использовании nginxvhosts; теперь я могу использовать как SSL, так и простой HTTP. Работает даже с комбинированными портами.