Openssl

創建 *.local ssl 證書

  • January 13, 2021

我正在嘗試設置一個 SSL 證書,該證書將使任何 *.local 網站都可以通過 https 執行。我有所有 .local 域都指向我的本地機器。我在開發網站時使用這些。許多新功能(地理位置、服務人員等)都需要 SSL。

我相信對於 Chrome/Firefox 的最新版本,舊式自簽名證書不再有效。

以下是我在遵循這些指南的組合後採取的步驟: https ://deliciousbrains.com/https-locally-without-browser-privacy-errors/

https://codeghar.wordpress.com/2008/03/17/create-a-certificate-authority-and-certificates-with-openssl/

https://stackoverflow.com/questions/27294589/creating-self-signed-certificate-for-domain-and-subdomains-neterr-cert-commo

這是我的配置文件:

#..................................
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /home/*****/Sites/root-ca
serial = $dir/serial
database = $dir/index.txt
new_certs_dir = $dir/certs
certificate = $dir/certs/cacert.pem
private_key = $dir/private/cakey.pem
default_days = 3000
default_md = sha256
preserve = no
email_in_dn = no
nameopt = default_ca
certopt = default_ca
policy = policy_match
copy_extensions = copyall
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 2048 # Size of keys
default_keyfile = key.pem # name of generated keys
default_md = md5 # message digest algorithm
string_mask = nombstr # permitted characters
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
# Variable name Prompt string
#------------------------- ----------------------------------
0.organizationName = Organization Name (company)
organizationalUnitName = Organizational Unit Name (department, division)
emailAddress = Email Address
emailAddress_max = 40
localityName = Locality Name (city, district)
stateOrProvinceName = State or Province Name (full name)
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
commonName = Common Name (hostname, IP, or your name)
commonName_max = 64
# Default values for the above, for consistency and less typing.
# Variable name Value
#------------------------ ------------------------------
0.organizationName_default = *****
localityName_default = *****
stateOrProvinceName_default = *****
countryName_default = *****
emailAddress_default = *****
[ v3_ca ]
basicConstraints = CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
subjectAltName       = @alternate_names
[ v3_req ]
subjectKeyIdentifier = hash
basicConstraints     = CA:FALSE
keyUsage             = digitalSignature, keyEncipherment
subjectAltName       = @alternate_names
nsComment            = "OpenSSL Generated Certificate"

[ alternate_names ]

DNS.1       = *.local

我首先創建一個新的證書頒發機構:

openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out certs/cacert.pem -days 3000 -config conf/caconfig.cnf

我在這裡給出了通用名稱作為我的名字

Common Name (hostname, IP, or your name) []:Jonathan Hodgson

然後我將文件certs/cacert.pem導入鉻的權威,它可以正常工作。

然後我創建一個證書請求:

openssl req -extensions v3_req -new -nodes -out local.req.pem -keyout private/local.key.pem -config conf/caconfig.cnf

我在這裡將通用名稱命名為 *.local

Common Name (hostname, IP, or your name) []:*.local

然後我簽署請求:

openssl ca -out certs/local.cert.pem  -config conf/caconfig.cnf -infiles local.req.pem

我將文件添加到我的 http 配置中:

<VirtualHost *:80>
   ServerName test.local
   ServerAlias *.local
   VirtualDocumentRoot /home/jonathan/Sites/%-2/public_html
   CustomLog /home/jonathan/Sites/access.log vhost_combined
   ErrorLog /home/jonathan/Sites/error.log
</VirtualHost>

<VirtualHost *:443>
   ServerName test.local
   ServerAlias *.local
   VirtualDocumentRoot /home/jonathan/Sites/%-2/public_html
   CustomLog /home/jonathan/Sites/access.log vhost_combined
   ErrorLog /home/jonathan/Sites/error.log
   SSLEngine On
   SSLCertificateFile /home/jonathan/Sites/root-ca/certs/local.cert.pem
   SSLCertificateKeyFile /home/jonathan/Sites/root-ca/private/local.key.pem
</VirtualHost>

我已經重新啟動了 apache,但我仍然得到NET::ERR_CERT_COMMON_NAME_INVALID

我的印像是,這是因為我需要將 subjectAltName 添加到我已經完成的配置文件中。

請讓我知道我應該做些什麼不同的事情。

提前感謝您的幫助

編輯

