Website Migration Notice: SafePoint is now operated by CyberServal.Learn more →
DiscussionSLA

【推荐】纯脚本解决雷池WAF自动续签问题

Published 2 years ago

# Github Discussion
# General

Published 2 years ago

profile_photo

dominicx

Updated 2 years ago

0

解决思路

  1. 使用acme.sh自动续签SSL证书,支持泛域名证书。
  2. 更新雷池数据库,新证书信息同步到雷池界面信息。
  3. 雷池加载新SSL证书,让新证书生效。
  4. 不用过多代码,使用纯脚本。

操作步骤

1、使用acme.sh生成初步证书

可以直接使用acme.sh脚本,也可以使用容器,我使用了容器。
先拉取容器:docker pull neilpang/acme.sh
再初始生成证书:docker run --rm -it -v "/data/acme":/acme.sh neilpang/acme.sh --issue --dns dns_tencent -d *.987654321.xyz -d 987654321.xyz --yes-I-know-dns-manual-mode-enough-go-ahead-please

这里我使用的是腾讯云的域名服务,如果是其他DNS注册商,请更改dns_tencent ,具体参考acme.sh文档。987654321.xyz 为需要使用的域名。
具体acme.sh过程不赘述,需要提供各DNS注册商的SecretId、SecretKey。初次申请SSL证书运行成功之后可以补充到/data/acme/account.conf文件中。

2、雷池WAF中添加证书

把上一步的SSL下载到本地之后,在雷池WAF中“防护站点”->"证书管理" 中添加证书或者更新证书。这里获取证书在雷池WAF中的id。一般第一个是1 第二个是2,具体ID请自行获取(友情提示:按F12再编辑证书可见ID)

3、添加更新脚本

建立脚本目录:mkdir /data/acme/scripts
建立证书归档目录:mkdir /data/acme/archived/
编辑脚本:vi /data/acme/scripts/renew.sh
进入编辑模式之后输入一下内容

#!/bin/bash
#auto renew ssl for safeline waf
#by dominicx

#cert id in safeline for this ssl
CERTID=2
DOMAIN="987654321.xyz"
ARCHIVEDDIR="/data/acme/archived/"

#step 1 renew ssl cert
docker run --rm  -it -v "/data/acme":/acme.sh neilpang/acme.sh --issue --dns dns_tencent -d "*.$DOMAIN" -d "$DOMAIN"

newfile="/data/acme/*.$DOMAIN\_ecc/*.$DOMAIN.cer"
oldfile="/data/safeline/resources/nginx/certs/cert_$CERTID.crt"

newkey="/data/acme/*.$DOMAIN\_ecc/*.$DOMAIN.key"
oldkey="/data/safeline/resources/nginx/certs/cert_$CERTID.key"

if [ ! -e $newfile ] || [ ! -e $newkey ] ; then
    echo "至少有一个文件不存在,请检查文件路径。"
    echo $newfile
    echo $newkey
    exit 1
fi

newfile_ts=$(stat -c %Y $newfile)
oldfile_ts=$(stat -c %Y $oldfile)

if [ $[$newfile_ts - $oldfile_ts] -ge 300 ]; then   #5 minutes
    echo "Move old SSL cert files to $ARCHIVEDDIR ."
    mv $oldfile $ARCHIVEDDIR
    mv $oldkey $ARCHIVEDDIR
    echo "Copy new SSL cert files."
    cp $newfile $oldfile
    cp $newkey $oldkey

    keystr="$(<$newkey)"
    certstr="$(<$newfile)"

    sql="update mgt_ssl_cert set updated_at=to_timestamp($newfile_ts),valid_before=CAST(concat(to_timestamp($newfile_ts+90*24*3600)::date+1,' 07:59:59+08') AS TIMESTAMPTZ ),cert_content='$certstr',key_content='$keystr' where id=$CERTID;"

    #update safeline pg
    docker exec -it safeline-pg psql -U safeline-ce safeline-ce  -c "$sql"
    #nginx reload ssl cert
    docker exec -it safeline-tengine nginx -s reload

    echo "updating site $CERTID SSL cert file Done."

fi

脚本说明:

  1. CERTID 后面的2就是上面步骤获取到的雷池waf系统中证书的ID
  2. DOMAIN 就是雷池waf系统中证书 对应的域名,其实也可以脚本获取,但是写下来也容易。
  3. newfile="/data/acme/.$DOMAIN\_ecc/.$DOMAIN.cer" newkey="/data/acme/.$DOMAIN\_ecc/.$DOMAIN.key" 两个具体目录要根据第一步申请的证书存放目录来修改,我使用acme.sh默认ecc证书,所以目录结构是这样的。
  4. 默认只有新证书比旧证书时间戳大于5分钟才更新。300 那里。
  5. sql 为拼接的更新雷池waf 证书信息SQL语句,将来可能发生变化。其中更新证书时间为当前证书时间默认增加90天(ZeroSSL的证书90天有效)后的0点,时区采用北京时间时区,也就+0800时区。
  6. 最后两个步骤调用docker命令分别是更新数据信息和重新加载新证书。

4、添加定时任务

crontab -e 添加定时任务
15 1 1,15 * * /data/acme/scripts/renew.sh >/dev/null

在1号15号1点15分调度任务执行,可以根据需要修改。

大家玩得愉快

profile_photo

dominicx

Updated 2 years ago

0

腾讯云的Tencent_SecretId和Tencent_SecretKey
可以直接放到account.conf文件
Tencent_SecretId='AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxx'
Tencent_SecretKey='XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
运行成功后会变成下面样子,不用担心。
SAVED_Tencent_SecretId='AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxx'
SAVED_Tencent_SecretKey='XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

profile_photo

dominicx

Updated 2 years ago

0

其实也可以让acme.sh在docker之外运行用reload cmd来完成优化。
期待 雷池waf 整合一下。

profile_photo

zpxzgh

Updated a year ago

0

非常感谢大佬提出的解决方案!同期待雷池官方整合证书DNS更新。

顺便提供一点我实际使用时遇到的问题和解决方案。

直接按照大佬的方案操作,大部分情况是没问题的,PC网页也都正常,唯独bitwarden的安卓客户端会有证书问题。

后来我排查发现,导入证书的时候,不能导入*.$DOMAIN.cer,而是要导入fullchain.cer。貌似是因为bitwarden客户端的验证要求比较严格。

另外我发现,开启了BOT防护中的人机验证后,bitwarden的安卓客户端也会连不上,其它防护暂时没问题。

希望能帮到遇到同样问题的人 。