概要:

现在网站基本都要求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

 

posted on 2023-04-14 20:31  06  阅读(656)  评论(0编辑  收藏  举报