浏览代码

Merge pull request #8 from Duke-Wu/master

增加 python 语言版本(用户自动设置阿里云 DNS TXT 记录),感谢 @Duke-Wu
虞大胆 6 年之前
父节点
当前提交
df3eb181ae
共有 3 个文件被更改,包括 367 次插入0 次删除
  1. 173 0
      python-version/alydns27.py
  2. 173 0
      python-version/alydns36.py
  3. 21 0
      python-version/au.sh

+ 173 - 0
python-version/alydns27.py

@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+# coding:utf-8
+
+import base64
+import urllib
+import hmac
+import hashlib
+import pytz
+import datetime
+import random
+import string
+import json
+from sys import argv
+
+
+ACCESS_KEY_ID = '阿里云 access_key_id'
+ACCESS_KEY_SECRET = '阿里云 access_key_secret'
+
+
+class AliDns:
+    def __init__(self, access_key_id, access_key_secret, domain_name):
+        self.access_key_id = access_key_id
+        self.access_key_secret = access_key_secret
+        self.domain_name = domain_name
+
+    @staticmethod
+    def generate_random_str(length=14):
+        """
+        生成一个指定长度(默认14位)的随机数值,其中
+        string.digits = "0123456789'
+        """
+        str_list = [random.choice(string.digits) for i in range(length)]
+        random_str = ''.join(str_list)
+        return random_str
+
+    @staticmethod
+    def percent_encode(str):
+        res = urllib.quote(str.encode('utf-8'), '')
+        res = res.replace('+', '%20')
+        res = res.replace('*', '%2A')
+        res = res.replace('%7E', '~')
+        return res
+
+    @staticmethod
+    def utc_time():
+        """
+        请求的时间戳。日期格式按照ISO8601标准表示,
+        并需要使用UTC时间。格式为YYYY-MM-DDThh:mm:ssZ
+        例如,2015-01-09T12:00:00Z(为UTC时间2015年1月9日12点0分0秒)
+        :return:
+        """
+        utc_tz = pytz.timezone('UTC')
+        time = datetime.datetime.now(tz=utc_tz).strftime('%Y-%m-%dT%H:%M:%SZ')
+        return time
+
+    @staticmethod
+    def sign_string(url_param):
+        percent_encode = AliDns.percent_encode
+        sorted_url_param = sorted(url_param.items(), key=lambda x: x[0])
+        can_string = ''
+        for k, v in sorted_url_param:
+            can_string += '&' + percent_encode(k) + '=' + percent_encode(v)
+        string_to_sign = 'GET' + '&' + '%2F' + '&' + percent_encode(can_string[1:])
+        return string_to_sign
+
+    @staticmethod
+    def access_url(url):
+        f = urllib.urlopen(url)
+        result = f.read().decode('utf-8')
+        print(result)
+        return json.loads(result)
+
+    def visit_url(self, action_param):
+        common_param = {
+            'Format': 'json',
+            'Version': '2015-01-09',
+            'AccessKeyId': self.access_key_id,
+            'SignatureMethod': 'HMAC-SHA1',
+            'Timestamp': AliDns.utc_time(),
+            'SignatureVersion': '1.0',
+            'SignatureNonce': AliDns.generate_random_str(),
+            'DomainName': self.domain_name,
+        }
+        url_param = dict(common_param, **action_param)
+        string_to_sign = AliDns.sign_string(url_param)
+
+        hash_bytes = self.access_key_secret + "&"
+        h = hmac.new(hash_bytes, string_to_sign, digestmod=hashlib.sha1)
+        signature = base64.encodestring(h.digest()).strip()
+        url_param.setdefault('Signature', signature)
+        url = 'https://alidns.aliyuncs.com/?' + urllib.urlencode(url_param)
+        print(url)
+        return AliDns.access_url(url)
+
+    # 显示所有
+    def describe_domain_records(self):
+        """
+        最多只能查询此域名的 500条解析记录
+        PageNumber  当前页数,起始值为1,默认为1
+        PageSize  分页查询时设置的每页行数,最大值500,默认为20
+        :return:
+        """
+        action_param = dict(
+            Action='DescribeDomainRecords',
+            PageNumber='1',
+            PageSize='500',
+        )
+        result = self.visit_url(action_param)
+        return result
+
+    # 增加解析
+    def add_domain_record(self, type, rr, value):
+        action_param = dict(
+            Action='AddDomainRecord',
+            RR=rr,
+            Type=type,
+            Value=value,
+        )
+        result = self.visit_url(action_param)
+        return result
+
+    # 修改解析
+    def update_domain_record(self, id, type, rr, value):
+        action_param = dict(
+            Action="UpdateDomainRecord",
+            RecordId=id,
+            RR=rr,
+            Type=type,
+            Value=value,
+        )
+        result = self.visit_url(action_param)
+        return result
+
+    # 删除解析
+    def delete_domain_record(self, id):
+        action_param = dict(
+            Action="DeleteDomainRecord",
+            RecordId=id,
+        )
+        result = self.visit_url(action_param)
+        return result
+
+
+if __name__ == '__main__':
+    # domain = AliDns(ACCESS_KEY_ID, ACCESS_KEY_SECRET, 'wuqianlin.cn')
+    # domain.describe_domain_records()
+
+    # 增加记录
+    # domain.add_domain_record("TXT", "test", "test")
+
+    # 修改解析
+    # domain.update_domain_record('4011918010876928', 'TXT', 'test', 'text2')
+
+    # 删除解析记录
+    # data = domain.describe_domain_records()
+    # record_list = data["DomainRecords"]["Record"]
+    # for item in record_list:
+    #     if 'test' in item['RR']:
+    #        domain.delete_domain_record(item['RecordId'])
+
+    print(argv)
+    file_name, certbot_domain, acme_challenge, certbot_validation = argv
+
+    domain = AliDns(ACCESS_KEY_ID, ACCESS_KEY_SECRET, certbot_domain)
+    data = domain.describe_domain_records()
+    record_list = data["DomainRecords"]["Record"]
+    if record_list:
+        for item in record_list:
+            if acme_challenge == item['RR']:
+                domain.delete_domain_record(item['RecordId'])
+
+    domain.add_domain_record("TXT", acme_challenge, certbot_validation)
+

