本文將教學如何在Windows上申請Let’s Encrypt的SSL/TLS憑證,讓網站擁有HTTPS連線的機制。有時候為了讓各種後端語言同時存在,會在Windows上先安裝Apache或Nginx網頁伺服器,再反向代理到伺服器上的PHP、ASP、Java、NodeJS、Django等AP Server。因此在Windows上使用IIS(Internet Information Server)、Apache、Nginx申請憑證的方法都包含在文章內,一起讓瀏覽器網址列上面顯示有鎖頭的HTTPS吧。

更新:目前將IIS、Apache、Nginx了設定方式都補上了,可以依照需求觀看。但建議使用Nginx的朋友先從Apache看起,因為有一些重複的步驟我只寫在Apache教學上。

注意:在驗證網域階段如果失敗了,要仔細檢查一下是哪邊出問題,例如你的HTTP沒有使用80 port、防火牆沒允許HTTP連線、網域指向錯誤IP等。不要一直重新嘗試驗證,否則Let’s Encrypt會暫時封鎖你的網域的驗證,被封鎖的話通常要等到隔天才能再重試一次了。

基礎知識簡介

Virtual Host 虛擬主機/站台

Apache與Nginx都有Virtual Host的設定,接下來的驗證也會使用到Virtual Host,因此在此先進行一段簡介,對應IIS上的應該是稱為站台吧。Virtual Host直譯為虛擬主機,用處是讓一台Web伺服器可以一次負責好幾個網站。瀏覽器要連上伺服器的時候,除了會需要伺服器的IP地址,還會告訴伺服器要看哪一個網站,網頁伺服器的虛擬主機設定就能按照設定得知瀏覽器真正要看的是哪一個網站。這樣一個IP地址與一台伺服器就能同時服務好幾個網站了。

Reverse Proxy 反向代理

反向代理是為了隔離網際網路的使用者與伺服器之間的直接連結,平常使用者的瀏覽器可以直接連上網頁伺服器,但是當我們將網頁伺服器藏在內網的話,就必須要透過一台反向代理伺服器,用來瀏覽器只能連上反向代理伺服器,再由反向代理伺服器跟真正的網頁伺服器溝通。反向代理伺服器跟真正回應的Web伺服器可以是同一台Windows電腦,只要彼此使用的TCP Port不一樣就可以,記得要將80與443分給反向代理伺服器喔。

有點概念的朋友應該會發現這樣轉一首效能不好吧?沒錯,但他帶來的好處多於壞處,所以沒關係的。像是Apache、Nginx作為反向代理伺服器時可以直接處理靜態檔案,當瀏覽器需要的是靜態檔案時可以直接回傳檔案,而且效率非常好。只有當瀏覽器需要的是經過運算後的資料,才會反向代理到後端如Java的Tomcat、Python的Django內建伺服器,這樣能大幅提高效能。Apache與Nginx還能承擔負載平衡的工作,例如一個Nginx服務後面接了好幾個Tomcat伺服器,能大幅提升服務容量。

Let’s Encrypt 憑證頒發機構

Let’s Encrypt是由非營利團體建立的SSL/TLS憑證頒發機構,靠著自動化流程來減少團隊人力,靠著各大機構的捐款來提供免費的憑證給世界各地的網站。之前有介紹過這邊就說太多了,可以參考他們官網:https://letsencrypt.org/,可以看到FireFox、Chrome、IBM、Facebook、雅馬遜等各大公司都是贊助者。

在我的另一篇文章:在Linux上使用Let’s Encrypt搭配NginX獲得免費的SSL憑證,也有提及HTTPS、SSL/TLS憑證與Let’s Encrypt的一些相關知識。

WIN-ACME 憑證申請工具

Let’s Encrypt本身沒有提供運作在伺服器上的申請工具,但有推薦合適的工具給申請者,其中WIN-ACME就是提供給Windows系統使用的申請工具,可以參考他們的網站:https://www.win-acme.com/,可以先點選上面的Download下載最近穩定版,因為待會會用到喔。