我認為問題與萬用字元有關。如果我將alternate_names 設置為example.local 並將請求的通用名稱設置為example.local,example.local 在Chrome 和Firefox 中都顯示為安全的。

我嘗試將 DNS.1 設置為local並將 DNS.2 設置為*.local,然後我就進入ERR_SSL_SERVER_CERT_BAD_FORMAT了 chrome 和SEC_ERROR_REUSED_ISSUER_AND_SERIALFirefox。在生成證書之前,我肯定會重置我的序列文件和索引文件。

您將 SAN 添加到CSR,但您沒有**告訴ca在證書中包含來自 CSR 的擴展。**請參閱 https://security.stackexchange.com/questions/150078/missing-x509-extensions-with-an-openssl-generated-certificate或線上手冊頁,ca 網址copy_extensions

編輯:您需要x509_extensionsca配置中指定,或等效但不太方便的命令行選項-extensions,在任何一種情況下都指向一個存在但如果您不想要任何 CA 所需的擴展可以為空的部分。起初我沒有註意到這一點,因為我從未嘗試過僅從 CSR 擴展而不是從配置擴展的情況*,這對於大多數 CA 來說是不現實的。如果您指定的copy_extensions不是none(並且 CSR 有一些)但未指定x509_extensions,則ca 確實將副檔名放入證書中,但在存在副檔名時沒有*按照標準(如 rfc5280)的要求將證書版本設置為 v3。

這是否是一個錯誤是有爭議的;手冊頁說x509_extensions/extensions控制 v3 設置,並且沒有說任何類似的事情copy_extensions暗示沒有,但恕我直言,這肯定是一個非常次優的功能。編輯:這是一個錯誤,將被修復,但在此之前使用解決方法,請參閱https://unix.stackexchange.com/a/394465/59699

但是:在我的測試中,這實際上並沒有解決您的問題。即使證書*.local在 SANCN 中並且(現在)在其他方面有效,我的 Firefox (53.0.2) 和 Chrome (59.0.3071.109) 仍然分別使用 SSL_ERROR_CERT_DOMAIN_ERROR 和 ERR_CERT_COMMON_NAME_INVALID 拒絕它。我猜想他們可能不會local從正常的 2+ 級邏輯中排除並嘗試過*.example.local:Chrome 確實接受了這一點,但 Firefox 不接受。我也嘗試過*.example.orgChrome 和 IE11 都喜歡這樣*,*但仍然不是 Firefox(當然,在真實的 TLD 中.org為自己分配名稱並不是 DNS 應該工作的方式)。

這讓我卡住了。通過一些工作,可以使 OpenSSL 生成一個包含幾乎任何你想要的東西的證書,但我不知道Firefox 和 Chrome 會*接受什麼。*如果我發現任何東西,我會嘗試調查並更新。


我希望你的意思是你*.local只為伺服器 CSR 而不是 CA(自簽名)證書作為 CommonName。如果 CA 和葉證書的主題名稱相同,則沒有任何東西可以可靠地工作。編輯:您編輯的 Q 確認它們是正確的不同。儘管它沒有提到ca您使用的策略所要求的指定國家、州和組織。

注意“自簽名”是一個藝術術語,表示使用相同的密鑰簽名。您的 CA 證書是自簽名的。您的伺服器證書由您自己使用自己的密鑰簽名,但不是自簽名的。嘗試將自簽名證書的說明應用於非自簽名證書是您問題的一部分。

而 Gilles 關於 md5 對於簽名算法的觀點也是正確的。

編輯:設置的“重置”序列(和索引)openssl ca是一個壞主意,除非您永久丟棄它們所使用的 CA 證書和名稱。標準規定,給定的 CA 不得頒發多個證書中具有相同序列值的證書,並且序列文件是方式openssl ca(以及x509 -req) 實現這一點。如今,“真實”(公共)CA 不再使用簡單的計數器,而是包含熵來阻止對 PKI 的碰撞攻擊——google hashclash——但這對於像你這樣的個人 CA 來說不是問題。如果瀏覽器(或其他依賴者)看到具有相同序列號和 CA 名稱的多個證書,我很容易相信它會不高興,儘管我不希望瀏覽器持久儲存葉證書——因此會同時看到舊證書和新證書在一個過程中,除非長時間執行 - 除非您將其導入適用的商店,包括在 Firefox 中,如果您將其設為永久“例外”。

引用自:https://unix.stackexchange.com/questions/371997