随着谷歌浏览器对非https网站醒目警示不安全后,https就成为网站的一个标配,但是现在一个ssl证书动辄几千元一年,对于创业公司也是一笔不小的费用。如果你喜欢自己动手,那么可以了解一下Let’s Encrypt项目,定期自己生成免费的SSL证书。 因为Let’s Encrypt证书有效期只有3个月,所以建议自动化,比如本文使用certbot-auto脚本。
证书分两种:一种是单域名证书,一种是通配符证书,其中单域名证书比较简单,也能自动化续期,本文主要针对通配符证书的生成。

下载脚本

1
2
wget https://dl.eff.org/certbot-auto
chmod a+x ./certbot-auto

自动部署

1
certbot-auto -v # 会自动安装部署

生成单域名证书

1
certbot-auto certonly --webroot -w /var/www/liming.pub -d  liming.pub #手工生成并部署单域名证书

生成通配符证书

  1. 执行命令:

    1
    
    certbot-auto certonly  -d *.liming.pub --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory 
  2. 配置域名验证: 根据要求配置一个txt类型的DNS解析,注意不要删除,否则后面验证的时候报错。 测试解析是否生效

    1
    
    dig -t txt _acme-challenge.liming.pub

    确认生效后回车即可完成申请。

  3. 配置nginx 如果以上命令没有自动配置nginx,则手工配置一下,配置参考:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    ssl_certificate /etc/letsencrypt/live/liming.pub/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/liming.pub/privkey.pem; # managed by Certbot
    ssl_session_cache shared:le_nginx_SSL:1m;
    ssl_session_timeout 1440m;
    
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    
    ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";

    配完后重新加载一下nginx即可生效:/usr/sbin/nginx -s reload

查看生成的证书

1
openssl x509 -in  /etc/letsencrypt/live/liming.pub/fullchain.pem -noout -text

相关参数说明:

1
2
3
4
certonly 表示插件,Certbot 有很多插件。不同的插件都可以申请证书,用户可以根据需要自行选择。
-d 为哪些主机申请证书。如果是通配符,输入 *.xxx.com (根据实际情况替换为你自己的域名)。
--preferred-challenges dns-01,使用 DNS 方式校验域名所有权。
--server,Let's Encrypt ACME v2 版本使用的服务器不同于 v1 版本,需要显示指定。

手动更新

1
./certbot-auto renew -v

注意:由于以下原因,上面命令可能无法执行:

  • 域名认证有效期是30天,但是更新操作只有到期时间小于30天才能执行,所以需要重新再配置域名的txt记录(否则更新会报错:PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.'

  • 如果当前机器配置了多个通配符nginx配置,会每个每个去更新,所以建议先将nginx的配置移动一下目录后,只保留要更新的nginx配置,然后再更新:

    1
    2
    3
    4
    
    mv /etc/nginx/conf.d /etc/nginx/conf.d.bak
    certbot-auto certonly --no-self-upgrade -d *.liming.pub --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
    mv /etc/nginx/conf.d.bak /etc/nginx/conf.d
    /usr/sbin/nginx -s reload

自动更新

由于证书的有效期只有3个月,所以可以可以采用定时任务的方式自动续期。

  1. 设置定时规则
    vi /etc/crontab

    1
    2
    
    certbot-auto renew --quiet --no-self-upgrade
    0 3 1 * * certbot-auto renew --quiet –renew-hook "/usr/sbin/nginx -s reload"
  2. 重启定时任务

    1
    
    service crond restart

注意: 通配符域名证书只能手动更新,暂无法使用自动更新,原因见上。

java访问不信任

Let’s Encrypt证书浏览器基本都认,但是java程序去访问的时候回不认,此时可以考虑将证书导入到jre环境中即可。具体方法如下:

  1. 下载证书
    在web浏览器上(这里我用的是chrome)打开https的链接,然后点击https前面的小锁头,然后点详细信息.就可以看到右侧有一些信息.然后点击view certificate.直接拖拽证书的图标到一个路径,就保存下来了

  2. 导入证书
    进入JDK的security路径:cd $JAVA_HOME/jre/lib/securiy 执行命令导入证书,遇到输入口令的情况, java的默认口令是changeit:

    1
    
    sudo keytool -keystore cacerts -importcert -alias limingpub -file xxx.cer