diff --git a/README.md b/README.md
index 5a18682..e838872 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,7 @@
- [x] [DNS.COM](https://www.dns.com/)(@loftor-git)
- [x] [DNSPOD 国际版](https://www.dnspod.com/)
- [x] [CloudFlare](https://www.cloudflare.com/)(@tongyifan)
+ - [x] [HE.net](https://dns.he.net/)(@NN708) (不支持自动创建记录)
- 其他:
- [x] 可设置定时任务
- [x] 本地文件缓存(减少 API 请求)
@@ -78,6 +79,7 @@
- [DNS.COM API Key/Secret](https://www.dns.com/member/apiSet)
- [DNSPOD(国际版)](https://www.dnspod.com/docs/info.html#get-the-user-token)
- [CloudFlare API Key](https://support.cloudflare.com/hc/en-us/articles/200167836-Where-do-I-find-my-Cloudflare-API-key-)
+ - [HE.net DDNS 文档](https://dns.he.net/docs.html)(仅需将设置的密码填入`token`字段,`id`字段可留空)
2. 修改配置文件,`ipv4`和`ipv6`字段,为待更新的域名,详细参照配置说明
@@ -102,9 +104,9 @@ python run.py -c /path/to/config.json
| key | type | required | default | description | tips |
| :----: | :---------: | :------: | :---------: | :--------------: | ----------------------------------------------------------------- |
-| id | string | √ | 无 | api 访问 ID | cloudflare 为邮箱 |
+| id | string | √ | 无 | api 访问 ID | cloudflare 为邮箱,
HE.net 可留空 |
| token | string | √ | 无 | api 授权 token | 也叫 secret key, **反馈粘贴时删除** |
-| dns | string | No | `"dnspod"` | dns 服务商 | 阿里`alidns`,
dns.com 为`dnscom`,
DNSPOD 国际版`dnspod_com` |
+| dns | string | No | `"dnspod"` | dns 服务商 | 阿里`alidns`,
dns.com 为`dnscom`,
DNSPOD 国际版`dnspod_com`,
HE.net 为`he` |
| ipv4 | array | No | `[]` | ipv4 域名列表 | 为`[]`时,不会获取和更新 IPv4 地址 |
| ipv6 | array | No | `[]` | ipv6 域名列表 | 为`[]`时,不会获取和更新 IPv6 地址 |
| index4 | string\|int | No | `"default"` | ipv4 获取方式 | 可设置`网卡`,`内网`,`公网`,`正则`等方式 |
@@ -133,7 +135,7 @@ python run.py -c /path/to/config.json
"$schema": "https://ddns.newfuture.cc/schema/v2.json",
"id": "12345",
"token": "mytokenkey",
- "dns": "dnspod 或 dnspod_com 或 alidns 或 dnscom 或 cloudflare",
+ "dns": "dnspod 或 dnspod_com 或 alidns 或 dnscom 或 cloudflare 或 he",
"ipv4": ["ddns.newfuture.cc", "ipv4.ddns.newfuture.cc"],
"ipv6": ["ddns.newfuture.cc", "ipv6.ddns.newfuture.cc"],
"index4": 0,
diff --git a/dns/he.py b/dns/he.py
new file mode 100644
index 0000000..ea4b12c
--- /dev/null
+++ b/dns/he.py
@@ -0,0 +1,85 @@
+# coding=utf-8
+"""
+Hurricane Electric (he.net) API
+Hurricane Electric (he.net) 接口解析操作库
+https://dns.he.net/docs.html
+@author: NN708
+"""
+
+from logging import debug, info, warning
+
+try:
+ # python 2
+ from httplib import HTTPSConnection
+ from urllib import urlencode
+except ImportError:
+ # python 3
+ from http.client import HTTPSConnection
+ from urllib.parse import urlencode
+
+__author__ = 'NN708'
+
+
+class Config:
+ TOKEN = "password"
+ PROXY = None # 代理设置
+
+
+class API:
+ # API 配置
+ SITE = "dyn.dns.he.net"
+ METHOD = "POST"
+ ACTION = "nic/update"
+ TOKEN_PARAM = "password" # key name of token param
+
+
+def request(param=None, **params):
+ """
+ 发送请求数据
+ """
+ if param:
+ params.update(param)
+
+ params.update({API.TOKEN_PARAM: '***'})
+ info("%s/%s : %s", API.SITE, API.ACTION, params)
+ params[API.TOKEN_PARAM] = Config.TOKEN
+
+ if Config.PROXY:
+ conn = HTTPSConnection(Config.PROXY)
+ conn.set_tunnel(API.SITE, 443)
+ else:
+ conn = HTTPSConnection(API.SITE)
+
+ conn.request(API.METHOD, '/' + API.ACTION, urlencode(params), {
+ "Content-type": "application/x-www-form-urlencoded"
+ })
+ response = conn.getresponse()
+ res = response.read().decode('utf8')
+ conn.close()
+
+ if response.status < 200 or response.status >= 300:
+ warning('%s : error[%d]:%s', API.ACTION, response.status, res)
+ raise Exception(res)
+ else:
+ debug('%s : result:%s', API.ACTION, res)
+ if not res:
+ raise Exception("empty response")
+ elif res[:5] == "nochg" or res[:4] == "good": # No change or success
+ return res
+ else:
+ raise Exception(res)
+
+
+def update_record(domain, value, record_type="A"):
+ """
+ 更新记录
+ """
+ info(">>>>>%s(%s)", domain, record_type)
+ res = request(hostname=domain, myip=value)
+ if res[:4] == "good":
+ result = "Record updated. New IP is: " + res[5:-1]
+ elif res[:5] == "nochg":
+ result = "IP not changed. IP is: " + res[6:-1]
+ else:
+ result = "Record update failed."
+ return result
diff --git a/schema.json b/schema.json
index 5cb10ca..79b1b87 100644
--- a/schema.json
+++ b/schema.json
@@ -29,7 +29,7 @@
"$id": "/properties/dns",
"type": "string",
"title": "DNS Provider",
- "description": "dns服务商:阿里为alidns,DNS.COM为dnscom,DNSPOD国际版为(dnspod_com),cloudflare",
+ "description": "dns服务商:阿里为alidns,DNS.COM为dnscom,DNSPOD国际版为(dnspod_com),cloudflare,HE.net为he",
"default": "dnspod",
"examples": [
"dnspod",
@@ -41,7 +41,8 @@
"alidns",
"cloudflare",
"dnspod_com",
- "dnscom"
+ "dnscom",
+ "he"
]
},
"ipv4": {
diff --git a/schema/v2.json b/schema/v2.json
index 644af91..76a7014 100644
--- a/schema/v2.json
+++ b/schema/v2.json
@@ -31,10 +31,10 @@
"$id": "/properties/dns",
"type": "string",
"title": "DNS Provider",
- "description": "dns服务商:阿里为alidns,DNS.COM为dnscom,DNSPOD国际版为dnspod_com,cloudflare",
+ "description": "dns服务商:阿里为alidns,DNS.COM为dnscom,DNSPOD国际版为dnspod_com,cloudflare,HE.net为he",
"default": "dnspod",
"examples": ["dnspod", "alidns", "cloudflare"],
- "enum": ["dnspod", "alidns", "cloudflare", "dnspod_com", "dnscom"]
+ "enum": ["dnspod", "alidns", "cloudflare", "dnspod_com", "dnscom", "he"]
},
"ipv4": {
"$id": "/properties/ipv4",