2012-01-07 65 views
84

我跑後面乘客/ nginx的一個屈應用程序。我試圖讓它響應http和https呼叫。問題是,當兩者都在服務器塊中定義時,https調用通常會得到響應,但http會產生400「普通HTTP請求已發送到HTTPS端口」錯誤。這是一個靜態頁面,所以我猜測Sinatra與此無關。有想法該怎麼解決這個嗎?nginx的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; 
} 
+0

我建議你接受@bobojam給出的答案 – 2012-12-27 08:47:23

+0

在我的情況是,瀏覽器中的URL:'my.example.com:443'不起作用。改爲「https:// my.example.com」。奇怪的是,從來沒有與Apache的這個問題。 – Sebastian 2016-10-06 18:43:29

+0

'ssl on;'通過SSL告訴NGINX服務器** ANY **內容。如果您的服務器同時提供http和https流量,並且刪除'ssl on;'指令,則在'listen 443;'listen listen 443 ssl;''末尾使用「ssl」標誌。 – Stphane 2016-12-10 09:44:53

回答

169

我遇到了類似的問題。它在一臺服務器上運行,而不在具有相同Nginx配置的另一臺服務器上運行。發現這是由伊戈爾在這裏找到答案的解決方案http://forum.nginx.org/read.php?2,1612,1627#msg-1627

是。

server { 
    listen 80; 
    listen 443 default ssl; 

    # ssl on - remember to comment this out 

} 
+0

按照rapam iosif的說法,確定你還包括'ssl off;' – aceofspades 2012-06-11 19:24:28

+18

你只需要刪除'ssl on'這一行(不需要添加ssl off)。另外,由於我不記得哪個Nginx版本,因此不再需要在'listen 443'行上使用'default'。所以OP配置是好的,只需要刪除'ssl on'就可以了。 – laurent 2012-12-02 01:10:50

+0

@bobojam可以隨時包含我答案中的解釋,以便您的答案更完整。我已經要求OP作者接受你的回答。 – 2012-12-27 08:49:12

16

錯誤說,這一切其實。您的配置告訴Nginx監聽端口80(HTTP)並使用SSL。當您將瀏覽器指向http://localhost時,它會嘗試通過HTTP進行連接。由於Nginx需要SSL,因此會報錯。

的解決方法是非常簡單的。你需要兩個server部分:

server { 
    listen 80; 

    // other directives... 
} 

server { 
    listen 443; 

    ssl on; 
    // SSL directives... 

    // other directives... 
} 
+7

您實際上並不需要兩個服務器部分。刪除「ssl on」行並根據@ bobojam的回答更改監聽行。 – toxaq 2012-08-14 00:16:19

3

其實你可以這樣做:或者你可以在一臺服務器結合SSL /非SSL服務器

ssl off; 

這解決了我在使用nginxvhosts問題;現在我可以同時使用SSL和純HTTP。 即使與合併端口一起工作。

+0

對於我在nginx/1.6.3上的作品:) – djthoms 2015-10-25 03:53:37

4

如果用phpmyadmin地址:fastcgi_param HTTPS上;

20

以上的答案是不正確的,大多數過騎「是這方面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; 

    [....] 
} 
+1

您可能希望$ server_name而不是$ host,server_name大概設置爲SSL證書認證的CN。這樣,如果用戶通過IP或本地主機進入,用戶不會得到恐慌屏幕。 – George 2013-11-09 05:31:02

+0

@ michael-j-evans您節省我的一週,我很沮喪,因爲我沒有找到解決方案,thks:D – rderoldan1 2014-05-06 19:51:59

+0

我試圖在本地安裝[GitLab](https://gitlab.com /),但是使用了[在GitLab服務器塊中插入自定義NGINX設置](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/nginx.md#inserting-custom- nginx-settings-into-the-gitlab-server-block)方法因此''nginx ['custom_gitlab_server_config'] =「error_page 497 https:// $ host:$ server_port $ request_uri;''做了竅門 – 2016-06-30 16:13:10

12

我有相同的問題,我有一種相同的配置爲您爲例的,我得到它通過刪除行工作:

ssl on;

引述商務部:

如果HTTP和HTTPS服務器是相等的,用於處理單個服務器HTTP和HTTPS請求可以通過刪除「上SSL」的指令並添加ssl參數爲*被配置:443端口

+0

任何機會你有鏈接到doc? – 2016-03-31 23:24:25

10

根據wikipedia article on status codes。當HTTP流量發送到https端口時,Nginx具有自定義錯誤代碼(錯誤代碼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; 
    } 
} 

然而,如果客戶端發出經由除了一個GET的任何其它方法的請求,該請求將被變成GET。從而保留客戶端通過的請求方法;我們使用錯誤處理重定向,如nginx docs on error_page

這就是爲什麼我們使用301 =307重定向。

使用這裏顯示的nginx.conf文件,我們能夠有HTTP和HTTPS監聽同一端口

+0

這對我有用 - error_page 497 301 = 307 https://89.89.89.89:7000$request_uri; – 2018-01-29 08:54:18

5

在這裏有一個例子來配置HTTPHTTPS在相同配置塊與支持ipv6。配置在Ubuntu服務器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

希望這有助於!