创建 *.local ssl 证书

创建 *.local ssl 证书

我正在尝试设置一个 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导入到 chromium 的权威中,它可以正常工作。

然后我创建一个证书请求:

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_FORMATchrome 和SEC_ERROR_REUSED_ISSUER_AND_SERIALfirefox。在生成证书之前,我肯定重置了我的串行文件和索引文件。

答案1

您将 SAN 添加到企业社会责任但你没有告诉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_extensionsca 将扩展名放入证书中,但是才不是当存在扩展时,根据标准(如 rfc5280)的要求将证书版本设置为 v3。

这是否是一个错误是有争议的;联机帮助页说x509_extensions/extensions控制 v3 设置,并且通过不是说任何类似的话都copy_extensions意味着事实并非如此,但恕我直言,这肯定是一个非常次优的功能。编辑:这是一个错误,将被修复,但在此之前使用解决方法,请参阅https://unix.stackexchange.com/a/394465/59699

但是:在我的测试中,这实际上并没有解决您的问题。即使证书已*.local在 SAN 中CN 并且(现在)在其他方面有效,我的 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.org,Chrome 和 IE11 都喜欢但仍然不是 Firefox(当然,在真正的 TLD 中为自己分配名称.org并不是 DNS 应该工作的方式)。

这让我陷入困境。通过一些工作,OpenSSL 可以生成一个包含几乎任何你想要的内容的证书,但 Firefox 和 Chrome 会接受我不知道。我会尝试调查这一点并更新如果我发现任何东西。


我希望您的意思是*.local只为服务器 CSR 而不是为 CA(自签名)证书提供 CommonName。如果 CA 和叶证书的主题名称相同,则任何内容都无法可靠运行。编辑:您编辑的问题确认它们是正确不同的。尽管它没有提及ca您所使用的策略所要求的指定国家/地区、州/省和组织。

注意“自签名”是一个艺术术语,意味着用相同的签名钥匙。您的 CA 证书是自签名的。您的服务器证书是您自己使用自己的密钥签名的,但它是不是自签名。尝试将自签名证书的说明应用于非自签名证书是您的问题的一部分。

Gilles关于md5签名算法的观点也是正确的。

编辑:“重置”设置的序列号(和索引)openssl ca是一个坏主意,除非您永久丢弃 CA 证书和名称它们被用来。标准规定,给定的 CA 不得颁发多个具有相同序列值的证书,而序列文件就是实现这一点的方式openssl ca(也是x509 -req)。如今,“真实”(公共)CA 不再使用简单的计数器,而是包含熵来阻止对 PKI 的冲突攻击 - google hashclash - 但这对于像您这样的个人 CA 来说不是问题。我很容易相信,如果浏览器(或其他依赖者)看到具有相同序列和 CA 名称的多个证书,它会感到不高兴,尽管我不希望浏览器持久存储叶证书 - 从而同时看到旧的和新的证书在一个进程中,除非长时间运行 - 除非您将其导入到适用的商店,包括在 Firefox 中,如果您将其设置为永久“例外”。

答案2

顶级域(例如.local或 )不允许使用通配符证书.com,并且 Firefox 或 IE 也不接受通配符证书。https://crbug.com/736715

答案3

至少一个明显的问题是您正在创建一个签名的证书MD5。 MD5 已被弃用一段时间,并且自 2012 年以来在证书中遭到破坏。有一段时间没有信誉良好的服务器支持它。

改成。default_md md5default_md sha256

如果您正在遵循推荐 MD5 的教程,请将其扔掉,它太旧了,没有任何用处。

请注意,我还没有审查是否存在其他问题。服务器日志应该会有帮助。

答案4

这两个答案都不适合我,但我设法想出了一个可以满足我未来需求的 Powershell 脚本:

#openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout localhost-CA.pem -out localhost-CA.crt -subj '/emailAddress=<redacted>/O=<redacted>/CN=<redacted>/C=US' -extensions v3_ca -addext 'nsCertType=sslCA' # uncomment to generate a root CA cert.
'basicConstraints=CA:FALSE`
extendedKeyUsage=serverAuth`
subjectAltName=IP.1:127.0.0.1,IP.2:::1,DNS:localhost' | Set-Content sign.conf
Invoke-Expression "openssl req -new -sha256 -key localhost.pem -out localhost.csr -subj '/emailAddress=<redacted>/O=<redacted>/CN=<redacted>/C=US' $((Get-Content sign.conf | ForEach-Object { "-addext '$_'" }) -join ' ')"
openssl x509 -req -in localhost.csr -CA localhost-CA.crt -CAkey localhost-CA.pem -CAcreateserial -out localhost.crt -days 3650 -sha256 -extfile sign.conf -extensions default
Remove-Item sign.conf

它将与用于生成 CSR 的扩展名相同的扩展名传递给新的证书生成实用程序,而不必弄乱配置文件,因为根据我的口味,对于这么小的东西来说,这有点太多了,生成的证书是 V3 。

相关内容