Cloudflare SSL CDN

Cloudflare

Let't Encrypt TLS-SNI-01 续签证书的方式因为安全原因被禁止使用。虽然certbot可以使用HTTP认证的方式暂时绕过,不过听说cloudflare更省心。

cloudflare支持Flexible SSL, Full SSL, Full SSL (strict)。Full SSL (strict) 需要服务器部署一个cloudflare信任的证书,可以是正规CA签发的证书,也可以是cloudflare签发的证书。

Origin Certificates 功能就是使用cloudflare签发的证书部署在源服务器,保持源服务器与cloudflare加密通讯。部署完成就可以使用Full SSL (strict)。

origin-ca
Origin CA uses a Cloudflare-issued SSL certificate instead of one issued by a Certificate Authority. This reduces much of the friction around configuring SSL on your origin server, while still securing traffic from your origin to Cloudflare. Instead of having your certificate signed by a CA, you can generate a signed certificate directly in the Cloudflare dashboard.

Authenticated Origin Pulls是一个TLS客户端认证的选项,开启这个功能需要在服务器验证客户端的身份

ssl_client_certificate /etc/nginx/certs/cloudflare.crt;
ssl_verify_client on;

cloudflare.crt 是cloudflare的公钥,没有cloudflare的私钥而直接访问源服务器会返回400,这样就保护了源服务器,而访问cloudflare是没有问题的。

使用curl进行验证:

curl -I https://blog.marskid.net:443/ --resolve blog.marskid.net:443:[origin_ip] -k

返回应该是HTTP/1.1 400 Bad Request

如果开启SSL客户端验证,没有私钥任何人都无法直接访问源服务器。如果想让自己能够访问源服务器的资源,有两种方法:

一是设置ssl_verify_client optional;
二是在/etc/nginx/certs/cloudflare.crt中加入自己签发的CA的公钥,客户端使用自签CA认证过的私钥访问。/etc/nginx/certs/cloudflare.crt中可以有多个公钥;

签发过程可参考 基于openssl的单向和双向认证SSL双向认证

对于客户端认证,只需要自签Root CA证书和客户端私钥和证书,不需要与服务端是同一个CA,也不需要认证过的CA。或使用如下命令自签一对一证书,不需要CA:

openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout client.key -out client.pem -subj "/C=US/ST=Mars/L=Mars/O=Mars/OU=Mars/CN=marskid.net"

生成的client.key为私钥,client.pem为公钥。将client.pem 内容复制到ssl_client_certificate指定的文件里,客户端使用client.key和client.pem来访问服务端。

如果使用Root CA来验证证书,则将CA的公钥复制到ssl_client_certificate指定的文件里,好处是该CA可以签署多份客户端证书而不用修改服务端文件。

如果配置正确,可以使用curl进行验证。

curl -I https://blog.marskid.net:443/ --resolve blog.marskid.net:443:origin_ip --cert client.pem --key client.key --cacert cloudflare_origin_rsa.pem

返回应该是HTTP/1.1 200 OK,而不是HTTP/1.1 400 Bad Request

其中client.pem和client.key是客户端证书和私钥,cloudflare_origin_rsa.pem是cloudflare的CA公钥,可以在这里找到。

相应的stunnel的配置如下:

[proxy]
client = yes
accept = 127.0.0.1:9000
connect = origin_ip:port
sni = marskid.net
checkHost = marskid.net
cert = /etc/stunnel/client.pem
key = /etc/stunnel/client.key
verifyChain = yes
CAfile = /etc/stunnel/cloudflare_origin_rsa.pem

可以使用curl验证:

curl -I http://blog.marskid.net:9000/ --resolve blog.marskid.net:9000:127.0.0.1

返回应该是HTTP/1.1 200 OK

原文链接:https://marskid.net/2018/01/31/tls-client-authentication/