+ 173 - 0
python-version/alydns36.py

@@ -0,0 +1,173 @@
+# coding:utf-8
+
+import base64
+import urllib.parse
+import urllib
+import hmac
+import pytz
+import datetime
+import random
+import string
+import json
+from urllib import request
+from sys import argv
+
+
+ACCESS_KEY_ID = '阿里云 access_key_id'
+ACCESS_KEY_SECRET = '阿里云 access_key_secret'
+
+
+class AliDns:
+    def __init__(self, access_key_id, access_key_secret, domain_name):
+        self.access_key_id = access_key_id
+        self.access_key_secret = access_key_secret
+        self.domain_name = domain_name
+
+    @staticmethod
+    def generate_random_str(length=14):
+        """
+        生成一个指定长度(默认14位)的随机数值,其中
+        string.digits = "0123456789'
+        """
+        str_list = [random.choice(string.digits) for i in range(length)]
+        random_str = ''.join(str_list)
+        return random_str
+
+    @staticmethod
+    def percent_encode(str):
+        res = urllib.parse.quote(str.encode('utf-8'), '')
+        res = res.replace('+', '%20')
+        res = res.replace('*', '%2A')
+        res = res.replace('%7E', '~')
+        return res
+
+    @staticmethod
+    def utc_time():
+        """
+        请求的时间戳。日期格式按照ISO8601标准表示,
+        并需要使用UTC时间。格式为YYYY-MM-DDThh:mm:ssZ
+        例如,2015-01-09T12:00:00Z(为UTC时间2015年1月9日12点0分0秒)
+        :return:
+        """
+        utc_tz = pytz.timezone('UTC')
+        time = datetime.datetime.now(tz=utc_tz).strftime('%Y-%m-%dT%H:%M:%SZ')
+        return time
+
+    @staticmethod
+    def sign_string(url_param):
+        percent_encode = AliDns.percent_encode
+        sorted_url_param = sorted(url_param.items(), key=lambda x: x[0])
+        can_string = ''
+        for k, v in sorted_url_param:
+            can_string += '&' + percent_encode(k) + '=' + percent_encode(v)
+        string_to_sign = 'GET' + '&' + '%2F' + '&' + percent_encode(can_string[1:])
+        return string_to_sign
+
+    @staticmethod
+    def access_url(url):
+        req = request.Request(url)
+        with request.urlopen(req) as f:
+            result = f.read().decode('utf-8')
+            print(result)
+            return json.loads(result)
+
+    def visit_url(self, action_param):
+        common_param = {
+            'Format': 'json',
+            'Version': '2015-01-09',
+            'AccessKeyId': self.access_key_id,
+            'SignatureMethod': 'HMAC-SHA1',
+            'Timestamp': AliDns.utc_time(),
+            'SignatureVersion': '1.0',
+            'SignatureNonce': AliDns.generate_random_str(),
+            'DomainName': self.domain_name,
+        }
+        url_param = dict(common_param, **action_param)
+        string_to_sign = AliDns.sign_string(url_param)
+
+        hash_bytes = self.access_key_secret + "&"
+        h = hmac.new(hash_bytes.encode('utf-8'), string_to_sign.encode('utf-8'), digestmod='SHA1')
+        signature = base64.encodestring(h.digest()).strip()
+        url_param.setdefault('Signature', signature)
+        url = 'https://alidns.aliyuncs.com/?' + urllib.parse.urlencode(url_param)
+        print(url)
+        return AliDns.access_url(url)
+
+    # 显示所有
+    def describe_domain_records(self):
+        """
+        最多只能查询此域名的 500条解析记录
+        PageNumber  当前页数,起始值为1,默认为1
+        PageSize  分页查询时设置的每页行数,最大值500,默认为20
+        :return:
+        """
+        action_param = dict(
+            Action='DescribeDomainRecords',
+            PageNumber='1',
+            PageSize='500',
+        )
+        result = self.visit_url(action_param)
+        return result
+
+    # 增加解析
+    def add_domain_record(self, type, rr, value):
+        action_param = dict(
+            Action='AddDomainRecord',
+            RR=rr,
+            Type=type,
+            Value=value,
+        )
+        result = self.visit_url(action_param)
+        return result
+
+    # 修改解析
+    def update_domain_record(self, id, type, rr, value):
+        action_param = dict(
+            Action="UpdateDomainRecord",
+            RecordId=id,
+            RR=rr,
+            Type=type,
+            Value=value,
+        )
+        result = self.visit_url(action_param)
+        return result
+
+    # 删除解析
+    def delete_domain_record(self, id):
+        action_param = dict(
+            Action="DeleteDomainRecord",
+            RecordId=id,
+        )
+        result = self.visit_url(action_param)
+        return result
+
+
+if __name__ == '__main__':
+    # domain = AliDns(ACCESS_KEY_ID, ACCESS_KEY_SECRET, 'wuqianlin.cn')
+    # domain.describe_domain_records()
+
+    # 增加记录
+    # domain.add_domain_record("TXT", "test", "test")
+
+    # 修改解析
+    # domain.update_domain_record('4011918010876928', 'TXT', 'test', 'text2')
+
+    # 删除解析记录
+    # data = domain.describe_domain_records()
+    # record_list = data["DomainRecords"]["Record"]
+    # for item in record_list:
+    #     if 'test' in item['RR']:
+    #        domain.delete_domain_record(item['RecordId'])
+
+    print(argv)
+    file_name, certbot_domain, acme_challenge, certbot_validation = argv
+
+    domain = AliDns(ACCESS_KEY_ID, ACCESS_KEY_SECRET, certbot_domain)
+    data = domain.describe_domain_records()
+    record_list = data["DomainRecords"]["Record"]
+    if record_list:
+        for item in record_list:
+            if acme_challenge == item['RR']:
+                domain.delete_domain_record(item['RecordId'])
+
+    domain.add_domain_record("TXT", acme_challenge, certbot_validation)

+ 21 - 0
python-version/au.sh

@@ -0,0 +1,21 @@
+#!/bin/bash
+
+
+path=$(cd `dirname $0`; pwd)
+
+echo $path"/alydns.py"
+
+# 调用 python 脚本,自动设置 DNS TXT 记录。
+# 第一个参数:需要为那个域名设置 DNS 记录
+# 第二个参数:需要为具体那个 RR 设置
+# 第三个参数: letsencrypt 动态传递的 RR 值
+
+echo $CERTBOT_DOMAIN "_acme-challenge" $CERTBOT_VALIDATION
+
+python  $path"/alydns27.py"  $CERTBOT_DOMAIN "_acme-challenge"  $CERTBOT_VALIDATION >"/var/log/certdebug.log"
+
+# DNS TXT 记录刷新时间
+/bin/sleep 20
+
+echo "END"
+###