给网站增加 SSL 证书

进击的学霸...大约 6 分钟

现在的 Chrome 浏览器会将非 https 的网站标记为 不安全 ,https 的则是显示一把锁的样子,之前一直觉得升级很麻烦还要申请证书,这次因为放在七牛云上的图片需要以 https 访问,进行了所有站点的 https 的升级,本文记录升级遇到的一些问题和解决办法

七牛云的 ssl 证书

七牛云的域名开启 https ,我在自己的服务器上操作了半天,上传的本地证书各种不合格,后来发现直接用七牛云提供的免费证书就可以了,申请只花了 15 分钟。

而且最后发现之前的那个问题是我理解错了,并不需要用 https 链接的图片,但是既然开了就留着用吧

其他域名的 ssl 证书

熟悉我网站的伙伴都知道,我的站点系列有四五个左右,子域名使用的比较多,针对这样的情况我想用的方式是申请一涨通配符证书,这样我的子域名都可以使用这张证书,如果为每个子域名都申请一个的话太麻烦了,而且维护也不方便。

获取证书

通过调研发现 Let's Encrypt 可以提供免费的 ssl 证书,由于只是小网站,用付费的一年几千的证书大可不必,这种免费的就足以满足我的需求,但是它的缺点是只有 90 天的有效期,过了 90 天就得重新申请,以前我觉得麻烦的点也是在这里,然后最近在寻找这块的消息的时候发现了一个比较好用的脚本 acme.shopen in new window ,它的作用就是可以从 Let's Encrypt 生成免费证书,而且每隔一段时间(在当前证书失效前)会自动更新证书,这样就解决了 90 天有效期的麻烦。

安装 acme.sh

curl  https://get.acme.sh | sh -s email=my@example.com

执行成功后这个脚本就被安装到了 home 目录下,地址为 ~/.acme.sh/

生成证书

生成证书我这里是采用的 dnsapi 的方式, 文档链接open in new window ,这个方式是最简单方便的方式,其他的方式我试过之后发现如果要生成多域名的就总是有问题,最后采用这个方式是可以成功的。上面文档中列出了十几种 dns 服务商的处理方式,可以根据自己域名提供商的实际情况选用,我的域名是买自阿里云的

按照操作先去生成 Ali_Key 和 Ali_Secret ,这里有一点要注意的是,进去 账户设置open in new window 阿里云会推荐你使用子账户来进行后续的操作,这个安全性我觉得是必要的,生成了子账户之后,根据提示,将账户信息保存一下,然后要给这个子账户添加权限,要添加上对应的权限才能调用 dnsapi 的,不是生成就可以调用的

添加权限

权限添加的弹窗这里,在策略的搜索框输入 dns 可以帮助我们快速的过滤出我们想要找的策略,选择 管理云解析(DNS) 这项,我这里因为已经添加过了所以是不可选的,选择之后会出现在右边的框里,然后点击确定按钮,你的子账户的 key 和 secret 就可以操作 dnsapi 了。

设置权限

依次输入命令并执行后,执行完成后会有 success 的相应提示,然后把证书给你放在什么位置了等等,这里的可以输入多个 -d 和域名,最后只会生成一个证书,生成证书的时候可以按通配符生成,以第一个输入的域名为名字

export Ali_Key="AccessKey ID"
export Ali_Secret="AccessKey Secret"
cd ~/.acme.sh/
acme.sh --issue --dns dns_ali -d jjdxb.top -d *.jjdxb.top

安装证书

新建目录 /etc/nginx ,文件不用新建,执行命令的时候会自动创建,安装证书的时候使用生成证书时的名字

acme.sh --install-cert -d jjdxb.top --key-file    \
/etc/nginx/key.pem  --fullchain-file /etc/nginx/cert.pem \
--reloadcmd     "nginx -s reload"

查看证书

查看已生成的证书的信息,同理也是要输入证书名字

./acme.sh --info -d jjdxb.top -d blog.jjdxb.top -d blog.lovem.fun -d code.jjdxb.top

配置 nginx

首先确定下自己当前的 nginx 是否安装了 ssl 模块 --with-http_ssl_module ,通过命令 nginx -V ,从执行结果可以看到对应的模块是已安装的,如果没有安装该模块的话需要先安装一下,

[ali-server ~]# nginx -V
nginx version: nginx/1.8.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.1j 15 Oct 2014
TLS SNI support enabled
configure arguments: --user=nobody --group=nobody --prefix=/service/nginx --with-pcre=/service/pcre-8.33 --with-zlib=/service/zlib-1.2.11 --with-openssl=/service/openssl-1.0.1j --with-http_stub_status_module --with-http_gzip_static_module --with-http_realip_module --with-http_sub_module --with-http_ssl_module

原先我的配置都是监听 80 端口,然后根据不同的域名给他们做不同的配置,开启 ssl 即访问 https 的话是访问 443 端口,所以我们可以很自然的想到,只要把原来的 80 端口换成 443 端口,按照 ssl 配置要求配置上就可以实现我们的效果了,访问 80 端口(以 http 的方式访问)的时候将他们都转发到 https 的链接上,这样保证了用户访问的一定是 https 的链接。OK,接下来看下具体的配置

首先因为我所有的域名用的是一个证书,也就是说他们的 ssl 配置是相同的,我将这个配置单独写入一个文件,然后通过 include 的方式引入,便于后续的维护,这是我能想到的比较好的解决办法,如果有更简便的方法还请在评论区不吝赐教

# 在 vhosts 下新建 ssl.configure 文件,放置 ssl 公共配置
# 因为在 vhosts 下所有 .conf 后缀的都会被引入 nginx 配置中,所以文件后缀写为 configure
ssl_certificate   /etc/nginx/cert.pem;
ssl_certificate_key  /etc/nginx/key.pem;
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;
ssl_prefer_server_ciphers on;
# jjdxb.top, www.jjdxb.top 站点的配置
# 其他几个子域名的配置改动和这个基本一致
server {
  listen 80;
  server_name jjdxb.top;
  rewrite ^(.*)$ https://${server_name}$1 permanent;
}
server {
  listen       443 ssl;
  server_name jjdxb.top www.jjdxb.top;
  charset utf-8;
  access_log  logs/home_jjdxb_top.access.log;
  error_log   logs/home_jjdxb_top.error.log;

	include vhosts/ssl.configure; # 引入 ssl 公共配置

	location / {
      try_files $uri $uri/ /index.html;
	    root   /service/nginx/html/home/;
      index  index.html index.htm;
  }
}

配置到这里就 OK 了,访问网站就都是 https 了

小结

  1. 通配符这种写法还是看 issues 里看到的,想着试一下,发现真的可行
  2. 子账户还要再添加一下权限才能用
评论
  • 按正序
  • 按倒序
  • 按热度