Linux CentOS 7 下 Nginx 安装使用 Let’ s Encrypt 证书的完整过程

samport · December 20, 2016 · Last by charlie_hsieh replied at July 02, 2017 · 22816 hits
Topic has been selected as the excellent topic by the admin.

最近在项目上线过程中顺便整理了几篇原创文章,还没发到自己的博客上,先在这里分享了。

CentOS7 下 nginx 安装使用 Let’s Encrypt 证书的完整过程

网站转成 https 是大势所趋。但是在国内,推进的过程显然要比国外慢很多。

现阶段如果将自己的网站改成 https 以后,会碰到这样的尴尬现象:如果在页面上引用了http://的链接或者图片,用户在浏览器上会看到类似该网站是非安全网站的警告,对于网站运营者来说可以说非常冤。由于很多链接是第三方的,没有办法去控制。

对于 api 接口类的网站,就不存在混合的问题,所以首先应该从 api 后台接口部分开始用 https。(ios 已经强制要求接口地址必须为 https 了)

大牌提供商的 SSL 证书可不便宜,对于大公司也许不算什么,但是对于小公司及个人来说贵了。现在国外出现的免费 SSL 服务商Let’s Encrypt,绝对是小公司或者开发者的福音。(现阶段在天朝也能够正常使用,但是未来不清楚。如果天朝有一天自绝于世界网络的话,没准这个证书也会被封堵。)

这里整理了在 CentOS7 + nginx 安装和使用Let’s Encrypt的完整过程。

官方网站:https://letsencrypt.org

申请 let's encript 证书可以有三种方式:

  1. 通过 certbot 脚本
  2. 通过支持 Letencript 的虚拟主机提供商
  3. 手工申请 manual mode

没有特殊情况,首选采用 certbot 脚本方式。

由于 letsencrypt 证书的有效期只有 90 天,需要长期使用的话,需要在失效前进行延长申请。用 certbot 脚本工具,可以将延期申请的脚本写到定时任务来自动完成,非常方便。

一、前提条件

  1. 拥有一个域名,例如 mydomain.com (在国内主机的用的话,还需要通过 ICP 备案)
  2. 在域名服务器创建一条 A 记录,指向云主机的公网 IP 地址。例如 demo.mydomain.com 指向 xxx.xxx.xxx.xxx 的 IP 地址
  3. 要等到新创建的域名解析能在公网上被解析到。
  4. 据说国内的域名提供商对 letsencrypt 的支持非常差,但是经过试验,至少现阶段用 dnspod 解析的域名还没碰到问题。

二、在云主机上安装 nginx 服务器,配置好最基本的 80 口 ngnix 站点

例如,假设为 demo.mydomain.com 快速配置一个最简单的 nginx 站点

  1. 安装 nginx 服务器

    yum install -y nginx
    
  2. 配置一个 nginx 站点

    mkdir /opt/www/demo.mydomain.com -p
    chown nginx:nginx /opt/www/demo.mydomain.com/ -R
    vi /etc/nginx/conf.d/demo.mydomain.com.conf
    

    将以下内容复制到该文件中

    server {
    listen 80;
    server_name demo.mydomain.com;
    charset utf-8;
    
    root /opt/www/demo.mydomain.com;
    index index.html index.htm;
    
    access_log  /var/log/nginx/demo.mydomain.com_access.log;
    error_log  /var/log/nginx/demo.mydomain.com_error.log;
    }
    
  3. 启动 nginx 服务

    systemctl start nginx
    

    注意:要确认 CentOS 服务器开放 80 口及 443 端口

  4. 在浏览器上确认访问到http://demo.mydomain.com 如果没有页面的话,正常情况下应该会显示 403 错误。nginx 站点配置完成。

三、安装 certbot 工具

yum install -y epel-release
yum install -y certbot

四、使用 certbot 命令初次申请证书

# 使用方法:certbot certonly --webroot -w [Web站点目录] -d [站点域名] -m [联系人email地址] --agree-tos
# 例如:
certbot certonly --webroot -w /opt/www/demo.mydomain.com -d demo.mydomain.com -m [email protected] --agree-tos

注意:联系人 email 地址要填写真实有效的,letsencrypt 会在证书在过期以前发送预告的通知邮件。 申请成功后,会显示以下 Congratulations 信息

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/[xxx.xxx.xxx]/fullchain.pem. Your cert will
   expire on 2017-03-20. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