其實WIN-ACME也有提供給IIS使用,但我沒有在用IIS沒多研究,因此要用IIS的朋友可以直接上去看看。或是使用我提供的反向代理方法,使用Nginx作為主要對外的伺服器,只透過Nginx來申請SSL/TLS憑證,然後在反向代理到內部的IIS。這樣有一個好處是Nginx的效能很好,未來要添加更多後端伺服器時也很好調整。


IIS設定

建立站台

先上IIS的設定畫面,指定你的Domain Name並且綁定TCP 80 port,先不用管HTTPS與443 port的部分,確認可以連線即可開始。我這邊測試時使用 iis.klab.tw 來做申請的示範。

下載WIN-ACME

連上 https://www.win-acme.com/ 網站下載最新穩定版,然後在執行IIS的電腦上找個合適的地方解壓縮。解壓縮後使用系統管理員身份開啟wacs.exe執行檔。

我拍攝時下載的是win-acme.v2.1.22.1289版,然後放到C:/opt/win-acme.v2.1.22.1289資料夾。

使用系統管理員身份執行wacs.exe

必須要系統管理員權限才能讓WIN-ACME幫忙設定SSL憑證,不然就需要透過比較複雜一點的步驟,先申請到憑證後自己加入IIS站台。不透過系統管理員的設定方式不在本篇文章的教學內,但可以參考本篇文章的Apache申請教學,原理是一樣的。

看到WIN-ACME啟動畫面

申請SSL憑證

在啟動畫面會看到Please choose from the menu:,輸入N按下Enter進入申請憑證選單,WIN-ACME會詢問使用者要為IIS上的哪一個站台申請SSL憑證。因為我的IIS上面有兩個站台,三號已經申請好SSL憑證,四號是還沒申請憑證的 iis.klab.tw,因此在這邊我輸入4代表要為 iis.klab.tw 申請憑證。

初次啟動的時候,可能會需要輸入申請人的Email信箱,然後要按下Y同意使用者條款。Let’s Encrypt會在憑證快要到期的時候,或是有其他消息的時候,寄信到指定的Email信箱。

根據要申請的網域的號碼輸入數字

接下來會再次出現你要申請SSL憑證的網域名稱,然後出現兩個選項,分別輸入A與Y就可以了。

使用A選項,然後輸入Y確認申請

接下來會進入自動驗證的階段。

驗證完成,憑證也自動裝好了

完成後就會回到最一開始的畫面,這時候IIS的憑證已經自動裝好了,也自動將https綁定443 port,完全是自動的。以我這邊的例子就是連上 https://iis.klab.tw 就可以看到有鎖頭的網站囉。

第一次執行完成後,WIN-ACME會詢問是否要在快過期的時候自動執行更新流程,這邊選擇Y就交給WIN-ACME即可。然後WIN-ACME會詢問是否要使用特定的使用者來執行自動更新流程,我選擇N,由系統管理員權限執行。要是缺乏系統管理員權限,WIN-ACME會沒辦法幫忙自動更新IIS。

完成後即可看到網站有https囉

Apache設定

Apache的安裝過程我就不提了,如果想要快速安裝的話,可以使用XAMPP,一次把Apache、PHP、MySQL等都安裝好了,不需要安裝的部分取消勾選即可。

開啟Apache的設定檔「httpd.conf」,如果使用XAMPP安裝的話,那他會放在C:\xampp\apache\conf\httpd.conf,先在httpd.conf的旁邊建立一個新的文字檔案,叫「virtual_host.conf」,然後打開httpd.conf在最下面加上以下這行。

<Directory "C:/www/klab.tw">
    AllowOverride All
    Options None
    Require all granted
</Directory>
include conf/virtual_host.conf

