如何在 Linux Chrome 和 Firefox 上信任自签名本地主机证书

How to trust self-signed localhost certificates on Linux Chrome and Firefox

我尝试为指向 127.0.0.1 的自定义本地域生成自签名证书:

# /etc/hosts
127.0.0.1 subdomain.domain.local

我已经使用 openssl 生成了一个自签名证书,请记住过去一切正常。但是好像从Chrome58开始,对使用自签名证书的限制就多了很多

我的尝试以“您的连接不是私人连接”结束,并出现以下错误之一:

我很确定我在这个过程中遗漏了一些东西。拜托,任何人都可以提供处理备用名称的有效配置以及创建相应 CA 和证书的确切步骤,以便 Chrome 和 Firefox 可以处理我的本地自定义域吗?

TLDR

  1. 创建文件generate.sh

    #!/usr/bin/env bash
    find . \( -name ".*" -o -name "*.srl" \) -type f -delete
    cp /usr/lib/ssl/openssl.cnf .cnf
    python <(
    cat << "END"
    import sys
    from ConfigParser import ConfigParser
    from StringIO import StringIO
    
    domain = sys.argv[1]
    
    config = ConfigParser()
    config.optionxform = lambda option: option
    
    name = "{}.cnf".format(domain)
    
    with open(name, "rb") as stream:
      config.readfp(StringIO("[top]\n" + stream.read()))
    
    config.set(" v3_ca ", "subjectKeyIdentifier", "hash")
    config.set(" v3_ca ", "authorityKeyIdentifier", "keyid:always,issuer")
    config.set(" v3_ca ", "basicConstraints", "critical, CA:TRUE, pathlen:3")
    config.set(" v3_ca ", "keyUsage", "critical, cRLSign, keyCertSign")
    config.set(" v3_ca ", "nsCertType", "sslCA, emailCA")
    
    config.set(" v3_req ", "basicConstraints", "CA:FALSE")
    config.set(" v3_req ", "keyUsage", "nonRepudiation, digitalSignature, keyEncipherment")
    config.set(" v3_req ", "subjectAltName", "@alt_names")
    config.remove_option(" v3_req ", "extendedKeyUsage")
    
    config.add_section(" alt_names ")
    config.set(" alt_names ", "DNS.1", domain)
    config.set(" alt_names ", "DNS.2", "*.{}".format(domain))
    
    config.set(" req ", "req_extensions", "v3_req")
    
    with open(name, "wb") as stream:
        config.write(stream)
    END
    ) 
    tail -n +2 .cnf > .cnf.tmp && mv .cnf.tmp .cnf
    echo "\n" | openssl genrsa -aes256 -out .ca.key 2048
    chmod 400 .ca.key
    openssl req -new -x509 -subj "/CN=" -extensions v3_ca -days 3650 -key .ca.key -sha256 -out .ca.crt -config .cnf
    openssl genrsa -out .key 2048
    openssl req -subj "/CN=" -extensions v3_req -sha256 -new -key .key -out .csr
    openssl x509 -req -extensions v3_req -days 3650 -sha256 -in .csr -CA .ca.crt -CAkey .ca.key -CAcreateserial -out .crt -extfile .cnf
    openssl x509 -in .crt -text -noout
    
  2. 致电./generate.sh example.com

    Requires Python 2


All credits go to this excellent article by Fabian Lee.

使用 OpenSSL 创建受信任的 CA 和 SAN 证书

  1. 自定义openssl.cnf
  2. 创建 CA 证书
  3. 使用 CA 签名的 SAN 创建服务器证书

先决条件

作为先决条件,确保安装了 SSL 包:

$ sudo apt install libssl1.0.0 -y

自定义openssl.cnf

第一步是获取系统上可用的 openssl.cnf 模板。在 Ubuntu 上,可以在 /usr/lib/ssl/openssl.cnf 找到它。您可能会在 Mac/System/Library/OpenSSL/OS 和 Redhat 变体/etc/pki/tls 中找到它。

export prefix="mydomain"

cp /usr/lib/ssl/openssl.cnf $prefix.cnf

$prefix.cnf 需要用我们将要生成的证书的具体信息进行修改。

[ v3_ca ] 部分下,添加以下值。对于 CA,这表示我们正在创建一个将用于密钥签名的 CA。

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical, CA:TRUE, pathlen:3
keyUsage = critical, cRLSign, keyCertSign
nsCertType = sslCA, emailCA

