Nginx配置SSL

在 https 的大趋势下,如果你的站点不适用 https 显得不是很 low 吗?接下来我将带领大家如果在 centos7 nginx 上配置 https

安装 nginx

  关于nginx 安装建议看我以前的教程centos7 nginx 的 brotli 压缩 ,已经算是写的比较详细了,我这里就不多说废话了。

申请 ssl 证书

  目前证书申请有以下两种方式,因为第二中方式各个平台都写的非常清楚了,我就不多做解释。

自己申请 ssl 泛域名证书

这里我们采用的是申请 Let’s Encrypt 的泛域名证书,对这个组织感兴趣的朋友可以百度一下。

我们今天采用的是 acme.sh ,这个是一个 shell 脚本,大大简化了申请证书的难度。

  • 安装 acme.sh
1
2
3
4
[[安装]]
curl https://get.acme.sh | sh -s email=my@example.com
# 或wget
wget -O -  https://get.acme.sh | sh -s email=my@example.com

  普通用户和 root 用户都可以安装使用。 acme.sh 安装到你的 home 目录下:~/.acme.sh/,并创建 一个 bash 的 alias, 方便你的使用:

1
2
3
alias acme.sh=~/.acme.sh/acme.sh
[[让alias生效]]
source ~/.bashrc
  • 设置 DNS 解析

    Let’s Encrypt 支持DNSPod、CloudXNS、Amazon Route53、CloudFlare等 DNS 解析,你需要先把域名的 NS 修改好。

    因为博主使用的是 CloudXNS,所以我将用 CloudXNS 为例解析,其他 DNS 解析 解析也大同小异。

    在控制台输入以下指令: vim ~/.acme.sh/account.conf,把下面的配置写到文件中

    1
    
    export CX_Key="1234"export CX_Secret="sADDsdasdgdsf"
    

  

https://image.coderlab.cn/preview/1438621191936950273

  

https://image.coderlab.cn/preview/1438621355674189826

API KEY == CX_Key CX_Secret == SECRET KEY

  • 签发泛域名证书

    在控制台输入下面指令:

    1
    
    acme.sh --issue --dns dns_cx -d example.com -d www.example.com
    

    https://image.coderlab.cn/preview/1438621365258174466

    稍等片刻,证书就颁发生成功了。

  • 复制证书

    前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件。正确的使用方法是使用 –installcert 命令,并指定目标位置, 然后证书文件会被 copy 到相应的位置, 例如:

    1
    2
    3
    4
    
    acme.sh --installcert  -d gclmit.club -d *.gclmit.club   \
            --key-file  /etc/nginx/ssl/gclmit.key \
            --fullchain-file /etc/nginx/ssl/fullchain.cer \
            --reloadcmd  "service nginx force-reload"
    

    其中 gclmit.club 为我的域名,你们将他替换成你们的域名就可以了。

2. 采用平台申请的单域名证书

  请自行前往各大平台查看文档,目前 阿里、腾讯、宝塔等都可以申请到单域名证书。

