IT story

nginx 400 "일반 HTTP 요청이 HTTPS 포트로 전송되었습니다"오류 처리

hot-time 2020. 8. 9. 09:41
반응형

nginx 400 "일반 HTTP 요청이 HTTPS 포트로 전송되었습니다"오류 처리


승객 / nginx 뒤에서 Sinatra 앱을 실행하고 있습니다. http 및 https 호출에 모두 응답하도록 노력하고 있습니다. 문제는 둘 다 서버 블록에 정의 된 경우 https 호출이 정상적으로 응답되지만 http는 400 "일반 HTTP 요청이 HTTPS 포트로 전송되었습니다"오류를 생성한다는 것입니다. 이것은 정적 페이지 용이므로 Sinatra가 이것과 아무 관련이 없다고 생각합니다. 이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

다음은 서버 블록입니다.

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;
}

비슷한 문제가 발생했습니다. 한 서버에서 작동하며 동일한 Nginx 구성을 가진 다른 서버에서는 작동하지 않습니다. 여기에서 Igor가 답변 한 솔루션을 찾았습니다. 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

}

연결 보안에 관계없이 http를 통해 페이지를 제공 할 수 있도록 '이 연결 HTTPS'테스트를 대부분 무시한다는 점에서 위의 답변은 올바르지 않습니다.

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...
}

I had the exact same issue, I have kind of the same configuration as your exemple and I got it working by removing the line :

ssl on;

To quote the doc:

If HTTP and HTTPS servers are equal, a single server that handles both HTTP and HTTPS requests may be configured by deleting the directive “ssl on” and adding the ssl parameter for *:443 port


According to wikipedia article on status codes. Nginx has a custom error code when http traffic is sent to https port(error code 497)

And according to nginx docs on error_page, you can define a URI that will be shown for a specific error.
Thus we can create a uri that clients will be sent to when error code 497 is raised.

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;
    }
}

However if a client makes a request via any other method except a GET, that request will be turned into a GET. Thus to preserve the request method that the client came in via; we use error processing redirects as shown in nginx docs on error_page

And thats why we use the 301 =307 redirect.

Using the nginx.conf file shown here, we are able to have http and https listen in on the same port


Here is an example to config HTTP and HTTPS in same config block with ipv6 support. The config is tested in Ubuntu Server and NGINX/1.4.6 but this should work with all servers.

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;
}

Don't include ssl on which may cause 400 error. The config above should work for

http://example.com

http://www.example.com

https://example.com

https://www.example.com

Hope this helps!


if use phpmyadmin add: fastcgi_param HTTPS on;


Actually you can do this with:

ssl off; 

This solved my problem in using nginxvhosts; now I am able to use both SSL and plain HTTP. Works even with combined ports.


Ref https://serversforhackers.com/c/redirect-http-to-https-nginx

i had i similar issues like

http://www.example.com giving 400 error The plain HTTP request was sent to HTTPS but

if i type https://www.example.com it was working fine,

i wanted slove and redirect http to https automatically when user enter http://www.example.com

solution is

i made two server blocks one for port 80 and another for 443 ssl in port 80 block follow the below procedure

server {
    listen 80;

    server_name example.com, www.example.com;

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

and another server block for port 443 for ssl configuration

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...
} 

참고URL : https://stackoverflow.com/questions/8768946/dealing-with-nginx-400-the-plain-http-request-was-sent-to-https-port-error

반응형