然后在 [ v3_req ] 部分下,设置以下内容以及此证书的所有有效替代名称。

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
#extendedKeyUsage=serverAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = mydomain.com 
DNS.2 = *.dydomain.com

同时取消注释 [ req ] 部分下的以下行,以便使用 v3 扩展名创建证书请求。

req_extensions = v3_req

当我们生成每种类型的密钥时,我们指定要使用的扩展部分,这就是为什么我们可以共享 $prefix.cnf 来创建 CA 和 SAN 证书。

创建 CA 证书

现在我们将开始使用 OpenSSL 创建必要的密钥和证书。首先生成private/public RSA密钥对:

openssl genrsa -aes256 -out ca.key.pem 2048

chmod 400 ca.key.pem

这使用基于 AES256 的密码短语对密钥文件进行编码。 然后我们需要创建自签名根 CA 证书。

openssl req -new -x509 -subj "/CN=myca" -extensions v3_ca -days 3650 -key ca.key.pem -sha256 -out ca.pem -config $prefix.cnf

您可以使用以下方式验证此根 CA 证书:

openssl x509 -in ca.pem -text -noout

这将显示根 CA 证书,IssuerSubject 将相同,因为这是自签名的。这被标记为 CA:TRUE 意味着它将被识别为根 CA 证书;这意味着浏览器和 OS 将允许将其导入到其受信任的根证书存储中。

Issuer: CN=myca 
... 
Subject: CN=myca 
... 
X509v3 Basic Constraints: 
  critical CA:TRUE, pathlen:3 
X509v3 Key Usage: 
  critical Certificate Sign, CRL Sign 
Netscape Cert Type: 
  SSL CA, S/MIME CA

创建由 CA 签名的服务器证书

现在创建了根 CA,我们切换到服务器证书。首先生成private/public RSA密钥对:

openssl genrsa -out $prefix.key.pem 2048

我们没有在此密钥上设置密码,仅仅是因为 CA 是更有价值的目标,而且我们始终可以重新生成服务器证书,但请随时采取额外的预防措施。

然后创建服务器证书签名请求:

openssl req -subj "/CN=$prefix" -extensions v3_req -sha256 -new -key $prefix.key.pem -out $prefix.csr

然后使用以下内容生成服务器证书:服务器签名请求、CA 签名密钥和 CA 证书。

openssl x509 -req -extensions v3_req -days 3650 -sha256 -in $prefix.csr -CA ca.pem -CAkey ca.key.pem -CAcreateserial -out $prefix.crt -extfile $prefix.cnf

$prefix.key.pem是服务器私钥,$prefix.crt是服务器证书。验证证书:

openssl x509 -in $prefix.crt -text -noout

这将显示证书,Issuer 将是 CA 名称,而主题是前缀。这未设置为 CA,并且 Subject Alternative Name 字段包含将被浏览器视为有效的 URL。

Issuer: 
 CN=myca 
... 
Subject: 
  CN=mydomain 
... 
X509v3 Basic Constraints: 
  CA:FALSE 
X509v3 Key Usage: 
  Digital Signature, Non Repudiation, Key Encipherment 
X509v3 Subject Alternative Name:
  DNS:mydomain.com, DNS:*.mydomain.com

浏览器评价

当您第一次使用带有 CA 签名的 SAN 证书将 Chrome 或 Firefox 指向站点时,它会抛出与自签名 SAN 证书相同类型的异常。这是因为根 CA 证书不是签名证书的可信来源。

Chrome

Linux

在 Linux 上,Chrome 管理自己的证书存储,您应该再次将 ca.pem 导入 Authorities。这现在应该使安全图标变为绿色。

Windows

在 Chrome 设置 (chrome://settings) 中,搜索 certificates 并单击 Manage Certificates。在 Windows 这将打开 Windows 证书管理器,您应该在 Trusted Root Certification Authorities 选项卡中导入 ca.pem 文件。这相当于通过 mmc.exelocal user 受信任的根存储(不是计算机级别)中添加它。

火狐

在 Firefox 选项 about:preferences 中,搜索 certificates 并单击 View Certificates。转到 Authorities 选项卡并导入 ca.pem。选中该框以使其信任网站,现在当您访问该页面时,锁定图标应该变为绿色。