Nginx 配置 HTTPS 证书

Posted by 彭楷淳 on 2020-10-02
Estimated Reading Time 6 Minutes
Words 1.6k In Total
Viewed Times

随着我们网站用户的增多,我们会逐渐意识到 HTTPS 加密的重要性。在不修改现有代码的情况下,要从 HTTP 升级到 HTTPS,让 Nginx 支持 HTTPS 是个很好的选择。今天我们来讲下如何从 Nginx 入手,从 HTTP 升级到 HTTPS,同时支持静态网站和 Spring Boot 应用,希望对大家有所帮助!

生成 SSL 自签名证书


虽然自签名证书浏览器认为并不是安全的,但是学习下 SSL 证书的生成还是很有必要的!

首先创建 SSL 证书私钥,期间需要输入两次用户名和密码,生成文件为 blog.key

1
$ openssl genrsa -des3 -out blog.key 2048

利用私钥生成一个不需要输入密码的密钥文件,生成文件为 blog_nopass.key

1
$ openssl rsa -in blog.key -out blog_nopass.key

创建 SSL 证书签名请求文件,生成 SSL 证书时需要使用到,生成文件为 blog.csr

1
$ openssl req -new -key blog.key -out blog.csr

在生成过程中,我们需要输入一些信息,需要注意的是 Common Name 需要和网站域名一致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Enter pass phrase for blog.key:
-----
$ Country Name (2 letter code) [XX]:CN # 国家代码
$ State or Province Name (full name) []:jiangsu # 省份
$ Locality Name (eg, city) [Default City]:jiangsu # 城市
$ Organization Name (eg, company) [Default Company Ltd]:antoniopeng # 机构名称
$ Organizational Unit Name (eg, section) []:dev # 单位名称
$ Common Name (eg, your name or your server's hostname) []:blog.antoniopeng.com # 网站域名
$ Email Address []:antoniopeng@foxmail.com # 邮箱

Please enter the following 'extra' attributes
to be sent with your certificate request
$ A challenge password []: # 私钥保护密码,可以不输入直接回车
$ An optional company name []: # 可选公司名称,可以不输入直接回车

生成 SSL 证书,有效期为 365 天,生成文件为 blog.crt

1
$ openssl x509 -req -days 365 -in blog.csr -signkey blog.key -out blog.crt

其实最终有用的文件是两个,一个是证书文件 blog.crt,另一个是不需要输入密码的证书私钥文件 blog_nopass.key

Nginx 支持 HTTPS


SSL 证书生成好了,接下来我们就可以配置 Nginx 来支持 HTTPS 了!

将我们生成好的 SSL 证书和私钥拷贝到 Nginx 的 html/ssl 目录下:

1
2
$ cp blog_nopass.key /mydata/nginx/html/ssl/
$ cp blog.crt /mydata/nginx/html/ssl/

接下来我们需要给 antoniopeng.com 这个域名添加 HTTPS 支持,修改 nginx.conf 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
listen 80; # 同时支持HTTP
listen 443 ssl; # 添加HTTPS支持
server_name antoniopeng.com;

#SSL配置
ssl_certificate /usr/share/nginx/html/ssl/blog/blog.crt; # 配置证书
ssl_certificate_key /usr/share/nginx/html/ssl/blog/blog_nopass.key; # 配置证书私钥
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 配置SSL协议版本
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; # 配置SSL加密算法
ssl_prefer_server_ciphers on; # 优先采取服务器算法
ssl_session_cache shared:SSL:10m; # 配置共享会话缓存大小
ssl_session_timeout 10m; # 配置会话超时时间

location / {
root /usr/share/nginx/html/docs;
index index.html index.htm;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

通过 HTTPS 访问 antoniopeng.com 这个域名,由于我们使用的是自己签名的SSL证书,浏览器会提示 您的连接不是私密连接,点击继续前往可以通过HTTPS正常访问。我们可以查看下证书的 颁发者 信息,可以发现正好是之前我们创建 SSL 证书签名请求文件时录入的信息。

接下来动态代理添加 HTTPS 支持,修改 nginx.conf 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server {
listen 80; # 同时支持HTTP
listen 443 ssl; # 添加HTTPS支持
server_name antoniopeng.com; #修改域名

#ssl配置
ssl_certificate /usr/share/nginx/html/ssl/blog/blog.crt; # 配置证书
ssl_certificate_key /usr/share/nginx/html/ssl/blog/blog.crt; # 配置证书私钥
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 配置SSL协议版本 # 配置SSL加密算法
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on; # 优先采取服务器算法
ssl_session_cache shared:SSL:10m; # 配置共享会话缓存大小
ssl_session_timeout 10m; # 配置会话超时时间

location / {
proxy_pass http://192.168.3.101:4000; # 设置代理服务访问地址
proxy_set_header Host $http_host; # 设置客户端真实的域名(包括端口号)
proxy_set_header X-Real-IP $remote_addr; # 设置客户端真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 设置在多层代理时会包含真实客户端及中间每个代理服务器的IP
proxy_set_header X-Forwarded-Proto $scheme; # 设置客户端真实的协议(http还是https)
index index.html index.htm;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

使用受信任的证书


之前我们使用的是自签名的 SSL 证书,对于浏览器来说是无效的。使用权威机构颁发的 SSL 证书浏览器才会认为是有效的,这里给大家推荐两种申请免费 SSL 证书的方法,一种是从阿里云申请,另一种是从 FreeSSL 申请。

阿里云证书

阿里云上可以申请的免费证书目前只有支持单个域名的 DV 级 SSL 证书。比如说你有 blog.antoniopeng.comapi.antoniopeng.com 两个二级域名需要使用 HTTPS,就需要申请两个 SSL 证书:

img

申请成功后点击下载 Nginx 证书即可。

img

下载完成后解压会有下面两个文件:

1
2
blog.antoniopeng.com.key # 证书私钥文件
blog.antoniopeng.com.pem # 证书文件

拷贝证书文件到 Nginx 的指定目录下,然后修改 nginx.conf 配置路径即可,修改完成后重启Nginx:

1
2
3
#SSL配置
ssl_certificate /usr/share/nginx/html/ssl/blog/blog.antoniopeng.com.pem; # 配置证书
ssl_certificate_key /usr/share/nginx/html/ssl/blog/blog.antoniopeng.com.key; # 配置证书私钥

再次通过 HTTPS 访问 blog.antoniopeng.com 这个域名,发现证书已经有效了,连接也是安全的了。

FreeSSL 证书

如果你有使用通配符域名的需求,可以上 FreeSSL 申请SSL证书,不过免费的有效期只有 3 个月,这就意味着你过 3 个月就要重新申请一次了。

img

附上官网地址:https://freessl.cn/

使用 acme.sh 自动申请证书

acme.sh 脚本实现了 acme 协议, 可以从 letsencrypt 生成免费的证书。一般我们申请的证书有效期都是 1 年,过期就要重新申请了,使用 acme.sh 脚本可以实现到期自动申请,再也不用担心证书过期了!

img

更多干货请移步:https://antoniopeng.com


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !