概要:
现在网站基本都要求https加密访问,阿里云和腾讯云只有一年的免费证书可以用,于是尝试着看能不能自己搭一个免费证书
这里使用的是docker 容器 certbot来获取免费证书,具体步骤可以参考官网:https://eff-certbot.readthedocs.io/en/stable/using.html#setting-up-automated-renewal
dockerhub镜像地址为:https://hub.docker.com/r/certbot/certbot
首先看下官网:https://eff-certbot.readthedocs.io/en/stable/using.html#certbot-commands
certbot获取证书有好几种方式:
这里使用webroot的方式,即在自己服务器上放一个目录,给certbot验证,以确认域名的归属权,从而获取证书。
下面是从这个逻辑下的操作
具体命令使用可以用help看一下
docker run -it --rm certbot/certbot --help
搭建步骤:
1.理清docker nginx和certbot文件映射关系,做好文件映射
nginx和certbot有两个文件夹要共用:证书生成文件夹和web验证文件夹
容器启动命令如下:
nginx
docker run -d \
-v /app/docker/certbot/www:/usr/share/certbot/www \ #与certbot容器共用,http验证目录
-v /app/docker/certbot/ssl:/usr/share/certbot/ssl \ #与certbot容器共用,证书位置
-v /app/docker/nginx/conf/conf.d:/etc/nginx \ #配置文件
-v /app/docker/nginx/log:/var/log/nginx \ #日志
-v /app/docker/nginx/www:/usr/share/nginx \ #网站静态文件,我这里省略了,因为该nginx主要做反向代理
nginx \
-p 80:80 \
-p 443:443 \
certbot
docker run -it --rm \ #--rm执行完,自动删除容器 -v /app/docker/certbot/www:/data/letsencrypt \ #与nginx容器共用,http验证目录 -v /app/docker/certbot/ssl:/etc/letsencrypt \ #与nginx容器共用,证书生成目录 -v /app/docker/certbot/logs:/var/log/letsencrypt \ #certbot日志 certbot/certbot certonly \ #只获取不安装 -n \ #静默执行 --webroot \ #webroot方式 --webroot-path=/data/letsencrypt \ #webroot验证路径 -m xxx@qq.com \ #邮箱 --agree-tos \ #同意邮件推送协议 -d "$domain" #需要验证的域名
启动nginx,修改conf.d下的域名配置文件
server { listen 80; listen [::]:80; server_name xxx.com;#域名 server_tokens off; #配置http验证可访问 location ~/.well-known/acme-challenge/ { #此目录都是nginx容器内的目录,对应宿主机volumes中的http验证目录,而宿主机的又与certbot容器中命令--webroot-path指定目录一致,从而就整个串起来了,解决了http验证问题 root /usr/share/certbot/www; } #http跳转到https location / { return 301 https://xxx.com$request_uri; }
#默认请求设置 location / { proxy_pass http://1.1.1.1:8888; #转向真实页面处理 proxy_set_header Host $proxy_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Via "nginx"; }
}
配置完成,重启nginx
docker restart nginx
2.执行certbot容器命令
如无意外会出现succee提示,证书创建成功了
3.修改conf.d中的网站配置文件,增加ssl配置
注意:这里的证书地址为nginx里的地址,不要填成宿主机地址
server { listen 80; listen 443 ssl; server_name www.xxx.com; ssl_certificate /usr/share/certbot/ssl/live/www.xxx.com/fullchain.pem; #证书里面,必须是包含两套完整的-----BEGIN CERTIFICATE-----和-----END CERTIFICATE----- ssl_certificate_key /usr/share/certbot/ssl/live/www.xxx.com/privkey.pem; #证书密钥文件
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / { proxy_set_header Host $proxy_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Via "nginx"; proxy_pass http://1.1.1.1:8888; #转向真实地址处理
}
}
4.重启nginx,查看日志,打开域名测试
docker restart nginx docker logs -tf --tail 20 nginx
测试成功
不过查看证书信息,只有三个月有效期,定期更新必须安排上
这里写了两个脚本:一个用于创建证书,一个用于更新证书
创建证书脚本如下:
create_cert.sh
#!/bin/bash #useage: sh create_cert.sh DOMAIN1 DOMAIN2 ... LIST="$*" FAILED_LIST=() for domain in ${LIST[@]};do docker run -it --rm \ -v /app/docker/certbot/www:/data/letsencrypt \ #与nginx容器共用,http验证目录 -v /app/docker/certbot/ssl:/etc/letsencrypt \ #与nginx容器共用,证书生成目录 -v /app/docker/certbot/logs:/var/log/letsencrypt \ #certbot日志 certbot/certbot certonly \ -n \ --webroot \ --webroot-path=/data/letsencrypt \ -m xxx@qq.com \ --agree-tos \ -d "$domain" CODE=$? if [ $CODE -ne 0 ]; then FAILED_LIST+=($domain) fi done # output failed domains if [ ${#FAILED_LIST[@]} -ne 0 ];then echo 'failed domain:' for (( i=0; i<${#FAILED_LIST[@]}; i++ )); do echo ${FAILED_LIST[$i]} done fi
更新证书脚本如下:
renew_cert.sh
docker run -it --rm \ -v /app/docker/certbot/www:/data/letsencrypt \ #与nginx容器共用,http验证目录 -v /app/docker/certbot/ssl:/etc/letsencrypt \ #与nginx容器共用,证书生成目录 -v /app/docker/certbot/logs:/var/log/letsencrypt \ #certbot日志 certbot/certbot renew
把 renew_cert.sh 脚本放入crontab即可,每天执行一次
后记:
enhance参数貌似可以增加企业名称显示,值得研究
还可以研究下certbot 泛域名证书的获取,即 *.xxx.com
http://events.jianshu.io/p/034b891cf395
https://zhuanlan.zhihu.com/p/354241539
另外还看到github上有个域名获取开源项目,感觉也不错:https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E
由于是已存在的nginx容器,想新增映射文件又不动原有容器的情况下,只有修改配置文件,上次配置日志大小修改一个文件,这次挂载文件配置得修改两个文件,即
hostconfig.json
config.v2.json
https://blog.csdn.net/lcc2001/article/details/129270589
https://www.jb51.net/article/276039.htm
参考文档:
https://www.cnblogs.com/sparkdev/p/9163162.html (certbot版本太老,命令已经不兼容,不过思路说的很清楚)
https://www.cnblogs.com/txb1989/p/13079961.html
https://www.cnblogs.com/vishun/p/15746849.html
https://www.linuxprobe.com/linux-shell-get-args.html
https://blog.csdn.net/weixin_44052462/article/details/116024265