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

$ 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