如果想用 Nginx 保护某一个重要的页面或者程序入口,一般会采用 Basic Authentication 的方式,当用户访问某个页面时,Nginx 会弹出一个输入框,让用户验证用户名和密码。这种方式比较原始,同时在用户比较多的时候管理起来也比较麻烦。因此可以引入 ClientSide Certificate Authentication,即「用户侧证书认证」的方式。其原理是通过 CA 向可信的用户颁发数字证书,用户凭数字证书访问网站,同时这个证书可以设置期限,到期后自动吊销(未到期也可以主动吊销)。
设置 CA
创建 CA 密钥
openssl genrsa -des3 -out ca.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes) ....................................................................................++++ ..++++ e is 65537 (0x010001) Enter pass phrase for ca.key: Verifying - Enter pass phrase for ca.key:
运行后会要输入口令,这个口令是用来保护 CA 私钥的,必须要记住,而且最好设置一个比较复杂的。
创建 CA 证书
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
创建 CA 证书的时候会用到刚才创建的 CA 密钥的口令,接下来会输入一些证书的基本信息。注意:CA 和用户的 Common Name 不能一样,否则将遇到 Bug 。另外,这里设置 CA 证书的有效期是 365 天,即一年。你可以根据实际情况修改。
Enter pass phrase for ca.key: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:BJ Locality Name (eg, city) []:Beijing Organization Name (eg, company) [Internet Widgits Pty Ltd]:Uncle Organizational Unit Name (eg, section) []:Tech Common Name (e.g. server FQDN or YOUR name) []:Uncle #Common Name,不可与用户证书的 Common Name 一致 Email Address []: xxxx@xxxx.com #填写 CA 管理员的邮箱地址
如果你想看证书里面都有啥信息,可以用下面这个命令:
openssl x509 -in ca.crt -noout -text
创建用户证书
用户证书是签发给具体用户的,首先要生成用户密钥、CSR,最后用 CA 证书来签名。
生成用户密钥
openssl genrsa -des3 -out user.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes) ............................++++ ........................................................................................................................................++++ e is 65537 (0x010001) Enter pass phrase for user.key: Verifying - Enter pass phrase for user.key:
同样的,用户密钥也需要有一个口令进行保护,用户口令和 CA 口令不能一样。
生成 CSR
openssl req -new -key user.key -out user.csr
这一步首先会让输入用户密钥(user.key)的口令,输入后会填写一些基本的证书信息:
Enter pass phrase for user.key: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:BJ Locality Name (eg, city) []:BeiJing Organization Name (eg, company) [Internet Widgits Pty Ltd]:Uncle Organizational Unit Name (eg, section) []:TECH Common Name (e.g. server FQDN or YOUR name) []:Uncle #注意,这里不能和 CA 证书的 Common Name 一样 Email Address []:noappcn@icloud.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: #不用填,直接回车 An optional company name []: #不用填,直接回车
用 CA 的密钥对 CSR 进行签名
openssl x509 -req -days 365 -in user.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out user.crt
签名时,需要用到 CA 密钥的口令。
生成 PCKS#12(PFX)文件
然后是将证书文件打包成 PCKS#12 格式:
openssl pkcs12 -export -out user.pfx -inkey user.key -in user.crt -certfile ca.crt
注意,第一个要输入的是用户密钥的口令,然后要输入导出口令,这个口令是用来保护 PCKS#12 文件的(不知道口令的人将无法导入证书)
openssl pkcs12 -export -out user.pfx -inkey user.key -in user.crt -certfile ca.crt Enter pass phrase for user.key: Enter Export Password: Verifying - Enter Export Password:
配置 Nginx
在需要用证书保护的 Server 配置块中加入:
ssl_client_certificate /etc/nginx/client_certs/ca.crt; ssl_verify_client on; ssl_verify_depth 2; if ($ssl_client_verify != SUCCESS) { return 400; }
最后重启 Nginx 或者 LNMP 服务。
将 PFX 文件安装到可信的设备
最后,把目录中的 .pfx 文件分发到可信的设备并且导入,即可完成。
文章评论