第一行的Directory標籤是設定要將新的網站放在C:/www/klab.tw,如果需要放在其他地方,修改成自己需要的路徑即可。最後一行使用了include載入額外的設定檔案,這是為了方便管理,將虛擬主機的設定寫到另一個檔案裡,然後在主要的設定檔案「httpd.conf」中載入「virtual_host.conf」。

靜態檔案或是連結PHP的設定

開啟「virtual_host.conf」寫入以下內容,當然ServerName klab.tw是我的範例,修改成自己的網域名稱。DocumentRoot也可以更改,一但更改了,上面的Directory也要一併修改。另外<Directory>的設定也可以放在virtual_host.conf檔案內。

使用Let’s Encrypt進行驗證來申請憑證的時候,申請工具會在根目錄新增一個資料夾來存放驗證檔案,以目前的範例來看會放在C:/www/klab.tw/.well-known,讓申請工具自己新增就可以了。

<VirtualHost *:80>
    ServerName klab.tw
    DocumentRoot "C:/www/klab.tw"
</VirtualHost>

反向代理的設定

這種情況是Apache同時要反向代理,又要處理靜態檔案的設定。第四行的/.well-known !代表有根目錄的.well-known資料夾不要反向代理,而是去C:/www/klab.tw尋找檔案。第五行的/ http://localhost:8080代表根目錄的所有請求都反向代理到http://localhost:8080處理,除了之前有加上驚嘆號排除的設定。第六行就的設定就照著第五行寫就可以了,ProxyPassReverse是告知Apache如何處理轉址的情況。

首先說明/.well-known資料夾,這個資料夾是留給Let’s Encrypt驗證時使用的,因此不能被反向代理。再來http://localhost:8080是網頁伺服器的網址,可能是Tomcat、Djaongo、IIS、NodeJS等各種伺服器,注意一下他們的port是什麼,這邊是以8080為範例。記得這些伺服器不可以使用80與443兩個TCP Port,要留給Apache使用。

<VirtualHost *:80>
    ServerName klab.tw
    DocumentRoot "C:/www/klab.tw"
    ProxyPass /.well-known !
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
</VirtualHost>

使用WIN-ACME進行申請憑證

https://www.win-acme.com/下載最新穩定版,找個地方解壓縮後啟動wacs.exe

# 以申請 klab.tw 為例
# 選擇手動新增
Please choose from the menu: M
# 手動設置
How shall we determine the domain(s) to include in the certificate?: 2
# 輸入網域名稱,例如klab.tw
Host: klab.tw
# 取個別名,這邊可以直接按下Enter
Friendly name '[Manual] klab.tw'. <Enter> to accept or type desired name: <Enter>
# 驗證方式,這邊選擇1
How would you like prove ownership for the domain(s)?: 1
# 網站的根目錄儲存位置
Path: C:/www/klab.tw
# 這個應該是IIS使用的設定檔,因此選擇N
Copy default web. config before validation? (y/n*): N
# 這邊按照預設值選擇2就可以了
What kind of private key should be used for the certificate?: 2
# 憑證類型,我們選擇2,可以給Aapache與Nginx使用
How would you like to store the certificate?: 2
# 輸入憑證儲存位置,可以自己決定
File path: C:/opt/ssl
# 選擇1不設定憑證密碼
Choose from the menu: 1
# 選擇預設值5就可以了
Would you like to store it in another way too?: 5
# 選擇預設值3就可以了
Which installation step should run first?: 3
# 後面可能會問你要不要選擇指定user來進行之類的,選擇N不要就好囉

上圖就是成功後的樣子,這個例子我是用本網域的另一個網站:http://ds.klab.tw 來做範例。

安裝憑證到Apache

回到「virtual_host.conf」檔案,不要變更原本的設定,在最下面新增以下內容,因此會有一個<VirtualHost *:80>與一個<VirtualHost *:443>的設定。注意除了ServerName與DocumentRoot要修改之外,第五、第六、第七行,這三行對應的檔案也要修改喔。

