OpenSSL可以做为CA中心,创建根密钥并签发证书。

初始化:

$ mkdir certs crl newcerts private
$ touch index.txt
$ echo 1000 > serial

下载默谁的openssl.cnf配置文件:

$ curl -o openssl.cnf https://webencrypt.org/certificateauthority/openssl.cnf.txt

创建私钥对:

$ openssl genrsa -out private/ca.key.pem 4096

创建根密钥:

$ openssl req -config openssl.cnf \
      -key private/ca.key.pem \
      -new -x509 -days 7300 -sha256 -extensions v3_ca \
      -out certs/ca.cert.pem

查看证书内容:

$ openssl x509 -noout -text -in certs/ca.cert.pem

A certificate revocation list (CRL) is “a list of digital certificates that have been revoked by the issuing certificate authority (CA) before their scheduled expiration date and should no longer be trusted”.

The Online Certificate Status Protocol (OCSP) is an Internet protocol used for obtaining the revocation status of an X.509 digital certificate. It is described in RFC 6960 and is on the Internet standards track. It was created as an alternative to certificate revocation lists (CRL), specifically addressing certain problems associated with using CRLs in a public key infrastructure (PKI). Messages communicated via OCSP are encoded in ASN.1 and are usually communicated over HTTP. The “request/response” nature of these messages leads to OCSP servers being termed OCSP responders.

$ openssl genrsa -out client.pem 4096

$ openssl req -new -key client.pem -out client.csr

$ openssl ca -in client.csr -cert certs/ca.cert.pem -keyfile private/ca.key.pem -out client.crt -config openssl.cnf

$ openssl pkcs12 -export -clcerts -in client.crt -inkey client.pem -out client.p12

nginx.conf:

ssl_client_certificate   clientca.pem;
ssl_verify_client    on;

其中 ssl_verify_client 的值可以是 optional | on 者两个:

  • 当选择 on 时会强制进行客户端认证,失败无法访问;
  • 当选择 optional 的时候,认证是可选的,是否认证成功可以从 $ssl_client_verify 变量得知。

我们想要网站根目录是任意访问的,但是 /admin 路径下是需要认证才能访问的,就可以这么配置:

server {
    ...
    ssl_client_certificate clientca.crt;
    ssl_verify_client optional;
    ...

    location /admin {
        if ($ssl_client_verify != SUCCESS) {
            return 401;
        }
        proxy_pass http://localhost:5000;
    }
}
  • $ssl_client_verify SUCCESS OR NONE
  • $ssl_client_s_dn
  • $ssl_client_cert
  • $ssl_client_cert_raw


cURL example:

$ curl -v -s -k --key client.key --cert client.crt https://example.com