HTTPS的双向认证(七)
上一篇文章讲解了容器的使用方法,这篇文章使用这个容器,启动容器里的nginx
服务,并使用容器里自带的curl
命令访问nginx
服务,看一下「https双向认证」的实际过程。
首先启动并且登录这个容器:
$ docker run -it alchemystudio/nginx-ssl-bidirection sh
登录进容器以后,启动nginx
服务:
$ nginx
然后查看nginx
是否正确启动了:
$ ps -ef | grep nginx
此时使用curl
命令访问nginx
服务:
$ curl https://localhost
执行上面的命令,可以看到curl
的报错信息:
如上所示,可以看到curl
在访问服务端的时候,说服务端提供的证书是self signed certificate
,就是自签名证书,因此无法验证这张证书。
因为我们的「服务端证书」不是第三方权威机构签名的,所以curl
无法进行验证。我们有两个方案可以解决这个问题:
- 使用
curl
的-k
选项,让curl
跳过对「服务端证书」的验证过程。 - 使用
curl
的--cacert
选项,指定验证「服务端证书」所需要使用的「CA证书」。
因为我们的「服务端证书」是自签名的,因此「服务端证书」的签名证书就是它自己。
上面两种方案我们都执行一下看看,首先是使用-k
选项跳过对「服务端证书」的签名验证:
$ curl -k https://localhost
可以看到这回curl
命令从nginx
服务这边返回了内容,说明curl
跳过了对「服务端证书」的验证,建立了和nginx
服务的连接,并取得了服务端返回的内容。
如果不跳过验证,那么就要在curl
访问nginx
服务的时候挂上「服务端证书」作为验证用的「CA证书」。命令如下:
$ curl --cacert /cert/server.crt https://localhost
执行上面命令的结果和跳过验证是一致的:
可以看到挂上「服务端证书」作为「CA证书」以后,curl
验证通过了服务端提供的证书,并且成功和服务端建立了连接,并且返回了nginx
提供的页面。
接下来看一下返回页面的内容。可以看到返回的内容是400 Bad Request
,错误信息也给出了:
No required SSL certificate was sent
也就是说「服务端」要「客户端」提供证书,但是我们在curl
中没有提供「客户端证书」,因此nginx
服务无法验证「客户端」的身份。
因此我们要在curl
请求服务端的时候,挂上「客户端证书」。方法是使用curl
的--cert
选项:
$ curl --cacert /cert/server.crt --cert /cert/client.crt https://localhost
以下是命令的执行结果:
可以看到,虽然在curl
的请求命令挂上了--cert
选项,但是这个证书curl
无法使用,因为curl
作为「客户端证书」的拥有者,还需要拥有「客户端证书」的「私钥」。这样,服务端使用「客户端证书」的「公钥」把一些加密数据发还给「客户端」的时候,「客户端」才能使用「私钥」正确解密。
这一点其实和nginx
服务这边的配置文件里,同时配置了「服务端证书」和「服务端证书私钥」的形式,是对等的。
因此在使用curl
访问「服务端」的时候,还要加上--key
选项,挂上「客户端」的「私钥文件」:
$ curl --cacert /cert/server.crt --cert /cert/client.crt --key /cert/client.key https://localhost
以下是命令的执行结果:
可以看到这次连接,curl
从nginx
服务端取回了Hello, world!
的页面数据。也就是说这次基于「ssl双向认证握手」的连接成功了。
因为在之前的文章里面已经看过,给「客户端证书」签名的「CA证书」是配置在nginx
服务的「配置文件」里的。所以curl
出示的「客户端证书」是被「服务端」所信任的。
本篇文章就写到这里,下一篇讲解这个容器的另一种使用方法,也就是通过docker-compose
启动容器,并在host端访问容器里面nginx
服务的方法。
- 上一篇 HTTPS的双向认证(六)
- 下一篇 HTTPS的双向认证(八)