前言

ssl证书是现代网站安全通信所必须配置的,众所周知,acme.sh是一个可以免费申请ssl证书并自动更新的开源程序,笔者结合自己的各个网站部署过程,重新写了一下自定义的申请证书的函数,放入.bashrc文件中source一下即可使用。https通信是很有必要的,你可以通过浏览器旁边的按钮查看一下当前网站的证书信息,如图为本站当前的证书信息:

2023-12-04T14:11:42.png

当证书无效或过期时,浏览器一般会发出安全警告,这时你就要注意不要在该站点交换敏感信息了。

自定义函数

笔者编写的自定义函数如下,笔者水平有限,函数可能比较简陋,敬请各位网友指正,提出改进意见。

export CF_Key=""
export CF_Email=""
function red() {
    [ "$1" = "-n" ] && local nl=$1 && shift
    echo -e $nl "\033[31m\033[01m$1\033[0m$2"
}
function green() {
        [ "$1" = "-n" ] && local nl=$1 && shift
        echo -e $nl "\033[32m\033[01m$1\033[0m$2"
}
function yellow() {
        [ "$1" = "-n" ] && local nl=$1 && shift
        echo -e $nl "\033[33m\033[01m$1\033[0m$2"
}
function blue() {
        [ "$1" = "-n" ] && local nl=$1 && shift
        echo -e $nl "\033[34m\033[01m$1\033[0m$2"
}
checkDomain () {
    local myip="$(curl -4 ifconfig.me)"
    if host $1 | grep --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn,.idea,.tox} $myip &> /dev/null
    then
            green "域名 $1 已解析到当前vps"
    else
            red "域名 $1 未解析到当前vps或解析未生效!"
            return 1
    fi
}
getCert () {
    cert_path=/usr/local/etc/certs
    local standalone all force
    mkdir -p $cert_path
    command -v nginx &> /dev/null || red "nginx未安装,请先安装nginx" || return 1
    # checkRelease
    if [ ! -d ~/.acme.sh/ ]
    then
            blue "准备安装acme和依赖socat"
            curl -L https://get.acme.sh | sh
            command -v socat &> /dev/null || sudo apt install -y socat
    fi
    green "acme已安装."
    ~/.acme.sh/acme.sh --upgrade --auto-upgrade
    while getopts :saf opt
    do
            case $opt in
                    (s) blue "using standalone mode." && standalone=true  ;;
                    (a) blue "all subdomains." && all=true  ;;
                    (f) blue "force mode." && force="--force"  ;;
                    (*) red "skip invalid option: $opt" ;;
            esac
    done
    shift $[$OPTIND -1]
    ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
    for domain in $@
    do
            blue $domain
            if [[ ! "$domain" =~ "\*." ]] && ! checkDomain $1
            then
                    continue
            fi
            if [ -z $standalone ]
            then
                    blue "using default dns_cf mode."
                    /root/.acme.sh/acme.sh --issue -d "$domain" --dns dns_cf --key-file "$cert_path/$domain.key" --fullchain-file "$cert_path/$domain.cer" --reloadcmd "nginx -s reload" $force
                    /root/.acme.sh/acme.sh --issue -d "$domain" -k ec-256 --dns dns_cf --key-file "$cert_path/ecc.$domain.key" --fullchain-file "$cert_path/ecc.$domain.cer" --reloadcmd "nginx -s reload" $force
                    if [ ! -z $all ]
                    then
                            /root/.acme.sh/acme.sh --issue -d "*.$domain" --dns dns_cf --key-file "$cert_path/*.$domain.key" --fullchain-file "$cert_path/*.$domain.cer" --reloadcmd "nginx -s reload" $force
                            /root/.acme.sh/acme.sh --issue -d "*.$domain" -k ec-256 --dns dns_cf --key-file "$cert_path/ecc.*.$domain.key" --fullchain-file "$cert_path/ecc.*.$domain.cer" --reloadcmd "nginx -s reload" $force
                    fi
            else
                    yellow "using standalone mode."
                    sudo fuser -k 80/tcp
                    /root/.acme.sh/acme.sh --issue -d "$domain" --standalone --key-file "$cert_path/$domain.key" --fullchain-file "$cert_path/$domain.cer" --reloadcmd "nginx || nginx -s reload" $force
                    sudo fuser -k 80/tcp
                    /root/.acme.sh/acme.sh --issue -d "$domain" -k ec-256 --standalone --key-file "$cert_path/ecc.$domain.key" --fullchain-file "$cert_path/ecc.$domain.cer" --reloadcmd "nginx || nginx -s reload" $force
            fi
    done
    return 0
}

用法与说明

默认采用dns_cf,需要配置cf的key和email,在如下网址可查看到key:

https://dash.cloudflare.com/profile/api-tokens

登录进入后查看复制Global API Key即可

使用dns法验证域名申请时不会影响到nginx等web服务器的运行,适合在一个服务器上运行多个网站的情况,配置好环境变量后即可开始申请证书。

申请单域名证书:

getCert sfnote.com

申请单域名证书和该域名的泛域名证书:

getCert -a sfnote.com

执行后会得到sfnote.com和*.sfnote.com两个证书,配置nginx的证书指向函数里配置的$cert_path下的证书即可。

另外,使用-s选项指定standalone模式验证域名,适合域名不在cf上或不想配置dns的同志,但要注意端口的占用问题,申请证书时因为释放端口会造成网站服务暂时不可用,acme会记住reloadcmd但不会在执行cron前关闭端口,你需要修改默认的acme安装的cron任务才能实现定期更新证书。一个示例cron任务如下:

44 12 * * * nginx -s stop; "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > cert_log ; nginx

最后,可使用-f选项强制更新证书,但要注意acme官方的频率限制。

注意:笔者使用的是nginx且为直接运行模式,所以reloadcmd里是nginx -s reload,你可能需要根据自己的实际服务器和运行模式修改reloadcmd和其他参数。

参考链接

最后修改:2023 年 12 月 04 日
如果觉得我的文章对你有用,请随意赞赏