- 网络
- CLI
【免费下载链接】DDNS
🌐自动更新域名解析到本机IP,支持dnspod,阿里DNS,CloudFlare,华为云,DNSCOM...
本文基于 DDNS 仓库中西部数码服务商的官方文档与实现源码,系统讲解 West.cn / 三五互联(35.cn)动态 DNS 记录的完整配置方法,涵盖域名认证与账号认证两种凭据获取流程、全部配置参数及解析线路代码,并结合 west provider 源码 深入剖析其域名自动拆分、404 重试与 DDNS 更新接口的底层调用逻辑。读完本文,你可以直接复制可运行的 JSON 配置完成接入,并能读懂 WestProvider 每一次 API 请求的实际构造过程。
一、概述:west 与 35cn 两个标识对应同一套 API
西部数码(west.cn)是中国知名的域名服务商,提供域名注册、DNS 解析等服务。DDNS 项目通过其dnsrec.updateDDNS 接口实现记录管理,支持将域名解析自动更新到本机 IP。
从服务商注册表 ddns/provider/init.py 可以看到,西部数码实际注册了三个可用的dns标识:
# west.cn "west": WestProvider, "west_cn": WestProvider, # 兼容west.cn "35cn": WestProvider, # 三五互联 (使用相同API)即west、west_cn(兼容别名)、35cn均映射到同一个 WestProvider 类。三五互联(35.cn)与西部数码共用同一套 API,区别仅在于 API 端点地址不同,可通过dns参数或endpoint参数切换,详见 docs/providers/README.md 中的服务商总表。
二、认证信息:两种认证方式及凭据获取
西部数码支持两种认证方式,源码层面由_get_auth_params根据id是否存在来自动区分:
def _get_auth_params(self): if self.id: # 账号认证: id 是用户名, token 是 API 密码的 MD5 return {"username": self.id, "apikey": self.token} else: # 域名认证: 仅 token (apidomainkey) return {"apidomainkey": self.token}1. 域名认证方式(推荐)
使用域名管理密码进行认证,只需要token(apidomainkey),不需要填写id。
凭据获取步骤:
- 登录西部数码会员中心;
- 进入「域名管理」> 选择域名 >「管理密码」;
- 复制APIkey(32 位 MD5 值),这是域名管理密码的 MD5 哈希值。
{ "dns": "west", "token": "ec4c66e34561428b2e9ad65048f9bsed" // 域名 APIkey }为什么推荐这种方式?域名认证只需要一个 32 位密钥,不涉及账号凭据,配置更简单且权限范围限定在单个域名。从 源码校验逻辑 看,WestProvider 重写了基类的_validate:只强制要求token非空(缺失时抛出token (apidomainkey or apikey) must be configured),id可以为None——这正是与大多数要求id+token双必填服务商的差异点:
def _validate(self): """West.cn supports two authentication methods, so id is optional for domain auth.""" if not self.token: raise ValueError("token (apidomainkey or apikey) must be configured") if not self.endpoint: raise ValueError("API endpoint must be defined in {}".format(self.__class__.__name__))2. 账号认证方式
使用会员账号和 API 密码进行认证,此时id填写会员账号,token填写 API 密码的 32 位 MD5 值。
凭据获取步骤:
- 登录西部数码会员中心;
- 进入「账号管理」>「API 接口设置」;
- 设置 API 密码;
id填写会员账号用户名(测试用例确认支持邮箱形式、纯数字形式的账号);token填写 API 密码的 32 位 MD5 值。
{ "dns": "west", "id": "your_username", // 会员账号 "token": "md5_of_your_api_password" // API密码的MD5值 }账号认证模式下,每次请求会携带username+apikey两个参数,权限覆盖账号下所有域名。
三、完整配置示例
域名认证方式
{ "$schema": "https://ddns.newfuture.cc/schema/v4.1.json", "dns": "west", "token": "ec4c66e34561428b2e9ad65048f9bsed", "index4": ["url:http://api.ipify.cn", "public"], "index6": "public", "ipv4": ["ddns.example.com"], "ipv6": ["ipv6.example.com"], "ttl": 900 }账号认证方式
{ "$schema": "https://ddns.newfuture.cc/schema/v4.1.json", "dns": "west", "id": "your_username", "token": "md5_of_your_api_password", "index4": ["url:http://api.ipify.cn", "public"], "index6": "public", "ipv4": ["ddns.example.com"], "ipv6": ["ipv6.example.com"], "ttl": 900 }三五互联(35.cn)配置
三五互联使用相同的 API,只需将dns参数改为35cn,或通过endpoint参数显式指定 API 地址:
{ "$schema": "https://ddns.newfuture.cc/schema/v4.1.json", "dns": "35cn", "token": "your_apidomainkey", "endpoint": "https://api.35.cn/API/v2/domain/dns/", "ipv4": ["ddns.example.com"] }WestProvider 的默认端点是https://api.west.cn/API/v2/domain/dns/(类属性定义)。endpoint的覆盖逻辑继承自基类SimpleProvider.__init__:构造时若传入了非空endpoint参数,会实例级覆盖类默认值,因此「dns: west+ 自定义 endpoint」与「dns: 35cn」两种写法等价。
参数说明
| 参数 | 说明 | 类型 | 取值范围/选项 | 默认值 | 参数类型 |
|---|---|---|---|---|---|
| dns | 服务商标识 | 字符串 | west、west_cn、35cn | 无 | 服务商参数 |
| id | 会员账号 | 字符串 | 账号认证时必填 | 无 | 服务商参数 |
| token | 认证密钥 | 字符串 | apidomainkey 或 MD5(API密码) | 无 | 服务商参数 |
| endpoint | API地址 | 字符串 | 自定义API端点 | 西部数码 | 服务商参数 |
| index4 | IPv4 来源 | 数组 | 参考配置 | default | 公用配置 |
| index6 | IPv6 来源 | 数组 | 参考配置 | default | 公用配置 |
| ipv4 | IPv4 域名 | 数组 | 域名列表 | 无 | 公用配置 |
| ipv6 | IPv6 域名 | 数组 | 域名列表 | 无 | 公用配置 |
| line | 解析线路 | 字符串 | 参考下方 | 默认 | 服务商参数 |
| ttl | TTL 时间 | 整数(秒) | 60 ~ 86400 | 900 | 服务商参数 |
| proxy | 代理设置 | 数组 | 参考配置 | 无 | 公用网络 |
| ssl | SSL 验证方式 | 布尔/字符串 | "auto"、true、false | auto | 公用网络 |
| cache | 缓存设置 | 布尔/字符串 | true、false、filepath | true | 公用配置 |
| log | 日志配置 | 对象 | 参考配置 | 无 | 公用配置 |
参数类型说明:
- 公用配置:所有支持的DNS服务商均适用的标准DNS配置参数
- 公用网络:所有支持的DNS服务商均适用的网络设置参数
- 服务商参数:当前服务商支持,值与当前服务商相关
关于ttl的适用前提需要特别说明:从 schema/v4.1.json 的通用定义看,ttl的默认值为null(表示读取 DNS 服务商自身的默认策略),西部数码文档建议取值 60 ~ 86400 秒、推荐900。而从 west.py 源码注释 看,ttl参数在dnsrec.update接口的请求体中并未被使用——即 TTL 实际由西部数码控制台的域名解析设置决定,该参数在此服务商下主要是为保持配置格式通用而保留的。
公用配置项取值速查
结合 docs/config/json.md 中的通用定义,上述公用参数在西部数码场景下的完整取值为:
- index4 / index6:支持
false(禁止更新对应类型记录)、数字(第 N 个网卡)、"default"(默认出口 IP)、"public"(API 查询公网 IP)、"url:http..."、"regex:xxx"、"cmd:xxx"、"shell:xxx",可写成数组按顺序回退; - proxy:支持单个代理地址、
"DIRECT"强制直连、"SYSTEM"系统代理、数组回退链; - ssl:
"auto"(自动降级)、true(强制验证)、false(不验证)、或自定义 CA 证书路径; - cache:
true启用(临时目录ddns.{hash}.cache)、false禁用、或自定义缓存文件路径; - log:对象,支持
level(默认INFO)、file、format、datefmt字段。
四、line 参数与解析线路代码
line参数指定 DNS 解析线路,西部数码支持的线路代码如下,配置时直接填入代码字符串:
| 线路代码 | 说明 |
|---|---|
| (空) | 默认线路 |
| LTEL | 中国电信 |
| LCNC | 中国联通 |
| LMOB | 中国移动 |
| LEDU | 中国教育网 |
| LSEO | 搜索引擎 |
| LFOR | 境外访问 |
从 west.py 请求构造逻辑 看,line只有在显式配置时才会以record_line字段附加到 API 请求体中,不配置则走西部数码的默认线路:
# Add line if specified if line: params["record_line"] = line单元测试 test_set_record_with_line 验证了line="LTEL"时请求体中确实包含record_line: "LTEL"。
五、源码解析:WestProvider 的记录更新机制
WestProvider 继承的是简单基类 SimpleProvider,只实现一个set_record方法,因为西部数码的dnsrec.update接口本身就是「存在则更新、不存在则创建」的 upsert 语义,不需要像标准 BaseProvider 那样先查 zone_id、再查 record_id、再分流到更新/创建两条链路。
域名拆分策略:三级解析
set_record是核心入口,处理域名拆分的优先级为:
- 显式分隔符(
~或+):域名中含~或+时直接按分隔符拆成「子域名 + 主域名」,只尝试这一次组合。例如a.b.c~example.com拆为子域a.b.c与主域example.com。这个能力在 基类文档的调用流程图 中也有体现(「快速解析 是否包含 ~ 或 + 分隔符?」分支)。测试用例 test_full_workflow_with_multilevel_subdomain 验证了多级子域a.b.c~example.com的拆分结果; - 最长子域到最短的逐级试探:对
ipv6.ddns.test.com这类多层域名,代码从最长子域开始逐段回退——先试ipv6.ddns+test.com,若 API 返回 404(域名未找到)再试ipv6+ddns.test.com,依次递减(源码 L99-L112); - 兜底根域:若域名只有两段(如
example.com),或上述试探全部 404,则以hostname="@"(根域记录)+ 完整域名作为最后一次尝试。
404 触发回退的关键在于_try_update的三态返回值设计:
| API 响应 code | 返回 | 含义 |
|---|---|---|
200 | True | 更新成功,日志记录record_id |
404 | None | 域名未找到,交给外层尝试下一组合 |
| 其他 | False | 认证失败等业务错误,直接终止 |
单元测试 test_set_record_domain_not_found_fallback 精确复现了这个流程:mock 的第一次调用返回code=404,第二次返回code=200,最终set_record返回True且_http被调用了 2 次。
API 请求体构造
每次更新实际发出的是一条 form 表单 POST 请求(content_type = TYPE_FORM,见 类属性),请求体字段为:
| 字段 | 值 | 说明 |
|---|---|---|
act | dnsrec.update | 固定动作标识 |
domain | 主域名 | 如example.com |
hostname | 子域名或@ | 根域记录用@ |
record_value | IP 地址 | A 记录为 IPv4,AAAA 记录为 IPv6 |
apidomainkey或username+apikey | 凭据 | 按认证模式二选一 |
record_line | 线路代码 | 仅配置line时出现 |
响应成功后会记录Record updated successfully: www.example.com (id=118610345)这样的日志(源码 L148-L150),其中的record_id来自响应的body.record_id字段。另外 源码 L82 会对输入域名统一转小写,测试 test_set_record_domain_lowercase 验证了WWW.EXAMPLE.COM会被规范为小写请求。
与主流程的衔接
DDNS 主循环在 ddns/main.py 中调用服务商:
result = dns.set_record( domain, address, record_type=record_type, ttl=config.ttl, line=config.line, **config.extra )也就是说,ipv4/ipv6配置中的每个域名都会独立走一次上述拆分与更新流程;config.line、config.ttl等配置字段通过同一入口透传到 WestProvider。缓存命中(地址未变化)时会在调用set_record之前就跳过,避免无意义的 API 请求。
敏感信息保护
基类_mask_sensitive_data会对日志中的 token 做打码处理(保留首尾 2 位、中间以***替代,同时处理 URL 编码形态),因此调试日志中不会出现完整的 APIkey 明文。
六、故障排除
调试模式
启用调试日志查看每一次 API 请求与响应详情:
ddns -c config.json --debug--debug参数在 ddns/config/cli.py 中定义(debug mode [开启调试模式])。调试时重点观察:域名拆分的每次试探(Trying: %s + %s的 debug 日志)、code=404回退、以及认证参数的打码输出。
常见问题
- 认证失败:检查 APIkey 或账号密码是否正确,确认
token是 32 位 MD5 值。若使用了域名认证却多填了id,请求会误走账号认证模式(携带username+apikey),这也是认证失败的一个隐蔽原因——域名认证时切勿填写id; - 域名未找到:确保域名已在西部数码账号下托管,配置拼写无误。多级域名的 404 回退机制只会在本账号已托管的主域组合上成功;
- 记录创建失败:检查子域名是否有冲突记录,TTL 设置是否合理;
- 请求频率限制:降低请求频率(可通过内置 interval 或调度器控制同步间隔)。
测试用例定位问题
仓库内置了 tests/test_provider_west.py 完整测试套件(mock 了_http,不产生真实 API 调用),可用于理解预期行为或本地复现验证:
- 认证参数构造:test_get_auth_params_domain_auth 验证域名认证只发
apidomainkey;test_get_auth_params_account_auth 验证账号认证发username+apikey,且两种模式互不串用; - 校验规则:test_validate_missing_token 确认缺失
token时抛出含token字样的ValueError; - 分隔符与回退:
~/+分隔符测试(L206-L228)、404 回退测试(L243-L256)、小写化测试(L230-L241); - 注册表别名:test_35cn_alias_registered 等确认
west、west_cn、35cn三个标识都能解析到 WestProvider。
运行方式参考 tests/README.md 中的测试说明,通常以python -m unittest tests.test_provider_west形式执行。
七、支持与资源
- 西部数码官网(www.west.cn)及其会员中心:域名认证与账号认证的凭据均在此获取;
- 西部数码 API 文档(apipost 平台在线文档):
dnsrec.update接口的完整字段定义以该文档为准; - 三五互联官网(www.35.cn):与西部数码共用 API,配置方式见上文「三五互联配置」;
- 仓库内对应中文文档为 docs/providers/west.md,英文版即本文所依据的 docs/en/providers/west.md,公共参数详细定义见 docs/config/json.md。
建议:推荐使用域名认证方式(apidomainkey),配置更简单且更安全——凭据范围锁定在单个域名,且不暴露会员账号。
- 网络
- CLI
【免费下载链接】DDNS
🌐自动更新域名解析到本机IP,支持dnspod,阿里DNS,CloudFlare,华为云,DNSCOM...
相关推荐
DDNS 配置 HE.net(Hurricane Electric)动态 DNS 完整指南:认证、参数与响应码解析
DDNS 配置 HE.net(Hurricane Electric)动态 DNS 完整指南:认证、参数与响应码解析 本篇指南围绕 DDNS 项目中 HE.net
网络CLIDDNS 接入阿里云 DNS(AliDNS):AccessKey 认证、配置参数与源码级实现解析
DDNS 接入阿里云 DNS(AliDNS):AccessKey 认证、配置参数与源码级实现解析 本篇指南讲解如何在 DDNS 项目中接入阿里云 DNS(Ali
网络CLIDDNS 中 DNSPod(dnspod.cn)配置指南:认证方式、完整参数与 API 实现解析
DDNS 中 DNSPod(dnspod.cn)配置指南:认证方式、完整参数与 API 实现解析 本文围绕 DDNS 仓库 https://link.gitco
网络CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考