<VirtualHost *:443>
    ServerName klab.tw
    DocumentRoot "C:/www/klab.tw"
    SSLEngine on
    SSLCertificateFile "C:\opt\ssl\klab.tw-crt.pem"
    SSLCertificateKeyFile "C:\opt\ssl\klab.tw-key.pem"
    SSLCertificateChainFile "C:\opt\ssl\klab.tw-chain.pem"
</VirtualHost>

如果是使用反向代理的功能,記得要在設定中補上ProxyPass與ProxyPassReverse。設定完成後,重新開起Apache就可以生效了。

自動更新

由於WIN-ACME會自動更新,因此自動更新憑證的部分沒有問題,但是憑證更新後Apache必須重開才會生效,因此可以新增一個batch檔案處理自動重開Apache,例如新增一個檔案名為C:/opt/renew-ssl.bat之類的,讓系統定期自動執行一次。

:: 更多教學參考 https://klab.tw
:: 以下路徑修改為放置WIN-ACME的地方
cd C:/opt/win-acme.v2.1.22.1289.x64.pluggable
wacs.exe --renew --force
net stop Apache2.4 && net start Apache2.4

上面的Apache2.4是Apache在Windows服務的名稱,記得開啟Windows服務對一下名字是否一樣。完成後開啟「工作排程器」讓以上程式自動執行,我設定為每兩個月執行一次,因為設為每三個月一次的話,會有大小月的問題,可能會有一兩天的空窗期讓憑證過期。但Windows工作排程器又沒辦法設定為89天執行一次之類的,只好兩個月一次。

Nginx設定

安裝Nginx

有一些一樣的步驟在Apache的教學提過了,這邊就簡單地講解,首先上Nginx的官網下載Windows版應用程式:http://nginx.org/en/docs/windows.html,找個地方解壓縮後就可以使用了。但這個免安裝版沒辦法在每次開機後自動執行,因此需要靠WINSW來包裝成Windows服務,可以到他們的GitHub專案下載:https://github.com/winsw/winsw/releases,選擇Latest版本下載,然後將winsw.exenginx.exe放在一起,我選擇放到C:/opt/nginx裡面。

新增winsw.xm檔案放入以下資訊。

<service>
  <id>Nginx</id>
  <name>Nginx</name>
  <description>The Service for Nginx web server</description>
  <delayedAutoStart>true</delayedAutoStart>
  <executable>nginx.exe</executable>
  <logpath>C:/opt/nginx/winsw_log</logpath>
  <log mode="roll"></log>
  <stopexecutable>nginx.exe</stopexecutable>
  <stoparguments>-s stop</stoparguments>
</service>
<!-- 更多教學參考 https://klab.tw -->

然後透過命令提示字元視窗,輸入winsw install就安裝好囉。

申請憑證

申請憑證的方式可以參考上面Apache版本的,操控WIN-ACME的方法是一樣的。

設定檔案

最後的設定檔案會長這樣子。需要更多Nginx反向代理的知識與操作方式可以參考我的另一篇文章:整合Spring Boot、Nginx反向代理、Linux systemd系統服務

server {
	listen 80;
	listen [::]:80;
	server_name klab.tw;

	location /.well-known {
		root C:/http/klab.tw;
	}
	location / {
		return 302 https://$host$request_uri;
	}
}

server {
	listen 443 ssl;
	listen [::]:443;
	server_name klab.tw;
	ssl_certificate	    C:/opt/ssl/klab.tw-crt.pem;
	ssl_certificate_key C:/opt/ssl/klab.tw-key.pem;
	
	location / {
		proxy_pass http://localhost:8080;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
	}
}

自動更新

自動更新需要新增一個Windows腳本,我取名為C:/opt/renew-ssl.bat。

:: 更多教學參考 https://klab.tw
:: 以下路徑修改為放置WIN-ACME的地方
cd C:/opt/win-acme.v2.1.22.1289.x64.pluggable
wacs.exe --renew --force
net stop Nginx && net start Nginx

剩下部分也是參考上面Apache的教學就可以囉。