0%

nginx学习笔记:ssl配置

写在前面

http,即超文本传输协议,是互联网上应用最为广泛的一种网络协议,采用明文传输,监听80端口。在安全隐私问题越来越被关注的今天,http存在三大问题:

  1. 通信使用明文(不加密), 内容可能会被窃听;

  2. 不验证通信方的身份, 因此有可能遭遇伪装;

  3. 无法证明报文的完整性, 所有有可能已遭篡改;

https,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,监听443端口。https协议通过在在客户端和服务器之间的加密传输,保证双方传递信息的安全性,不可被第三方窃听;用户可以通过服务器证书验证他所访问的网站是否真实可靠。

这则笔记主要整理ssl相关的基础知识,以及如何配置nginx支持ssl。

理论篇:ssl认证原理

对称加密和非对称加密

理解这一点,是掌握ssl的基础。

传统的对称加密,做个类比,就像柯南动画片里的犯罪手法,了解了犯罪手法,也就解开了整个谜团。在对称加密中,加密和解密用的都是同一组密钥,掌握了密钥就可以解开密文。对称加密最大的缺点,就是一旦密钥泄漏,那么加密就失去了意义。

而非对称加密,在安全性上又上了一个等级,用户A生成共钥和私钥两把钥匙,其中私钥只有A才有,共钥则可以交给其他人。在使用的时候,共钥加密的文件,必须由私钥解密,反之亦然。这就极大地提高了加密传输的安全性。

在https协议中,是采用混合加密机制,也就是在交换密钥环节适用非对称加密, 之后的建立通信交换报文阶段则使用对称加密。

CA证书

在采用加密传输之后,信息安全性已经得到了很大提升。但是还有一个问题,就是如果一开始在握手环节,server端服务器就是冒名顶替的,那后面的非对称加密也会失去意义。所以,就有了CA认证的环节。

证书,也叫“digital certificate”或“public key certificate”。

证书分为三种类型,域名型SSL证书(DV SSL)、企业型SSL证书(OVSSL)、增强型SSL证书(EVSSL)。个人拥护一版采用第一种就可以。

证书内容主要包括:电子签证机关的信息、公钥用户信息、公钥、权威机构的签字和有效期等等。目前,证书的格式和验证方法普遍遵循X.509国际标准。

根据证书颁发机构的不同,CA证书也是分层级的。如下图中,只要处于最顶端的跟证书C没问题,那么它之下的所有证书都没问题。

CA 是“Certificate Authority”的缩写,也叫“证书授权中心”,是负责管理和签发证书的第三方机构。CA 是“Certificate Authority”的缩写,也叫“证书授权中心”,是负责管理和签发证书的第三方机构。

常见的免费证书发放机构:

Let’s Encrypt是国外一个公共的免费SSL项目,由 Linux 基金会托管,由Mozilla、思科、Akamai、IdenTrust和EFF等组织发起。安装部署简单、方便,目前Cpanel、Oneinstack等面板都已经集成了Let’s Encrypt一键申请安装。

CloudFlare提供的免费SSL证书是UniversalSSL,即通用SSL,用户无需向证书发放机构申请和配置证书就可以使用的SSL证书,CloudFlare向所有用户(包括免费用户)提供SSL加密功能。

同时,国内的阿里云、腾讯云等也都有免费的ssl证书,但不推荐。

ssl验证过程

ssl验证,可以分为单向和双向两种,其中单向验证最常用。

单向验证

单向认证,仅仅是客户端需要检验服务端证书是否是正确的,而服务端不会检验客户端证书是否是正确的。

  1. 客户端say hello 服务端

  2. 服务端将证书、公钥等发给客户端

  3. 客户端CA验证证书,成功继续、不成功弹出选择页面

  4. 客户端告知服务端所支持的加密算法

  5. 服务端选择最高级别加密算法明文通知客户端

  6. 客户端生成随机对称密钥key,使用服务端公钥加密发送给服务端

  7. 服务端使用私钥解密,获取对称密钥key

  8. 后续客户端与服务端使用该密钥key进行加密通信

双向验证

双向认证,指客户端验证服务器端证书,而服务器也需要通过CA的公钥证书来验证客户端证书。

  1. 客户端say hello 服务端

  2. 服务端将证书、公钥等发给客户端

  3. 客户端CA验证证书,成功继续、不成功弹出选择页面

  4. 客户端将自己的证书和公钥发送给服务端

  5. 服务端验证客户端证书,如不通过直接断开连接

  6. 客户端告知服务端所支持的加密算法

  7. 服务端选择最高级别加密算法使用客户端公钥加密后发送给客户端

  8. 客户端收到后使用私钥解密并生成随机对称密钥key,使用服务端公钥加密发送给服务端

  9. 服务端使用私钥解密,获取对称密钥key

  10. 后续客户端与服务端使用该密钥key进行加密通信

实操篇:如何配置nginx支持https

前提条件:安装openssl、openssl-devel

nginx依赖openssl和openssl-devel来支持ssl模块,需要单独进行安装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
yum install -y openssl openssl-devel

cd usr/local/src/nginx-1.14.0

./configure \
--prefix=/usr/local/nginx \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_ssl_module

//编译完成之后重启nginx
systemctl restart nginx

申请CA证书

  1. 先生成一个私钥;

  2. 用私钥生成证书请求(证书请求里应含有公钥信息);

  3. 利用证书服务器的CA根证书来签发证书;

其中需要自己做的,其实主要是两个部分:

本地生成证书请求文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//创建cd目录,用来存放各种临时文件和最后的证书文件
mkdir -p /etc/ssl/

//创建账号
openssl genrsa 4096 > account.key

//创建 RSA 私钥
openssl genrsa 4096 > domain.key

//生成 CSR 文件
//目前一张证书最多可以包含 100 个域名,至少把域名带 www 和不带 www 的两种情况都加进去,其它子域可以根据需要添加
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr

//也可以使用交互方式创建 CSR
openssl req -new -sha256 -key domain.key -out domain.csr

nginx配置

单向验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//copy证书文件
cp /etc/pki/ca_test/server/server.* /usr/local/nginx/conf/

//修改nginx配置
{
listen 443 ssl;
server_name www.aminglinux.com;
index index.html index.php;
root /data/wwwroot/aminglinux.com;
ssl on;
ssl_certificate server.crt;
ssl_certificate_key server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:!eNULL;
ssl_prefer_server_ciphers on;
...
}

配置说明

1
2
3
4
5
6
7
1. 443端口为ssl监听端口。
2. ssl on表示打开ssl支持。
3. ssl_certificate指定crt文件所在路径,如果写相对路径,必须把该文件和nginx.conf文件放到一个目录下。
4. ssl_certificate_key指定key文件所在路径。
5. ssl_protocols指定SSL协议。
6. ssl_ciphers配置ssl加密算法,多个算法用:分隔,ALL表示全部算法,!表示不启用该算法,+表示将该算法排到最后面去。
7. ssl_prefer_server_ciphers 如果不指定默认为off,当为on时,在使用SSLv3和TLS协议时,服务器加密算法将优于客户端加密算法。

双向认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//copy证书文件
cp /etc/pki/ca_test/root/ca.crt /usr/local/nginx/conf/

//修改nginx配置
{
listen 443 ssl;
server_name www.aminglinux.com;
index index.html index.php;
root /data/wwwroot/aminglinux.com;
ssl on;
ssl_certificate server.crt;
ssl_certificate_key server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:!eNULL;
ssl_prefer_server_ciphers on;
ssl_client_certificate ca.crt; //这里的ca.crt是根证书公钥文件
ssl_verify_client on;
...
}
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!