使用nginx进行双向认证,可以实现吊销客户端证书。
在k8s中用ingress配置tls可以实现客户端认证,但吊销功能是不正常的,反复测试未能实现(k8s1.14.8版本)
1 nginx实现Https双向认证
双向认证可自主实现,与机构签发的服务器server证书无关,即只需要自己创建ca和client证书即可。
如果没有机构签发的证书,也可以用自建的ca签发自己本地的server证书,然后再签发client,实现本地环境的双向认证,常用于测试中。
1.1 准备nginx环境
安装nginx yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm yum install nginx -y nginx -v systemctl start nginx
1.2 配置nginx
修改nginx配置文件,已规划好证书路径名称等
vi /etc/nginx/conf.d/443.conf
其中ca.crl是吊销文件,在执行吊销后再启用该配置
server { listen 443 ssl; server_name www.younihao.com; ssl_certificate /etc/nginx/ca/server/server.crt; ssl_certificate_key /etc/nginx/ca/server/server.key; ssl_client_certificate /etc/nginx/ca/private/ca.crt; ssl_session_timeout 5m; ssl_verify_client on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; # ssl_crl /etc/nginx/ca/private/ca.crl; charset utf-8; access_log logs/host.access.log main; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location = /favicon.ico { log_not_found off; access_log off; expires 90d; } location / { root /usr/share/nginx/html; index index.html index.htm; } }
1.3 创建自签CA,server,client证书
1.3.1 创建证书目录
cd /etc/nginx/ mkdir ca cd ca/ mkdir newcerts private conf server users
1.3.2 创建openssl配置文件
vi /etc/nginx/ca/conf/openssl.conf [ ca ] default_ca = myserver [ myserver ] dir = /etc/nginx/ca database = /etc/nginx/ca/index.txt new_certs_dir = /etc/nginx/ca/newcerts certificate = /etc/nginx/ca/private/ca.crt serial = /etc/nginx/ca/serial private_key = /etc/nginx/ca/private/ca.key RANDFILE = /etc/nginx/ca/private/.rand default_days = 3650 default_crl_days = 3650 default_md = sha256 unique_subject = no policy = policy_any [ policy_any ] countryName = match stateOrProvinceName = match organizationName = match localityName = optional commonName = supplied emailAddress = optional
1.3.3 生成ca,server,client证书
生成ca openssl genrsa -out /etc/nginx/ca/private/ca.key openssl req -new -key /etc/nginx/ca/private/ca.key -out private/ca.csr openssl x509 -req -days 3650 -in /etc/nginx/ca/private/ca.csr -signkey /etc/nginx/ca/private/ca.key -out /etc/nginx/ca/private/ca.crt 设置起始序列号 echo FACE > /etc/nginx/ca/serial 创建CA键库 touch /etc/nginx/ca/index.txt 创建一个证书撤销列表 openssl ca -gencrl -out /etc/nginx/ca/private/ca.crl -crldays 3670 -config "/etc/nginx/ca/conf/openssl.conf" 生成自签server证书 openssl genrsa -out /etc/nginx/ca/server/server.key 2048 openssl req -new -key /etc/nginx/ca/server/server.key -out /etc/nginx/ca/server/server.csr openssl ca -in /etc/nginx/ca/server/server.csr -cert /etc/nginx/ca/private/ca.crt -keyfile /etc/nginx/ca/private/ca.key -out /etc/nginx/ca/server/server.crt -config "/etc/nginx/ca/conf/openssl.conf" 生成client证书 openssl genrsa -out /etc/nginx/ca/users/client.key 2048 openssl req -new -key /etc/nginx/ca/users/client.key -out /etc/nginx/ca/users/client.csr openssl ca -in /etc/nginx/ca/users/client.csr -cert /etc/nginx/ca/private/ca.crt -keyfile /etc/nginx/ca/private/ca.key -out /etc/nginx/ca/users/client.crt -config "/etc/nginx/ca/conf/openssl.conf"
上面req在创建证书请求文件的时候,需要输入一系列的参数可参看下图 其中Common Name项,server证书请求时需要填域名,ca与client不做要求;其他项保持一致。
1.3.4 将客户端证书转换成PKCS12文件
生成该文件时候需要设置一个密码,浏览器添加该证书时候会用到。
openssl pkcs12 -export -clcerts -in /etc/nginx/ca/users/client.crt -inkey /etc/nginx/ca/users/client.key -out /etc/nginx/ca/users/client.p12
1.4 验证测试双向认证
1.4.1 修改好了nginx配置,证书路径名称都准确无误
nginx -t #检查配置语法格式
nginx -s reload ##加载新配置
1.4.2 下载client.p12文件
sz /etc/nginx/ca/users/client.p12
1.4.3 浏览器添加客户端证书
每个浏览器方法不一样,自行百度p12证书文件导入,导入证书后重启浏览器。
浏览器访问https://www.younihao.com 会跳出证书选择页面,选定myclient证书,就可以正常访问啦
没有证书访问会得到400 Bad Request(No required SSL certificate was sent)错误
1.5 吊销客户端证书
1.5.1 查看serial号
openssl x509 -in /etc/nginx/ca/users/client.crt -noout -serial -subject [root@loaclhost ]# openssl x509 -in /etc/nginx/ca/users/client.crt -noout -serial -subject serial=FACF ##查到serial号是FACF subject= /C=cn/ST=henan/O=supercom/L=zhengzhou/CN=myclient
1.5.2 创建crlnumber
echo 01 > crlnumber ##第一次增加这个
1.5.3 ssl增加吊销配置
vi /etc/nginx/ca/conf/openssl.conf ##增加下面配置 crlnumber= /etc/nginx/ca/crlnumber
1.5.4 执行吊销client证书
openssl ca -revoke /etc/nginx/ca/newcerts/FACF.pem -config "/etc/nginx/ca/conf/openssl.conf"
1.5.5 重新乘车crl吊销列表
openssl ca -gencrl -out /etc/nginx/ca/private/ca.crl -config "/etc/nginx/ca/conf/openssl.conf" 查看吊销是否成功 openssl crl -in /etc/nginx/ca/private/ca.crl -noout -text
1.5.6 调整nginx参数
vi /etc/nginx/conf.d/443.conf ##增加启用crl配置 ssl_crl /etc/nginx/ca/private/ca.crl; nginx -t #验证重启 nginx -s reload
1.5.7 验证吊销结果
登录浏览器再次访问,选择对应证书,依旧被拒绝访问即为成功。
1.6 nginx认证参考
https://blog.csdn.net/rexueqingchun/article/details/82251563 https://help.aliyun.com/document_detail/54508.html?spm=5176.2020520152.0.0.61bb16ddEk6YWC
2 ingress实现Https双向认证(无吊销功能)
2.1这里是ingress示例
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/auth-tls-verify-client: "on" nginx.ingress.kubernetes.io/auth-tls-secret: "default/ca-secret" nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1" nginx.ingress.kubernetes.io/auth-tls-error-page: "http://www.mysite.com/error-cert.html" nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true" name: nginx-test namespace: default spec: rules: - host: mydomain.com http: paths: - backend: serviceName: http-svc servicePort: 80 path: / tls: - hosts: - mydomain.com secretName: tls-secret
2.2 创建tls-secret和ca-secret
tls-secret可以使用自建的,也可以使用机构签发的服务器证书 kubectl create secret generic tls-secret --from-file=tls.crt=server.crt --from-file=tls.key=server.key ca-secret到自己的ca目录创建 cd /etc/nginx/ca/private kubectl create secret generic ca-secret --from-file=ca.crt=ca.crt 然后创建ingress kubectl create -f ingress.yaml
2.3 添加其他annotations
ingress 跨域问题 需要在ingress中添加配置下面annotations nginx.ingress.kubernetes.io/cors-allow-headers: >- DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization nginx.ingress.kubernetes.io/cors-allow-methods: 'PUT, GET, POST, OPTIONS' nginx.ingress.kubernetes.io/cors-allow-origin: '*' nginx.ingress.kubernetes.io/enable-cors: 'true' ingress 强制443 nginx.ingress.kubernetes.io/ssl-redirect: 'true' ingress 白名单访问 nginx.ingress.kubernetes.io/whitelist-source-range: '192.168.5.3'
2.4 ingress 可参考
https://kubernetes.github.io/ingress-nginx/examples/auth/client-certs/ https://kubernetes.github.io/ingress-nginx/examples/PREREQUISITES/#client-certificate-authentication https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/