今天這一章將說明如何以自簽方式生成憑證並進行安裝。雖然我們在上一章提到憑證需要向 CA(憑證授權機構)申請(而且通常要錢),但如果我們是在本機測試,使用 .local
這種非合法持有的網域,就無法申請憑證;即使我們使用合法持有的網域,如果限制於內部網路使用,CA 廠商的驗證和發行憑證也較為麻煩,這時也可以考慮使用自簽的方案,並在客戶端安裝自簽的 Root CA。但如果是在外網環境中,當然還是需要向各大 CA 廠商申請憑證。
以下的方法較為複雜,是從管理 CA 的角度出發,並且因為上一章介紹了信任鏈,所以我們使用了三層(Root CA -> Intermediate CA -> Certificate)的架構來讓大家更有概念。但如果只是要在本機進行測試,其實不需要這麼複雜,只需要直接自簽憑證即可;目標只是讓 Nginx 有憑證可以加密流量,否則無法正常啟動。
首先,我們需要生成一個 Root CA(憑證授權機構)的私鑰與自簽證書,這個 Root CA 將用於為內部服務簽發 SSL 憑證。
openssl genrsa -out example_root_ca_1.key 4096
openssl req -x509 -new -nodes -key example_root_ca_1.key -sha256 -days 3650 -out example_root_ca_1.pem -subj "/C=TW/ST=Tainan/L=Tainan City/O=Example Inc/CN=Example Root CA 1"
這樣,我們就生成了 Root CA 的私鑰(example_root_ca_1.key
)和自簽證書(example_root_ca_1.pem
)。
接下來,我們將生成一個中繼 CA(Intermediate CA),專門用來為內部服務(如 odoo 反向代理)生成 SSL 憑證。
openssl genrsa -out example_internal_services_ca.key 4096
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
prompt = no
[ req_distinguished_name ]
C = TW
ST = Tainan
L = Tainan City
O = Example Inc
CN = Example Internal Services CA
[ v3_ca ]
basicConstraints = critical,CA:TRUE
keyUsage = critical,keyCertSign,cRLSign
這個設定檔定義了 Internal Services CA 的憑證屬性,並設置了這個憑證的基本限制和使用範圍。
openssl req -new -key example_internal_services_ca.key -out example_internal_services_ca.csr -config example_internal_services_ca.cnf
openssl x509 -req -in example_internal_services_ca.csr -CA example_root_ca_1.pem -CAkey example_root_ca_1.key -CAcreateserial -out example_internal_services_ca.pem -days 3650 -sha256 -extensions v3_ca -extfile example_internal_services_ca.cnf
odoo.internal.example.local
的 SSL 憑證接下來,我們將使用 Example Internal Services CA 來為 odoo.internal.example.local
這個網域簽發 SSL 憑證。
openssl genrsa -out odoo_internal_example_local.key 4096
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
C = TW
ST = Tainan
L = Tainan City
O = Example Inc
CN = odoo.internal.example.local
openssl req -new -key odoo_internal_example_local.key -out odoo_internal_example_local.csr -config odoo_internal_example_local.cnf
openssl x509 -req -in odoo_internal_example_local.csr -CA example_internal_services_ca.pem -CAkey example_internal_services_ca.key -CAcreateserial -out odoo_internal_example_local.crt -days 365 -sha256
這樣,我們就生成了 odoo.internal.example.local
的 SSL 憑證(odoo_internal_example_local.crt
),可以將其安裝到 Nginx 中。
在安裝憑證的時候,需要將 odoo_internal_example_local.crt
(為 odoo.internal.example.local
簽發的服務憑證)和 example_internal_services_ca.pem
(中繼 CA 憑證)合併成一個檔案,讓 Nginx 能向客戶端傳送完整的憑證鏈:
cat odoo_internal_example_local.crt example_internal_services_ca.pem > odoo_internal_example_local_fullchain.crt
根據我們前幾章的設定:
ssl_certificate /etc/nginx/certs/odoo_Certificate.crt; # 設定 SSL 憑證
ssl_certificate_key /etc/nginx/certs/odoo_Certificate.key; # 設定 SSL 私鑰
以及 Docker Compose 的設定:
- ./config/certs:/etc/nginx/certs
因此,我們需要將合併後的憑證和私鑰分別重命名,並放置在對應的目錄中。
使用以下指令將憑證和私鑰重命名:
mv odoo_internal_example_local_fullchain.crt odoo_Certificate.crt
mv odoo_internal_example_local.key odoo_Certificate.key
將這兩個檔案放置在 ./config/certs
目錄下,這樣 Nginx 就能讀取並使用這些憑證和私鑰。
客戶端(如瀏覽器或 OS)需要信任您的自簽 Root CA。因此,客戶端需要將 example_root_ca_1.pem
(根憑證)安裝到他們的信任存儲中,才能確保信任鏈完整。(如果不安裝,只是會出現不安全的警告)
example_root_ca_1.pem
,選擇「安裝憑證」,然後將其安裝到「受信任的根憑證授權機構」。example_root_ca_1.pem
憑證添加到「系統」鑰匙圈的「信任」類別中。/usr/local/share/ca-certificates/
,然後執行 sudo update-ca-certificates
更新系統信任存儲。這樣我們就完成了整個自簽憑證的流程。但要特別注意的是,在內網部署這套方案時,一定要確保所有的私鑰(包括 Root CA、Intermediate CA 和服務憑證的私鑰)都保存在安全的地方,只在需要簽發憑證時才使用。私鑰的洩露可能導致嚴重的安全問題。
到了這章設定好 SSL ,讓 Nginx 執行起來後,我們的反向代理基礎的功能就完成了,剩下的就是 odoo.conf
和一些敏感資料的設定方式修改,等到這些必要的設定都結束後,有空我們還會來介紹 Let's Encrypt 這個免費憑證的申請方式。