nginx + SSL Certificate – 讓 http 變身成為 https

接續 SSL For Free – 免費又有綠色鎖頭的 SSL Certificates 申請好 SSL Certificate 之後,這篇記錄一下怎麼樣把 SSL Certificate 加入 nginx 中,讓 http 可以進化成 https。

https
圖片來源:http://tw.freeimages.com/photo/computer-therms-2-1241965

囉哩巴唆

小蛙剛接觸 nginx 的時候,真是吃盡了苦頭,雖然說功能非常強大,但是有些功能 google 了好久才勉強達到,這裡提供的一些作法也許不是最好,小蛙相信有更優雅的作法,不過至少能達成小蛙的需求,正所謂能解決問題的就是好方法!先達到功能,之後看到更好的作法再慢慢修正。

準備所需的 crt 及 key

把從 SSL For Free – 免費又有綠色鎖頭的 SSL Certificates 下載回來的 3 個檔案,分別是 ca_bundle.crt, certificate.crt, private.key,接下來我們要將 ca_bundle.crt 與 certificate.crt 合併,如果是用 windows 的話,用筆記本新增一個檔案叫做 bundle.crt,然後分別將 certificate.crt 跟 ca_bundle.crt 這兩個檔案的內容貼進 bundle.crt,要注意有沒有不小心複製到換行,或是空白字元,大概會變成下面這樣

-----BEGIN CERTIFICATE-----
...
certificate.crt 的內容
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
ca_bundle.crt 的內容
...
-----END CERTIFICATE-----

如果像小蛙一樣使用 Linux 的話,可直接輸入

>cat certificate.crt ca_bundle.crt >> bundle.crt
// 接著用編輯器把以下的魂結斷開
-----END CERTIFICATE----------BEGIN CERTIFICATE-----

魂結沒有斷開的話,會得到這個錯誤

[emerg] 20131#0: PEM_read_bio_X509_AUX("/etc/nginx/ssl/crazyall.net.crt") failed (SSL: error:0906D066:PEM routines:PEM_read_bio:bad end line)

以小蛙的 nginx 為例,為了不要放檔案太亂,小蛙另外建了 ssl 資料夾,該目錄為 /etc/nginx/ssl/,並且將 bundle.crt 更名為 crazyall.net.crt,private.key 也更名為 crazyall.net.key,如此一來如果有多個網域搭配多個 SSL 會比較方便管理,完成後將 crazyall.net.crt 及 crazyall.net.key 複製到 /etc/nginx/ssl/ 資料夾中。

將 SSL 加入 nginx

這裡記錄給自己看,預設的 nginx 檔案會包含一小段搭配載入 php5-fpm 的部份,例如:

location ~ \.php$ {
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_read_timeout 120;
		fastcgi_index index.php;
		include fastcgi_params;
}

如果只有一個網域或一個站,直接這樣就好,但是像小蛙有 crazyall.net 以及 wazai.net 兩個,這一段就會重複,這時候可以把上面的內容獨立成 php.conf 並放在 /etc/nginx/ 資料夾下,接著從 /etc/nginx/sites-avaibale/wazai.net 設定檔中 include php.conf; 就可以了。

wazai.net 的設定部份如下

server {
		listen 443 ssl default_server;	 	 
		listen [::]:443 ssl default_server;
		server_name wazai.net;
		ssl_certificate /etc/nginx/ssl/wazai.net.crt;	 	 
		ssl_certificate_key /etc/nginx/ssl/wazai.net.key;	 	 
		... 以下省略 ...	 	 
}

這裡如果把 crazyall.net 使用一樣的設定就會得到下列錯誤

[emerg] 20005#0: a duplicate default server for 0.0.0.0:443 in /etc/nginx/sites-enabled/wazai.net:58

因此如果同一台主機上有不只一個網域要使用 SSL,就要改成下面這樣,加了 default_server 就直接錯給你看

server {
		listen 443 ssl;
		server_name crazyall.net;
		ssl_certificate /etc/nginx/ssl/crazyall.net.crt;
		ssl_certificate_key /etc/nginx/ssl/crazyall.net.key;
		root /your_www_document;
		index index.php index.html index.htm;
		... 以下省略 ...
}

經過這些修改 service nginx reload 就可以正常執行囉!試試看 https://your_domain/,如果是用 WordPress 架站的話,還會有很多很多很多問題需要克服,使用 Chrome 的 consloe 可以看到滿山滿谷的

滿山滿谷的 MixedContent
滿山滿谷的 MixedContent

而且網站打開來之後慘不忍睹, 這也是小蛙為什麼當初卻步的原因,下一篇根據 google 來的資料一一修正這些問題。

http://crazyall.net
正常的都瘋:http://crazyall.net
慘不忍睹的都瘋:https://crazyall.net
慘的都瘋:https://crazyall.net

參考資料

網站架設系列文章:

    4 個回應

    1. vini表示:

      我的博客皮肤和你这个一模一样。用了好几年。这个月初,刚好停了,服务器在其他地方,没转移到现在的服务器。

    2. vini表示:

      我也刚好遇到“a duplicate default server for 0.0.0.0:443”这个问题。原来,我是“太贪吃了”,每个server里都加了default,导致出现了这个问题。正如你所说,只有将默认里边加了“default”就可以了。

    3. um表示:

      我找到解法了@@
      慘的都瘋:https://crazyall.net
      的http檔案request https問題應該能解了
      https://www.never-nop.com/?p=2526

    發佈留言

    發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

    這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料