Работа с nginx 400 «Ошибка простого HTTP-запроса на порт HTTPS» - PullRequest
104 голосов
/ 07 января 2012

Я управляю приложением 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;
}

Ответы [ 9 ]

189 голосов
/ 11 января 2012

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

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

server {
  listen 80;
  listen 443 default ssl;

  # ssl on   - remember to comment this out

}
30 голосов
/ 27 сентября 2012

Приведенные выше ответы неверны в том смысле, что большинство тестов «Это соединение HTTPS» чаще всего позволяют обслуживать страницы через http независимо от безопасности соединения.

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

ОП должен использовать:

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;

  [....]
}
17 голосов
/ 07 января 2012

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

Обходной путь очень прост. Вам нужно две server секции:

server {
  listen 80;

  // other directives...
}

server {
  listen 443;

  ssl on;
  // SSL directives...

  // other directives...
}
12 голосов
/ 22 ноября 2012

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

ssl on;

Чтобы процитировать документ:

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

11 голосов
/ 04 февраля 2015

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

. В соответствии с документами nginx на странице 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;
    }
}

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

И именно поэтому мы используем перенаправление 301 =307.

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

7 голосов
/ 01 января 2016

Ниже приведен пример настройки 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

Надеюсь, это поможет!

4 голосов
/ 31 марта 2012

если используется phpmyadmin, добавьте: fastcgi_param HTTPS on;

4 голосов
/ 20 февраля 2012

На самом деле вы можете сделать это с помощью:

ssl off; 

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

0 голосов
/ 08 марта 2019

Ссылка https://serversforhackers.com/c/redirect-http-to-https-nginx

У меня были схожие проблемы, такие как

http://www.example.com, дающие 400 error The plain HTTP request was sent to HTTPS, но

, если янаберите https://www.example.com все работало нормально,

я хотел использовать словарь и автоматически перенаправлять http на https, когда пользователь вводит http://www.example.com

решение -

я сделал два серверных блока, один для порта 80 и другой для 443 ssl в блоке порта 80, следуя приведенной ниже процедуре

server {
    listen 80;

    server_name example.com, www.example.com;

    return 301 https://$host$request_uri;
}

и еще один серверный блок для порта 443 для конфигурации ssl

server {
    location = /favicon.ico { access_log off; log_not_found off; }


    listen [::]:443 ipv6only=on default_server ssl;
    listen 443 ssl;
    ssl on;
    ssl_certificate /home/hemanth/examp_com/example.crt;
    ssl_certificate_key /home/hemanth/ssl/example.com.key;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    # add here the ip address of your server
    # or a domain pointing to that ip (like example.com or www.example.com)
    server_name www.example.com;
    // continure rest code...
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...