Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
config.*.json

.vscode
*.temp

# Byte-compiled / optimized / DLL files
Expand Down
8 changes: 8 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"recommendations": [
"ms-python.flake8",
"ms-python.autopep8",
"ms-python.python",
"github.vscode-github-actions",
]
}
28 changes: 21 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# [DDNS](https://github.com/NewFuture/DDNS) [<img src=".build/ddns.svg" width="32px" height="32px"/>](https://ddns.newfuture.cc)


> 自动更新 DNS 解析 到本机 IP 地址,支持 ipv4 和 ipv6 以 本地(内网)IP 和 公网 IP。
> 代理模式,支持自动创建域名记录。


[![PyPI](https://img.shields.io/pypi/v/ddns.svg?label=DDNS&style=social)](https://pypi.org/project/ddns/)
[![Build Status](https://github.com/NewFuture/DDNS/actions/workflows/build.yml/badge.svg?event=push)](https://github.com/NewFuture/DDNS/actions/workflows/build.yml)
[![Publish Status](https://github.com/NewFuture/DDNS/actions/workflows/publish.yml/badge.svg)](https://github.com/NewFuture/DDNS/releases/latest)
Expand All @@ -18,7 +16,7 @@
- [x] 多系统兼容 ![cross platform](https://img.shields.io/badge/platform-windows_%7C%20linux_%7C%20osx-success.svg?style=social)
- [x] python3 支持 ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ddns.svg?style=social)(2.x支持python2和python3)
- [x] PIP 安装 ![PyPI - Wheel](https://img.shields.io/pypi/wheel/ddns.svg?style=social)
- [x] Docker 支持(@NN708)
- [x] Docker 支持(@NN708)
- 域名支持:
- [x] 多个域名支持
- [x] 多级域名解析
Expand Down Expand Up @@ -52,17 +50,25 @@
根据需要选择一种方式: `二进制`版,`pip`版,`源码`运行,或者`Docker`

- #### pip 安装(需要 pip 或 easy_install)

1. 安装 ddns: `pip install ddns` 或 `easy_install ddns`
2. 运行: `ddns`

- #### 二进制版(单文件,无需 python)

- Windows [ddns.exe](https://github.com/NewFuture/DDNS/releases/latest)
- Linux (仅 Ubuntu 测试) [ddns](https://github.com/NewFuture/DDNS/releases/latest)
- Mac OSX [ddns-osx](https://github.com/NewFuture/DDNS/releases/latest)

- #### 源码运行(无任何依赖, 需 python 环境)

1. clone 或者[下载此仓库](https://github.com/NewFuture/DDNS/archive/master.zip)并解压
2. 运行./run.py (widnows 双击`run.bat`或者运行`python run.py`)

- #### Docker(需要安装 Docker)

- 使用环境变量:

```
docker run -d \
-e DDNS_DNS=dnspod \
Expand All @@ -73,7 +79,9 @@
--network host \
newfuture/ddns
```

- 使用配置文件(docker 工作目录`/ddds/`,默认配置位置`/ddns/config.json`):

```
docker run -d \
-v /local/config/path/:/ddns/ \
Expand Down Expand Up @@ -102,7 +110,7 @@

1. 命令行参数 `ddns --key=value` (`ddns -h` 查看详情),优先级最高
2. JSON配置文件(值为null认为是有效值,会覆盖环境变量的设置,如果没有对应的key则会尝试试用环境变量)
3. 环境变量DDNS_前缀加上key 全大写或者全小写 (`${ddns_key}` 或 `${DDNS_KEY}`)
3. 环境变量DDNS_前缀加上key 全大写或者全小写,点转下划线 (`${ddns_id}` 或 `${DDNS_ID}`,`${DDNS_LOG_LEVEL}`)

<details open>

Expand Down Expand Up @@ -132,8 +140,9 @@ python run.py -c /path/to/config.json
| index6 | string\|int\|array | No | `"default"` | ipv6 获取方式 | 可设置`网卡`,`内网`,`公网`,`正则`等方式 |
| ttl | number | No | `null` | DNS 解析 TTL 时间 | 不设置采用 DNS 默认策略 |
| proxy | string | No | 无 | http 代理`;`分割 | 多代理逐个尝试直到成功,`DIRECT`为直连 |
| debug | bool | No | `false` | 是否开启调试 | 运行异常时,打开调试输出,方便诊断错误 |
| ~~debug~~ | bool | No | `false` | 是否开启调试 | v4 中弃用,请改用log.level=DEBUG |
| cache | string\|bool | No | `true` | 是否缓存记录 | 正常情况打开避免频繁更新,默认位置为临时目录下`ddns.cache`,<br>也可以指定一个具体文件实现自定义文件缓存位置 |
| log | {"level":string,"file":string} | No | `null` | 日志配置(可选) | 日志配置,日志级别和路径(默认命令行),<br>例如: `{ "level": "DEBUG", "file": "/path/to/logfile.log" }` |

#### index4 和 index6 参数说明

Expand Down Expand Up @@ -167,7 +176,7 @@ python run.py -c /path/to/config.json

```json
{
"$schema": "https://ddns.newfuture.cc/schema/v2.8.json",
"$schema": "https://ddns.newfuture.cc/schema/v4.0.json",
"id": "12345",
"token": "mytokenkey",
"dns": "dnspod 或 dnspod_com 或 alidns 或 dnscom 或 cloudflare 或 he 或 huaweidns 或 callback",
Expand All @@ -177,7 +186,10 @@ python run.py -c /path/to/config.json
"index6": "public",
"ttl": 600,
"proxy": "127.0.0.1:1080;DIRECT",
"debug": false
"log": {
"level": "DEBUG",
"file": "dns.log"
},
}
```

Expand All @@ -200,12 +212,14 @@ python run.py -c /path/to/config.json
- 使用init.d和crontab:
`sudo ./task.sh`
- 使用systemd:

```bash
安装:
sudo ./systemd.sh install
卸载:
sudo ./systemd.sh uninstall
```

该脚本安装的文件符合 [Filesystem Hierarchy Standard (FHS)](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard):
可执行文件所在目录为 `/usr/share/DDNS`
配置文件所在目录为 `/etc/DDNS`
Expand Down
30 changes: 14 additions & 16 deletions run.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@
# nuitka-project-else:
# nuitka-project: --product-version=0.0.0

from __future__ import print_function
from time import ctime, asctime
from os import path, environ, name as os_name
from tempfile import gettempdir
from logging import DEBUG, basicConfig, info, warning, error, debug
from logging import basicConfig, info, warning, error, debug
from subprocess import check_output

import sys
Expand Down Expand Up @@ -82,8 +80,7 @@ def change_dns_record(dns, proxy_list, **kw):
else:
dns.Config.PROXY = proxy
record_type, domain = kw['record_type'], kw['domain']
print('\n%s %s(%s) ==> %s [via %s]' %
(asctime(), domain, record_type, kw['ip'], proxy))
info("%s(%s) ==> %s [via %s]", domain, record_type, kw['ip'], proxy)
try:
return dns.update_record(domain, kw['ip'], record_type=record_type)
except Exception as e:
Expand All @@ -108,7 +105,7 @@ def update_ip(ip_type, cache, dns, proxy_list):
error('Fail to get %s address!', ipname)
return False
elif cache and (address == cache[ipname]):
print('.', end=" ") # 缓存命中
info('%s address not changed, using cache.', ipname)
return True
record_type = (ip_type == '4') and 'A' or 'AAAA'
update_fail = False # https://github.com/NewFuture/DDNS/issues/16
Expand All @@ -132,16 +129,17 @@ def main():
dns.Config.ID = get_config('id')
dns.Config.TOKEN = get_config('token')
dns.Config.TTL = get_config('ttl')
if get_config('debug'):
ip.DEBUG = get_config('debug')
basicConfig(
level=DEBUG,
format='%(asctime)s <%(module)s.%(funcName)s> %(lineno)d@%(pathname)s \n[%(levelname)s] %(message)s')
print("DDNS[", __version__, "] run:", os_name, sys.platform)
if get_config("config"):
print("Configuration was loaded from <==",
path.abspath(get_config("config")))
print("=" * 25, ctime(), "=" * 25, sep=' ')

basicConfig(
level=get_config('log.level'),
format='%(asctime)s [%(levelname)s] %(message)s',
datefmt='%m-%d %H:%M:%S',
filename=get_config('log.file'),
)

info("DDNS[ %s ] run: %s %s", __version__, os_name, sys.platform)
if get_config("config"):
info("loaded Config from: %s", path.abspath(get_config('config')))

proxy = get_config('proxy') or 'DIRECT'
proxy_list = proxy if isinstance(
Expand Down
7 changes: 4 additions & 3 deletions schema/v2.8.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,14 @@
"debug": {
"$id": "/properties/debug",
"type": "boolean",
"title": "Enable Debug Mode",
"description": "是否启用调试模式显示更多信息",
"title": "Enable Debug Mode (deprecated, use logger instead)",
"description": "是否启用调试模式显示更多信息(已废弃,请使用 logger 字段)",
"default": false,
"examples": [
false,
true
]
],
"deprecated": true
},
"cache": {
"$id": "/properties/cache",
Expand Down
95 changes: 75 additions & 20 deletions schema.json → schema/v4.0.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://ddns.newfuture.cc/schema.json",
"description": "[Deprecated] 已弃用,请使用 https://ddns.newfuture.cc/schema/v2.json",
"$id": "https://ddns.newfuture.cc/schema/v4.0.json",
"description": "DNS 配置文件 https://github.com/NewFuture/DDNS",
"type": "object",
"properties": {
"$schema": {
"type": "string",
"title": "please use https://ddns.newfuture.cc/schema/v2.json",
"description": "请更换为 https://ddns.newfuture.cc/schema/v2.json",
"title": "please use https://ddns.newfuture.cc/schema/v2.8.json",
"description": "请更换为 https://ddns.newfuture.cc/schema/v2.8.json",
"default": "https://ddns.newfuture.cc/schema/v2.8.json",
"enum": [
"https://ddns.newfuture.cc/schema/v2.json",
"http://ddns.newfuture.cc/schema/v2.json"
"https://ddns.newfuture.cc/schema/v2.8.json",
"http://ddns.newfuture.cc/schema/v2.8.json",
"./schema/v2.8.json"
]
},
"id": {
"$id": "/properties/id",
"type": "string",
"type": [
"string",
"null"
],
"title": "ID or Email",
"description": "DNS服务API认证的ID或者邮箱"
},
Expand All @@ -29,7 +34,7 @@
"$id": "/properties/dns",
"type": "string",
"title": "DNS Provider",
"description": "dns服务商:阿里为alidns,DNS.COM为dnscom,DNSPOD国际版为(dnspod_com),cloudflare,HE.net为he",
"description": "dns服务商:阿里为alidns,DNS.COM为dnscom,DNSPOD国际版为(dnspod_com),cloudflare,HE.net为he,华为DNS为huaweidns,自定义回调为callback",
"default": "dnspod",
"examples": [
"dnspod",
Expand All @@ -42,7 +47,9 @@
"cloudflare",
"dnspod_com",
"dnscom",
"he"
"he",
"huaweidns",
"callback"
]
},
"ipv4": {
Expand All @@ -55,7 +62,7 @@
"$id": "/properties/ipv4/items",
"title": "ipv4 domain for DDNS",
"type": "string",
"pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,18}$",
"pattern": "^(?:\\*\\.)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,18}$",
"examples": [
"newfuture.cc",
"ipv4.example.newfuture.cc"
Expand All @@ -72,7 +79,7 @@
"$id": "/properties/ipv6/items",
"title": "The ipv6 domain for DDNS",
"type": "string",
"pattern": "^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}$",
"pattern": "^(?:\\*\\.)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,18}$",
"examples": [
"newfuture.cc",
"ipv6.example.newfuture.cc"
Expand All @@ -84,8 +91,19 @@
"type": [
"string",
"integer",
"boolean"
"boolean",
"array"
],
"items": {
"type": [
"string",
"integer"
],
"minimum": 0
},
"uniqueItems": true,
"minItems": 1,
"minimum": 0,
"title": "IPv4 address Setting",
"description": "本机 IPv4 获取方式设置",
"default": "default",
Expand All @@ -103,8 +121,19 @@
"type": [
"string",
"integer",
"boolean"
"boolean",
"array"
],
"items": {
"type": [
"string",
"integer"
],
"minimum": 0
},
"uniqueItems": true,
"minItems": 1,
"minimum": 0,
"title": "IPv6 address Setting",
"description": "本机 IPv6 获取方式设置",
"default": "default",
Expand Down Expand Up @@ -144,16 +173,42 @@
"127.0.0.1:1080;DIRECT"
]
},
"debug": {
"$id": "/properties/debug",
"type": "boolean",
"title": "Enable Debug Mode",
"description": "是否启用调试模式显示更多信息",
"default": false,
"cache": {
"$id": "/properties/cache",
"type": [
"string",
"boolean"
],
"title": "Enable Cache",
"description": "是否启用缓存记录以避免频繁更新",
"default": true,
"examples": [
true,
false,
true
"/path/to/cache/ddns.cache"
]
},
"log": {
"$id": "/properties/log",
"type": "object",
"title": "Log Config",
"description": "日志配置,支持自定义日志级别和输出位置。可通过命令行 --log.level, --log.file 或环境变量 DDNS_LOG_LEVEL, DDNS_LOG_FILE 设置。",
"properties": {
"level": {
"type": "string",
"title": "Log Level",
"description": "日志级别,如 DEBUG、INFO、WARNING、ERROR、CRITICAL",
"default": "INFO",
"enum": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
},
"file": {
"type": ["string", "null"],
"title": "Log Output File",
"description": "日志输出文件路径,留空或为null时输出到控制台"
}
},
"required": [],
"additionalProperties": false
}
},
"required": [
Expand Down
Loading
Loading