CentOS 7 - 手把手部署 ASP.NET Core 網站
Introduction
在本篇文章中,將會:
- 安裝 CentOS 7 並建立基本環境
- 安裝 Nginx 並將 ASP.NET Core 包成服務自動啟動
- 安裝 Certbot 並申請 SSL 憑證使連線允許安全的 HTTPS
- 透過 Certbot 與 Crontab 使 SSL 證書可以自動更新
Steps of Configuring
Environment
在安裝完 CentOS 7 後,我們首先先設定一下基本環境,以及安裝一些需要用到的 Packages(e.g. SSH, xRDP, dotNET Runtime),關於這個部分可以參考之前的文章 CentOS 7 Environment Setup 以及微軟官方文件,並依照自己的需求操作。
Nginx
ASP.NET Core 內建 kestrel 伺服器讓我們可以不經修改直接搬到 CentOS 上執行,但輕巧的代價就是功能陽春,因此實務上還是需要 Reverse Proxy 來對外提供服務。目前 Linux 上有兩大 Reverse Proxy Server:
- Apache
- Nginx
Nginx was written with an explicit goal of outperforming the Apache web server.Out of the box, serving static files, Nginx uses dramatically less memory than Apache, and can handle roughly four times more requests per second.However, this performance boost comes at a cost of decreased flexibility, such as the ability to override systemwide access settings on a per-file basis (Apache accomplishes this with an .htaccess file, while Nginx has no such feature built in).
Wikipedia ── Nginx vs Apache
截至 2018 年 1 月,Nginx 服務或代理了全球 30.46% 的網站。而在比較後我也選擇使用 Nginx 作為我的 Reverse Proxy Server。
安裝並啟動 Nginx
1 | Install Nginx |
為了讓伺服器可以接受外在連線,我們將 http/https 加入至防火牆規則中:
1 | sudo firewall-cmd --permanent --zone=public --add-service=http |
接著,我們就可以先測試是否可以連線到 CentOS 主機了!
設定 Nginx 組態檔
在 ASP.NET Core 官方文件上詳細說明了如何設定反向代理伺服器,而做法是直接修改 /etc/nginx/nginx.conf
,不過較正確且模組化的作法是為每個站台建立自己的 conf,並放在 /etc/nginx/conf.d
下,舉例而言,建立一個 holey.cc 的站台組態:
1 | sudo vi /etc/nginx/conf.d/holey.cc.conf |
在建立完畢之後可以鍵入指令檢查組態,若沒問題則 reload 組態:
1 | Check Nginx configs |
Reload 組態之後可以試連網站看是否正常運作,若出現 502 Bad Gateway
錯誤可能是 Security-Enhanced Linux (SELinux) 禁止了 http 連線導致,可以透過指令來解鎖:
1 | sudo setsebool -P httpd_can_network_connect on |
自動啟動 ASP.NET Core
在 ASP.NET Core 官方文件上說明了如何將 ASP.NET Core 程式包成服務的方式。以 holey.cc 為例,首先先在 /etc/systemd/system/
下建立 kestrel-holey.cc.service
:
1 | [Unit] |
WorkingDirectory
是網站檔案存放的目錄。ExecStart
第一個參數是 dotnet 執行檔案,第二個參數是網站 DLL 檔。User
是執行服務的身分,需要注意的是 User 必須要有網站目錄的存取權。
在設定好 service 後,就可以註冊並啟動服務:
1 | Automatically start on boot |
檢視紀錄
我們可以透過下面的命令來檢視位於集中式日誌中 kestrel-holey.cc.service
的特定項目:
1 | sudo journalctl -fu kestrel-holey.cc.service |
若要進一步篩選,例如 --since today
、--until 1 hour ago
或這些項目的組合等時間選項:
1 | sudo journalctl -fu kestrel-holey.cc.service --since "2016-10-18" --until "2016-10-18 04:00" |
Certbot
由於 HTTPS 確保了伺服器與使用者雙方間的通訊安全,HTTPS 已成為許多平台與瀏覽器的最低要求。舉例而言,AppStore 便規定了所有連線都必須是 HTTPS 否則不可上架,或是如 Firefox、Chrome 等瀏覽器會將 HTTP 標示為不安全或未受信任。因此,將網站掛上 HTTPS 是勢在必行的。
而現在能夠在網路上申請的免費憑證中,當屬 Let’s Encrypt 較為出名,而 Certbot 便是將整個申請流程化繁為簡並自動化的 Package。
Certbot is an easy-to-use client that fetches a certificate from Let’s Encrypt—an open certificate authority launched by the EFF, Mozilla, and others—and deploys it to a web server.
Cretbot ── Introduction
Install Certbot
1 | sudo yum install certbot |
Modify Nginx config
若是有用過 Let’s Encrypt 申請憑證,對於驗證 your.domain/.well-known/acme-challenge
應該會有印象。為了讓我們的網站可以被驗證,我們必須先對 Nginx config 做一些調整:
1 | sudo vi /etc/nginx/conf.d/holey.cc.conf |
這樣我們讓原本 holey.cc/.well-known/acme-challenge
的要求會對應實際目錄的 /var/www/holey.cc/.well-known/acme-challenge
轉到 /var/www/.well-known/acme-challenge
去。
Get certificate from Let’s Encrypt
在調整完組態後,我們便可以開始申請 SSL 憑證:
1 | sudo certbot certonly --webroot -w /my/website/folder -d mydomain.name -m my.email@address |
- -w:(必填)網站目錄
- -d:(必填)要取得憑證的網域(子網域)名稱
- -m:(選填)當憑證快過期時可以收到通知的電子信箱
在驗證完畢且成功後會出現 Congratulations,而 Private Key 以及 LE Chain 存放路徑也會顯示在訊息內。
需要注意的是,Let’s Encrypt 有申請速率限制,對一般使用者較有影響的是:
- 每周 50 個註冊域名證書
假設holey.cc
為主域名,則每周最多可以申請 50 個*.holey.cc
的證書。 - 每周五份的重複證書限制
若證書包含忽略大小寫與排序而完全相同的主機名,則一周申請限制是五次。
Diffie-Hellman Key Exchange
Diffie-Hellman Key Exchange (D-H) 是著名的密鑰交換協定,目的在於確保通訊雙方可以安全地交換密鑰。需要注意的是它不是演算法,所以不提供加密功能,僅是保護密鑰交換的過程。
所以為了保護密鑰,我們透過 openssl 建立 2048 長度的 dhparam.pem
檔案並存放至 /etc/ssl/certs/
:
1 | Remember to modify your dhparam.pem path |
由於在進行 Diffie-Hellman Key Exchange 時,若長度太短則安全性低下,但若太長也可能會影響使用者體驗。因此建議使用 2048 或 4096 的長度會較好。而在產生的過程中會耗用大量的 CPU 資源,因此可視主機性能來決定產生長度。
在建立 dhparam.pem
之後,開啟網站組態並新增:
1 | sudo vi /etc/nginx/conf.d/holey.cc/conf |
之後重新檢查組態與 reload 讓設定生效即可:
1 | sudo nginx -t |
Automatically renew certificate
由於 Let’s Encrypt 所提供的證書有效期限只有 90 天,因此在過期前就必須重新申請一次。不過我們可以透過Crontab 與 Certbot 來達成自動更新證書:
1 | sudo crontab -e |
關於 Crontab 可以參考 Wikipedia 的說明,在本篇的範例是設定為每月五號三點時執行更新證書的動作:
1 | # ┌───────────── minute (0 - 59) |