前言

最近一段时间在搞自己的博客网站,本地环境一直使用的HTTP协议,但在上线发布到个人服务器后还使用HTTP访问就有点说不过去了。

另外博客网站的基础架构为 Hexo框架 + Butterfly主题 + 博客后端管理 (自己开发便于管理博客);此处涉及到自己个人后台服务以及服务端数据库的基本操作,还包括阿里云OSS存储对象。考虑至此,还是打算安装SSL证书,采用HTTPS方式堆外提供访问(其实最多的想法还是担心对于不搞程序的盆友们一看到不安全的链接就直接劝退了,这是万万伤不起的)。毕竟自己也是土生土长的程序猿,怎么能容忍此种情况发生。

虽然自己之前没搞过Nginx方面的东西,但这些都不是问题,只有一句话:“没有不会搞,只有不想搞”。

使用的环境如下:

服务器: 腾讯云轻量应用服务器(1G,2core)
centos: 7.6
nginx: 1.8.0

申请证书

此处采用的是腾讯云域名解析,首选先申请个人域名,并添加至域名解析中。

openssl nginx证书 ssl证书 nginx配置_openssl nginx证书

点击域名进入域名记录列表配置页,添加域名解析记录:

openssl nginx证书 ssl证书 nginx配置_ssl_02

添加完成后可在页面最上端前往 DNSPod控制台 进行SSL证书申请,找到刚刚添加的记录值,如图操作:

openssl nginx证书 ssl证书 nginx配置_nginx_03


openssl nginx证书 ssl证书 nginx配置_Nginx_04

申请完成后静等后台审核即可,审核通过后会有相应邮件提示。下面是我个人已申请SSL证书的域名:

openssl nginx证书 ssl证书 nginx配置_openssl nginx证书_05

下载对应域名的SSL证书,解压后Nginx中对应的文件即为我们需要的证书文件:

openssl nginx证书 ssl证书 nginx配置_ssl_06

Nginx配置SSL证书

此处默认服务器上已安装部署Nginx,将上述两个文件上传至服务器,目录地址任意;为了方便管理,本人将证书文件统一放在Nginx conf 目录下的 cert 文件夹中。

在 nginx.conf 中配置HTTPS server模块:

  • Nginx静态文件访问配置
server {
    listen       443;
    server_name  www.lynsite.cn;
    ssl on; # 打开SSL

    ssl_certificate     cert/1_www.lynsite.cn_bundle.crt; # 证书路径
    ssl_certificate_key cert/2_www.lynsite.cn.key; # 秘钥路径

    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #表示使用的加密套件的类型。
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
    ssl_prefer_server_ciphers on;
    #charset koi8-r;
    access_log logs/ssl-blog-web.access.log;
    error_log logs/ssl-blog-web-error.log;

    # 博客前端首页
    location / {
        root   /var/www/html/自己要访问的静态资源目录;
        index  index.html index.htm;
    }
}
  • API 接口服务配置

配置中的 proxy_pass http://blog-test; 为代理转发服务,需要另外配置 upstream 模块;

upstream blog-test{
    server localhost:1234 max_fails=3 fail_timeout=30s; #允许失败的最大次数和超时时间
}

server {
    listen       443;
    server_name  test.lynsite.cn;
    ssl on; # 打开SSL

    ssl_certificate     cert/1_test.lynsite.cn_bundle.crt; # 证书路径
    ssl_certificate_key cert/2_test.lynsite.cn.key; # 秘钥路径

    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;#表示使用的加密套件的类型。
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
    ssl_prefer_server_ciphers on;
    #charset koi8-r;

    access_log logs/ssl-blog-test-access.log;
    error_log logs/ssl-blog-test-error.log;

    # 博客后台管理服务
    location / {
        add_header backendIP $upstream_addr;
        add_header backendCode $upstream_status;
        proxy_pass http://blog-test;
        #proxy_redirect iff;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 600;
        proxy_buffer_size 256k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
        proxy_temp_file_write_size 256k;
        proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
        proxy_max_temp_file_size 128m;
        #proxy_cache mycache;
        #proxy_cache_valid 200 302 60m;
        #proxy_cache_valid 404 1m;
    }
}

小课堂

以上配置表示访问域名 server_name 为test.lynsite.cn 的请求都将代理转发至 localhost:1234,此处的localhost指的是服务器。
 举例:https://test.lynsite.cn/path 经过Nginx实际被代理为 localhost:1234/path;
 如果想实现代理后的实际地址为 localhost:1234 的根地址,则修改配置文件中的 proxy_pass http://blog-test; 为 proxy_pass http://blog-test/;另外,本人将 nginx.conf http 中的 server 模块 配置进行了提取,统一配置在 conf/conf.d/*.conf

openssl nginx证书 ssl证书 nginx配置_Nginx_07

  • 如上配置完成之后重新加载Nginx配置就可以使用 https://test.lynsite.cn 来访问我们的本地1234端口了,但是我们平常访问哪里会加 https 的前缀,都是直接访问域名,所以这里我们还需要把常用的 80 端口的访问重定向到 443 端口,假设我们想只输入 test.lynsite.cn 就能访问 443端口,那么我们还需要在Nginx中http模块添加 server 模块,具体配置如下所示:
server {
  listen 80;
  server_name  test.lynsite.cn; # 此处需要设定证书绑定的域名。
  rewrite ^/(.*)$ https://www.lynsite.cn:443/$1 permanent; #将所有HTTP请求通过rewrite指令重定向到HTTPS。
}
  • 重新加载Nginx配置文件就可以访问了,直接通过域名访问地址栏的地址为自动转换为 https 安全链接。

Nginx启动报错处理

如果前面操作正常,此部分可直接跳过。

启动Nginx或者配置完SSL模块后重新刷新配置文件报错:nginx:[emerg]unknown directive ssl,原因:我们配置这个SSL证书需要引用到nginx的中SSL这模块,然而我们一开始编译的Nginx的时候并没有把SSL模块一起编译进去,所以导致这个错误的出现。

  1. 下载Nginx安装包,重新编译
./configure --with-http_ssl_module
注: 执行以上命令出现这个错误(./configure:错误:SSL模块需要OpenSSL库。),原因是因为缺少了OpenSSL,那我们再来安装一个即可执行:yum -y install openssl openssl-devel 等待OpenSSL的安装完成后,再执行 ./configure 即可
  1. 执行make命令,但是不要执行make install,因为make是用来编译的,而make install是安装,不然你整个nginx会重新覆盖的。
  2. 在我们执行完做命令后,我们可以查看到在nginx解压目录下,objs文件夹中多了一个nginx的文件,这个就是新版本的程序了。首先我们把之前的nginx先备份一下,然后把新的程序复制过去覆盖之前的即可。
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak //备份,备份可不用执行

cp objs/nginx /usr/local/nginx/sbin/nginx

# 如果报进程被占用,则先停止nginx再进行上述操作。
  1. 查看ssl模块是否安装成功
cd /usr/local/nginx/

./sbin/nginx -v