我正在尝试设置一个 SSL 证书,使任何 *.local 网站都可以通过 https 运行。我的所有 .local 域都指向我的本地计算机。我在开发网站时使用这些。许多新功能(地理位置、服务工作者等)都需要 SSL。
我相信对于最新版本的 Chrome/Firefox,老式的自签名证书不再有效。
以下是我在遵循这些指南的组合后所采取的步骤: https://deliciousbrains.com/https-locally-without-browser-privacy-errors/
这是我的配置文件:
#..................................
[ 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_FORMAT
chrome 和SEC_ERROR_REUSED_ISSUER_AND_SERIAL
firefox。在生成证书之前,我肯定重置了我的串行文件和索引文件。
答案1
您将 SAN 添加到企业社会责任但你没有告诉ca
包括 CSR 的扩展在证书中。看
https://security.stackexchange.com/questions/150078/missing-x509-extensions-with-an-openssl- generated-certificate或手册页ca
也在网络上在copy_extensions
编辑:你还需要x509_extensions
在ca
配置中指定,或者等效但不太方便的命令行选项-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
在 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 md5
default_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 。