配置证书

  • 生成 dhparam.pem 文件,生成该文件有两种方式,任选其一

    1
    2
    3
    4
    5
    
    # 方法1: 很慢
    openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
    # 方法2: 较快
    # 与方法1无明显区别. 2048位也足够用, 4096更强
    openssl dhparam -dsaparam -out /etc/nginx/ssl/dhparam.pem 4096
    
  • 新建 ssl-params.conf 并把它放到 Nginx 的 snippets 目录中。

     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
    29
    30
    31
    32
    
    ##
    # ssl params setting
    ##
    
    ssl on;
    
    server_tokens   off;
    
    ssl_session_cache        shared:SSL:10m;
    ssl_session_timeout      60m;
    ssl_session_tickets      on;
    
    ssl_stapling             on;
    ssl_stapling_verify      on;
    
    resolver                 8.8.4.4 8.8.8.8  valid=300s;
    resolver_timeout         10s;
    
    ssl_prefer_server_ciphers on;
    ssl_certificate          /etc/nginx/ssl/fullchain.cer;
    ssl_certificate_key      /etc/nginx/ssl/gclmit.key;
    ssl_dhparam              /etc/nginx/ssl/dhparam.pem;
    
    ssl_protocols            TLSv1 TLSv1.1 TLSv1.2;
    
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    
    add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload";
    add_header X-Frame-Options  deny;
    add_header X-Content-Type-Options  nosniff;
    add_header x-xss-protection "1; mode=block";
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https:; connect-src 'self' https:; img-src 'self' data: https: blob:; style-src 'unsafe-inline' https:; font-src https:";
    
  • 接下来在 Nginx 主配置文件中开启 SSL 支持

    1
    2
    
    [root@gclms nginx]# cd /etc/nginx
    [root@gclms nginx]# vim 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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
    user  nginx;
    worker_processes  1;
    
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
    
    	##
        # Basic Settings
        ##
    
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
    
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$host" "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" $request_time';
    	##
        # Log Settings
        ##
        access_log  /var/log/nginx/access.log  main;
    	error_log /var/log/nginx/error.log;
    
    	##
        # SSL Settings
        ##
    
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    
        [[gzip]]  on;
    
        include /etc/nginx/conf.d/*.conf;
    }
    
  • 案例; 配置一个子域名:test.gclmit.club

    1
    2
    
    [root@gclms nginx]# cd conf.d
    [root@gclms nginx]# vim test.conf
    

    在 test.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
    29
    30
    
    server {
        listen       80;
        server_name  test.gclmit.club;
        rewrite ^ https://$http_host$request_uri? permanent;    [[强制将http重定向到https]]
        server_tokens off;
    }
    
    server {
    
       listen 443;      # ssl http2 fastopen=3 reuseport;
       listen [::]:443; # ssl http2 fastopen=3 reuseport;
    
       server_name test.gclmit.club;
    
       # include /etc/nginx/snippets/brotli.conf;
       include /etc/nginx/snippets/ssl-params.conf;
    
       access_log /opt/websites/test.gclmit.club/logs/nginx-access.log;
       error_log  /opt/websites/test.gclmit.club/logs/nginx-error.log error;
    
       location / {
    
    	   root /opt/websites/test.gclmit.club/public;
    
    	   index  index.html index.htm;
    
           proxy_read_timeout  1200s;
           client_max_body_size 0;
       }
    }
    

    接下来在控制台执行 nginx -s reload 重启 nginx, 你就可以看见一把带绿锁的网站了

其他平台的 DNS 解析 设置

  CloudFlare DNS API

  First you need to login to your CloudFlare account to get your API key.

1
2
export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="xxxx@sss.com"

  Ok, let’s issue a cert now:

1
acme.sh --issue --dns dns_cf -d example.com -d www.example.com

  The CF_Key and CF_Email will be saved in ~/.acme.sh/account.conf and will be reused when needed.

  DNSPod DNS API

  First you need to login to your DNSPod account to get your API Key and ID.

1
2
export DP_Id="1234"
export DP_Key="sADDsdasdgdsf"

  Ok, let’s issue a cert now:

1
acme.sh --issue --dns dns_dp -d example.com -d www.example.com

  The DP_Id and DP_Key will be saved in ~/.acme.sh/account.conf and will be reused when needed.

  阿里云 Aliyun DNS API

  First you need to login to your 阿里云 Aliyun account to get your API key. https://ak-console.aliyun.com/#/accesskey

1
2
export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export Ali_Secret="jlsdflanljkljlfdsaklkjflsa"

  Ok, let’s issue a cert now:

1
acme.sh --issue --dns dns_ali -d example.com -d www.example.com

  The Ali_Key and Ali_Secret will be saved in ~/.acme.sh/account.conf and will be reused when needed.

  GoDaddy DNS API

  First you need to login to your GoDaddy account to get your API Key and Secret. https://developer.godaddy.com/keys/

  Please create a Production key, instead of a Test key.

1
2
export GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export GD_Secret="asdfsdafdsfdsfdsfdsfdsafd"

  Ok, let’s issue a cert now:

1
acme.sh --issue --dns dns_gd -d example.com -d www.example.com

  The GD_Key and GD_Secret will be saved in ~/.acme.sh/account.conf and will be reused when needed.

  PowerDNS DNS API

  First you need to login to your PowerDNS account to enable the API and set your API-Token in the configuration. https://doc.powerdns.com/md/httpapi/README/

1
2
3
4
export PDNS_Url="http://ns.example.com:8081"
export PDNS_ServerId="localhost"
export PDNS_Token="0123456789ABCDEF"
export PDNS_Ttl=60

  Ok, let’s issue a cert now:

1
acme.sh --issue --dns dns_pdns -d example.com -d www.example.com

  The PDNS_Url, PDNS_ServerId, PDNS_Token and PDNS_Ttl will be saved in ~/.acme.sh/account.conf and will be reused when needed.

  Amazon Route53 DNS API

  方法见:https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API

1
2
export  AWS_ACCESS_KEY_ID=XXXXXXXXXX
export  AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXX

  To issue a cert:

1
acme.sh --issue --dns dns_aws -d example.com -d www.example.com

  The AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY will be saved in ~/.acme.sh/account.confand will be reused when needed.

  Linode DNS API

  First you need to login to your Linode account to get your API Key. https://manager.linode.com/profile/api

  Then add an API key with label ACME and copy the new key.

1
export LINODE_API_KEY="..."

  Due to the reload time of any changes in the DNS records, we have to use the dnssleep option to wait at least 15 minutes for the changes to take effect.

  Ok, let’s issue a cert now:

1
acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.com

  The LINODE_API_KEY will be saved in ~/.acme.sh/account.conf and will be reused when needed.

  DigitalOcean DNS API (native)

  You need to obtain a read and write capable API key from your DigitalOcean account. See: https://www.digitalocean.com/help/api/

1
export DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc"

  Ok, let’s issue a cert now:

1
acme.sh --issue --dns dns_dgon -d example.com -d www.example.com

  Namesilo DNS API

  You’ll need to generate an API key at https://www.namesilo.com/account_api.php Optionally you may restrict the access to an IP range there.

1
export Namesilo_Key="xxxxxxxxxxxxxxxxxxxxxxxx"

  And now you can issue certs with:

1
acme.sh --issue --dns dns_namesilo --dnssleep 900 -d example.com -d www.example.com

acme.sh 常用指令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 获取当前证书列表
[acme.sh](http://acme.sh) --list
# 运行crontab任务更新所有证书
acme.sh --cron 
# 发送消息到钉钉
acme.sh --set-notify  --notify-hook dingtalk 
# 更新证书
acme.sh --renew
# 强制更新证书
acme.sh --renew --face
# 更新所有证书
acme.sh --renew-all

感谢