暗中观察

免费通配符ssl证书
免费通配符ssl证书之Let's Encryptps: CentOS7 / Aliyundocker 方式安装 ...
扫描右侧二维码阅读全文
10
2018/12

免费通配符ssl证书

免费通配符ssl证书之Let's Encrypt

ps: CentOS7 / Aliyun

docker 方式安装

  sudo docker run -it --rm --name certbot \
        -v "/etc/letsencrypt:/etc/letsencrypt" \
        -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
        certbot/certbot certonly -d *.sunjianhua.xyz -d sunjianhua.xyz --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory  --register-unsafely-without-email

以下内容已失效,建议使用上面docker方式

下载安装

> wget https://dl.eff.org/certbot-auto
> chmod +x certbot-auto
> ./certbot-auto certonly  -d *.sunjianhua.xyz -d sunjianhua.xyz --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory 

执行完成后,证书就生成在以下路径:
/etc/letsencrypt/live/sunjianhua.xyz/

nginx配置

nginx配置文件中加入:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_session_cache builtin:1000 shared:SSL:10m;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/sunjianhua.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sunjianhua.xyz/privkey.pem;
ssl_session_timeout 5m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;

自动升续期

证书有效期3个月,通配证书通过dns的方式验证域名归属!

a、对机器上所有证书 renew
$ ./certbot-auto renew --manual --preferred-challenges dns --manual-auth-hook /脚本目录/au.sh

b、对某一张证书进行续期
先看看机器上有多少证书:
$ ./certbot-auto certificates
$ ./certbot-auto renew --cert-name sunjianhua.xyz --manual-auth-hook /脚本目录/au.sh

我最终执行的命令为:

> ./certbot-auto renew --cert-name sunjianhua.xyz --manual-auth-hook /root/script/certbot-renew-sunjianhua-xyz.sh

以上命令必须创建两个文件:
认证文件: certbot-renew-sunjianhua-xyz.sh
阿里云dns修改文件:alydns.php

certbot-renew-sunjianhua-xyz.sh内容如下:

#!/usr/bin/bash

# PHP 脚本位置
PHPPROGRAM="/root/script"

# 要配置的域名
#DOMAIN="sunjianhua.cn"
DOMAIN="sunjianhua.xyz"
# 脚本路径
PATH="/root/script"

# 要为那个 DNS RR 添加 TXT 记录
CREATE_DOMAIN="_acme-challenge"

# $CERTBOT_VALIDATION 是 Certbot 的内置变量,代表需要为 DNS TXT 记录设置的值
echo $PATH"/alydns.php"

# 调用 PHP 脚本,自动设置 DNS TXT 记录。
/usr/bin/php   $PATH"/alydns.php"  $DOMAIN $CREATE_DOMAIN  $CERTBOT_VALIDATION >/var/log/certdebug.log

# DNS TXT 记录刷新时间
/usr/bin/sleep 60

alydns.php 内容如下:

<?php

date_default_timezone_set("GMT");

//*这两个值需要去[阿里云申请][2]*
define("accessKeyId", "输入你aliyun的accessKeyId");
define("accessSecrec", "输入你aliyun的accessSecrec");

//manager domain 
$obj = new AliDns(accessKeyId, accessSecrec, $argv[1]);
$data = $obj->DescribeDomainRecords();
$data = $data["DomainRecords"]["Record"];
if (is_array($data)) {
      foreach ($data as $v) {
           if ($v["RR"] == $argv[2]) {
               $obj->DeleteDomainRecord($v["RecordId"]);
           }
      }
} 

print_r($obj->AddDomainRecord("TXT", $argv[2],$argv[3]));

class AliDns {
    private $accessKeyId = null;
    private $accessSecrec = null;
    private $DomainName = null;


    public function __construct($accessKeyId, $accessSecrec, $domain) {
        $this->accessKeyId = $accessKeyId;
        $this->accessSecrec = $accessSecrec;
        $this->DomainName = $domain;
    }

    public function DescribeDomainRecords() {
        $requestParams = array(
             "Action" => "DescribeDomainRecords"
        );
        $val = $this->send($requestParams);
        return $this->out($val);
    }


    public function UpdateDomainRecord($id, $type, $rr,$value){
        $requestParams = array(
            "Action" => "UpdateDomainRecord",
            "RecordId" => $id,
            "RR" => $rr,
            "Type" => $type,
            "Value" => $value,
        );
        $val = $this->send($requestParams);
        return $this->out($val);
    }
    public function DeleteDomainRecord($id) {
    $requestParams = array(
            "Action" => "DeleteDomainRecord",
            "RecordId" => $id,
        );
        $val = $this->send($requestParams);
        return $this->out($val);
    }

    public function AddDomainRecord($type, $rr, $value) {
        $requestParams = array(
            "Action" => "AddDomainRecord",
            "RR" => $rr,
            "Type" => $type,
            "Value" => $value,
        );
        $val = $this->send($requestParams);
        return $this->out($val);
    }

    private function send($requestParams) {
        $publicParams = array(
        "DomainName" => $this->DomainName,
        "Format" => "JSON",
        "Version" => "2015-01-09",
        "AccessKeyId" => $this->accessKeyId,
        "Timestamp" => date("Y-m-d\TH:i:s\Z"),
        "SignatureMethod" => "HMAC-SHA1",
        "SignatureVersion" => "1.0",
        "SignatureNonce" => substr(md5(rand(1, 99999999)), rand(1, 9), 14),
        );

        $params = array_merge($publicParams, $requestParams);
        print_r($params);
    $params['Signature'] = $this->sign($params, $this->accessSecrec);
        $uri = http_build_query($params);
        $url = 'http://alidns.aliyuncs.com/?'.$uri;
        return $this->curl($url);
    }


    private function sign($params, $accessSecrec, $method = "GET") {
        ksort($params);
        $stringToSign = strtoupper($method).'&'.$this->percentEncode('/').'&';
        $tmp = "";
        foreach($params as $key => $val){
            $tmp .= '&'.$this->percentEncode($key).'='.$this->percentEncode($val);
        }
        $tmp = trim($tmp, '&');
        $stringToSign = $stringToSign.$this->percentEncode($tmp);
        $key = $accessSecrec.'&';
        $hmac = hash_hmac("sha1", $stringToSign, $key, true);
        return base64_encode($hmac);
    }

    private function percentEncode($value = null){
        $en = urlencode($value);
        $en = str_replace("+", "%20", $en);
        $en = str_replace("*", "%2A", $en);
        $en = str_replace("%7E", "~", $en);
        return $en;
    }

    private function curl($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url );
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
        $result = curl_exec ($ch);
        curl_close($ch);
        return $result;
    }

    private function out($msg) {
        return json_decode($msg, true);
    }
}

最后配置crond定时任务:

> vi /etc/crontab
0 0 0 6 * ?  root /root/script/certbot-auto renew --cert-name sunjianhua.xyz --manual-auth-hook /root/script/certbot-renew-sunjianhua-xyz.sh

参考:
https://blog.csdn.net/lihao19910921/article/details/81534188
https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au

Last modification:April 26th, 2021 at 02:58 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment