OpenSSL 建立私有 CA 三部曲:
使用 OpenSSL 建立私有 CA:1 根證書
使用 OpenSSL 建立私有 CA:2 中間證書
使用 OpenSSL 建立私有 CA:3 使用者證書
在前文《使用 OpenSSL 建立私有 CA:2 中間證書》中我們介紹瞭如何建立中間證書,並生成證書鏈。本文我們將介紹如何為應用生成使用者證書(web 站點的 ssl 證書),並把證書部署到應用伺服器上和客戶端上。說明:本系列文章的演示環境為 Ubuntu 18.04,OpenSSL 的版本為 1.1.0g。
目標
為區域網中的站點 bigxa 建立 ssl 證書並部署。
準備使用者證書的配置檔案
在 myca 目錄下建立 bigxa 目錄,然後建立配置檔案 bigxa/bigxa.cnf,編輯其內容如下:
# OpenSSL to generate a certificate signing requests(csr) configuration file. # v1 [ req ] # Options for the `req` tool (`man req`). # use prompt config control user interactive prompt = no input_password = 123456 default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 # Extension to add when the -x509 option is used. #x509_extensions = v3_ca req_extensions = v3_req [ req_distinguished_name ] # See <https://en.wikipedia.org/wiki/Certificate_signing_request>. countryName = CN stateOrProvinceName = ShaanXi localityName = Xian organizationName = PowerCity Ltd organizationalUnitName = Star commonName = bigxa emailAddress = ljfpower@163.com [ v3_req ] subjectAltName = DNS:bigxa
該配置檔案主要通過 [ req_distinguished_name ] 段來設定證書的資訊,請注意 [ v3_req ] 段中的 subjectAltName 資訊,如果你為區域網中的 IP 地址生成 https 證書,就必須要設定 subjectAltName。
建立祕鑰
進入 bigxa 目錄:
$ cd bigxa
建立目錄 private csr certs:
$ mkdir private csr certs
執行下面的命令重建私鑰:
$ openssl genrsa -out private/bigxa.key.pem 2048
注意,這裡我們沒有使用 -aes256 選項,這樣建立的祕鑰不包含密碼。如果要建立 web 伺服器用的 ssl 證書,一定不要為祕鑰設定密碼!否則在每次重啟 web 服務的時候都需要輸入密碼!同樣也把祕鑰的許可權設定為 400:
$ chmod 400 private/bigxa.key.pem
此時當前目錄為 myca/bigxa。
建立 Certificate Signing Requests(csr)
對於建立站點的 https 型別的證書,必須在配置檔案中設定 Common Name 為 fully qualified domain name(也就是 網站的域名,或者是區域網中的機器名或 IP)。我們的 web 伺服器機器名為 bigxa,所以在配置檔案中設定 Common Name 為 bigxa,同時設定 subjectAltName 為 DNS:bigxa。注意,Common Name 不能與根 CA 和中間 CA 的 Common Name 相同。
使用下面的命令生成 csr:
$ openssl req -config bigxa.cnf \ -key private/bigxa.key.pem \ -new -sha256 \ -out csr/bigxa.csr.pem
用下面的命令來驗證已經生成的 csr:
$ openssl req -text -noout -in csr/bigxa.csr.pem
注意確認下圖中的關鍵資訊 CN = bigxa:
還有 Subject Alternative Name:
建立使用者證書
因為我們在 powerca.cnf 中新增了 copy_extensions = copy,所以在使用 csr 生成使用者證書時可以直接使用中間證書的配置檔案(powerca/powerca.cnf)而不用修改。下面先回到 myca 目錄下,然後生成使用者證書:
$ cd .. $ openssl ca -config powerca/powerca.cnf \ -extensions server_cert -days 1000 -notext -md sha256 \ -in bigxa/csr/bigxa.csr.pem \ -out bigxa/certs/bigxa.cert.pem
這次輸入的密碼為 powerca 祕鑰的保護密碼:123456。
如果發生 "TXT_DB error number 2" 的錯誤,把 powerca/db/index 檔案中相同名稱的記錄刪除即可。這個檔案是 OpenSSL CA 工具儲存資料的資料庫:
證書生成後我們把它的許可權修改為 444:
$ chmod 444 bigxa/certs/bigxa.cert.pem
驗證證書
先通過下面的命令來驗證使用者證書中的基本資訊:
$ openssl x509 -text -in bigxa/certs/bigxa.cert.pem -noout
圖中顯示證書頒發機構為 NickLi Power CA,可用日期為 2018-11-27 至 2021-8-23 號,證書的 Common Name 為 bigxa。還有一些 X509 協議相關的資訊:
CA:FALSE 表示該證書不能用作中間證書了,SSL Server 表示該證書可以用來支援 HTTPS 協議,最後確認 Subject Alternative Name 為:DNS:bigxa。
最後通過下面的命令驗證證書的合法性:
$ openssl verify -CAfile powerca/certs/powerca-chain.cert.pem bigxa/certs/bigxa.cert.pem
自動建立使用者證書
如果手動建立每個使用者證書還是挺繁瑣的,我們可以把這個過程自動化掉。在 myca 目錄下建立 usercert 目錄:
$ mkdir usercert
把 bigxa/bigxa.cnf 拷貝到 usercert 目錄下:
$ cp bigxa/bigxa.cnf usercert/usercert.csr.cnf
在 usercert 目錄下建立 private csr certs 三個目錄:
$ mkdir usercert/{private,csr,certs}
然後在 myca 目錄下建立指令碼檔案 certhelper.sh,編輯其內容如下:
#!/bin/bash # ./certhelper.sh yourhostname # if hostname is IP, should add the second paramerter "ip" # ./certhelper.sh 10.3.2.33 ip set -ex # demo: check string is empty if [ -z "$1" ]; then echo the first parameter is empty. echo plese add hostname as parameter exit 2 fi cname="$1" ctype="DNS" if [ ! -z "$2" ]; then if [ "$2" = "ip" ]; then ctype="IP" fi fi sed -i "s/^commonName.*/commonName = ${cname}/g" usercert/usercert.csr.cnf sed -i "s/^subjectAltName.*/subjectAltName = ${ctype}:${cname}/g" usercert/usercert.csr.cnf openssl genrsa -out usercert/private/${cname}.key.pem 2048 chmod 400 usercert/private/${cname}.key.pem openssl req -config usercert/usercert.csr.cnf \ -key usercert/private/${cname}.key.pem \ -new -sha256 \ -out usercert/csr/${cname}.csr.pem openssl ca -batch -config powerca/powerca.cnf \ -passin pass:123456 \ -extensions server_cert -days 3000 -notext -md sha256 \ -in usercert/csr/${cname}.csr.pem \ -out usercert/certs/${cname}.cert.pem openssl x509 -noout -text -in usercert/certs/${cname}.cert.pem openssl verify -CAfile powerca/certs/powerca-chain.cert.pem usercert/certs/${cname}.cert.pem cat usercert/certs/${cname}.cert.pem usercert/private/${cname}.key.pem > /tmp/temp.${cname}.certkey.pem cat /tmp/temp.${cname}.certkey.pem powerca/certs/powerca-chain.cert.pem > usercert/${cname}.ha.pem
然後在 myca 目錄下執行該指令碼就可以了:
$ ./certhelper.sh bigxa $ ./certhelper.sh 10.32.2.22 ip
生成的證書會儲存在 usercert 目錄下。
把證書部署到 web 伺服器
為了建立 HTTPS 站點,我們需要為 web 伺服器 bigxa 配置 ssl 證書。所需的檔案為 powerca-chain.cert.pem、bigxa.key.pem 和 bigxa.cert.pem。筆者的站點通過 HAProxy 做了負載均衡,所以在 HAProxy 的配置中新增 SSL 證書就可以了。具體的做法是通過下面的命令合成 HAProxy 所需的證書檔案:
$ cat bigxa/certs/bigxa.cert.pem bigxa/private/bigxa.key.pem > bigxa/temp.certkey.pem $ cat bigxa/temp.certkey.pem powerca/certs/powerca-chain.cert.pem > bigxa/bigxa.ha.pem
把 bigxa.ha.pem 放置在 bigxa 機器上的 /etc/ssl/private/ 目錄中,所有者和組都設定為 haproxy。最後在 HAProxy 的配置檔案 /etc/haproxy/haproxy.cfg 中設定 ssl 證書的路徑:
bind *:443 ssl crt /etc/ssl/private/usercert.ha.pem
這樣 web 伺服器端的配置就完成了。
把證書鏈安裝到客戶端
Firefox 支援直接匯入 pem 格式的證書鏈,直接匯入這個檔案就可以了。但是 windows 中需要使用 p12(pfx) 等格式,需要把 powerca-chain.cert.p12 安裝到信任的根證書列表中,然後 IE 和 chrome 就可以正常識別到根證書了。
總結
本系列文章主要介紹如何在區域網中建立私有 CA,並用來頒發內網中使用的數字證書。內容以操作步驟為主,目的是讓朋友們拷貝了就能立即使用。如果要了解數字證書的理論知識以及相關概念,建議閱讀更專業的資料。
參考:
OpenSSL Certificate Authority
《openssl-cookbook》