证书的保存位置在:

/etc/letsencrypt/live/demo.mydomain.com/

五、查看证书有效期的命令

openssl x509 -noout -dates -in /etc/letsencrypt/live/[demo.mydomain.com]/cert.pem

显示的是格林威治时间,不知道怎么才能显示当前时区。

六、设置定时任务自动更新证书

letsencrypt 证书的有效期是 90 天,但是可以用脚本去更新。

# 更新证书
certbot renew --dry-run 
# 如果不需要返回的信息,可以用静默方式:
certbot renew --quiet

注意:更新证书时候网站必须是能访问到的

# 可以使用crontab定时更新,例如:
# 每月1号5时执行执行一次更新,并重启nginx服务器
00 05 01 * * /usr/bin/certbot renew --quiet && /bin/systemctl restart nginx

七、应用实例:配置 nginx 使用证书开通 https 站点

  1. 生成 Perfect Forward Security(PFS)键值

    mkdir /etc/ssl/private/ -p
    cd /etc/ssl/private/
    openssl dhparam 2048 -out dhparam.pem
    
    • Perfect Forward Security(PFS) 是个什么东西,中文翻译成完美前向保密,一两句话也说不清楚,反正是这几年才提倡的加强安全性的技术。如果本地还没有生成这个键值,需要先执行生成的命令。
    • 生成的过程还挺花时间的,喝杯咖啡歇会儿吧。
  2. 配置 nginx 站点,例如/etc/nginx/conf.d/demo.mydomain.com.conf,样例内容如下:

    server {
    listen 80;
    server_name demo.mydomain.com;
    rewrite ^ https://$server_name$request_uri? permanent;
    }
    server {
      listen 443 ssl;
      server_name demo.mydomain.com;
    
      charset utf-8;
      root /opt/www/demo.mydomain.com;
      index index.html index.htm;
    
      access_log  /var/log/nginx/demo.mydomain.com_access.log;
      error_log  /var/log/nginx/demo.mydomain.com_error.log;
    
      # letsencrypt生成的文件
      ssl_certificate /etc/letsencrypt/live/demo.mydomain.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/demo.mydomain.com/privkey.pem;
    
      ssl_session_timeout 1d;
      ssl_session_cache shared:SSL:50m;
      ssl_session_tickets on;
    
      ssl_dhparam /etc/ssl/private/dhparam.pem;
    
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      # 一般推荐使用的ssl_ciphers值: https://wiki.mozilla.org/Security/Server_Side_TLS
      ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK';
      ssl_prefer_server_ciphers on;
    }
    
  3. 在浏览器打开http://demo.mydomain.com, 如果正常跳转到https://demo.mydomain.com,就算成功了。 如果是 chrome 浏览器,在地址栏点击小锁的图标,可以查看证书的详情

huacnlee mark as excellent topic. 20 Dec 15:08

其实 这个脚本很好用的 比官方的程序好用 支持添加 crontab 自动续签证书 acme.sh

Building dependency tree       
Reading state information... Done
dialog is already the newest version.
gcc is already the newest version.
python is already the newest version.
python-dev is already the newest version.
augeas-lenses is already the newest version.
ca-certificates is already the newest version.
libaugeas0 is already the newest version.
libffi-dev is already the newest version.
libssl-dev is already the newest version.
python-virtualenv is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 217 not upgraded.
Creating virtual environment...
Installing Python packages...

Installing Python packages... 一直不过去,貌似也是和 RubyGems 一样,pip 访问困难

我这边安装 cerbot 没发现问题。回头我试试这个 sh 脚本。

huacnlee in [Topic was deleted] mention this topic. 23 Dec 15:33

请问这种免费证书跟那些昂贵的证书有什么差别?

如果是安全等级有差,那么又差多少呢?怎么量化这个指标?

谢谢!

好像在這邊對於 CentOS 使用的接受度相當高,感覺現在到處找到的文章都是 Ubuntu。

很開心還能看到使用 CentOS 的使用者。

我是自己寫的 bash 去 deploy SSL 不過我把它搞得有點複雜了。給各位批評指教。

https://github.com/charlietag/os_preparation

https://github.com/charlietag/os_security

You need to Sign in before reply, if you don't have an account, please Sign up first.