curl 命令行 `--dns-servers` 选项完全指南:用 c-ares 自定义 DNS 服务器与端口
curl 命令行--dns-servers选项完全指南用 c-ares 自定义 DNS 服务器与端口【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl--dns-servers是 curl 提供的覆盖系统默认 DNS 解析目标的高级选项它允许用户在命令行直接指定一个或多个 DNS 服务器含自定义端口常用于调试、绕过错误的上游 DNS、或对接内网解析环境。本文以 curl 仓库官方手册文档 docs/cmdline-opts/dns-servers.md 为核心结合命令解析、libcurl 选项设置与 c-ares 解析器三层源码讲透该选项的语法、适用范围、底层实现与排错思路。一、选项概览它能做什么从官方选项定义文档来看--dns-servers的核心作用非常聚焦设置要使用的 DNS 服务器列表以取代系统默认配置。IP 地址列表应以逗号分隔也支持可选端口号以冒号附加在 IP 地址后。即它控制的是 curl 内部做主机名解析将主机名转换为 IP 地址这一环节使用的上游 DNS 服务器而非连接目标本身。该选项定义在 docs/cmdline-opts/dns-servers.md其 YAML 头元数据完整说明了关键属性字段取值含义Longdns-servers长选项名称Argaddresses需要一个服务器地址列表参数HelpDNS server addrs to use帮助信息中的一句话说明ProtocolsDNS作用于 DNS 解析过程Requiresc-ares仅在启用 c-ares 解析后端时可用Added7.33.0从该版本开始提供Categorydns属于 DNS 相关选项类别Multisingle非可累加选项重复指定时后值覆盖前值而非累积成列表二、前提条件必须在编译期启用 c-ares这是理解--dns-servers最重要的一步——它不是所有 curl 版本/发行版都携带的选项。curl 支持多种主机名解析后端阻塞式、线程式、c-ares而只有 c-ares 后端才能让应用自定义 DNS 服务器。选项元数据中的Requires: c-ares已明确这一点。从仓库构建配置可以印证CMake 构建中默认关闭需显式开启。见 CMakeLists.txt 第 184 行的option(ENABLE_ARES Enable c-ares support OFF)开启后它会通过 CMake/FindCares.cmake 定位系统 c-ares并要求链接CURL::cares。autotools 构建中则通过--enable-ares启用见 configure.ac 第 4380-4381 行启用成功后会AC_DEFINE(USE_RESOLV_ARES, 1, ...)此时解析后端报告为c-ares。c-ares 版本有硬性下限。源码 lib/vdns/asyn-ares.c 第 63-65 行强制要求ARES_VERSION 0x011000即 c-ares 1.16.0 及以上否则编译直接报错。验证当前构建是否支持该选项可在交互使用前执行curl --version检查输出中是否包含c-ares或直接运行curl --help all | grep dns-servers三、命令语法与参数格式详解完整语法curl --dns-servers addresses [其它选项] URL参数addresses是一个由逗号分隔的 DNS 服务器地址列表官方文档给出了两个示例# 使用两个 IPv4 DNS 服务器默认 53 端口 curl --dns-servers 192.168.0.1,192.168.0.2 $URL # 使用一个带自定义端口的 DNS 服务器 curl --dns-servers 10.0.0.1:53 $URL格式要点可归纳为多服务器用英文逗号分隔如--dns-servers 8.8.8.8,1.1.1.1。curl 会按文档语义将其理解为有序的服务器列表同时从 c-ares 的ares_set_servers_ports_csv调用看该函数本身也接受一个 CSV 格式字符串见下文源码解析两者格式完全对应。可选端口用英文冒号追加ip:port形式如10.0.0.1:5353。这与默认 53 端口可省略的常见 DNS 配置习惯一致。支持 IPv6 地址场景地址格式由 c-ares 解析器按 CSV 规则处理结合同目录的 dns-ipv6-addr.md 等选项可知curl 的 DNS 定制一族对 v4/v6 环境均有覆盖。涉及 IPv6 时需按 c-ares 的 CSV 规则书写端口分隔同样是冒号。与配置文件 / 变量写法该选项也可以写入 curl 配置文件--config指定的文件或~/.curlrc行内写法与命令行一致# ~/.curlrc 示例 dns-servers 192.168.0.1,192.168.0.2配置文件的通用解析规则参见 docs/cmdline-opts/config.md。四、一条命令的完整调用链源码级解析--dns-servers从命令行到真正生效跨越了三个层次仓库源码完整保留了这条链路。第 1 层命令行参数解析在命令行工具源码 src/tool_getparam.c 第 120 行注册了选项名{dns-servers, ARG_STRG, , C_DNS_SERVERS}表明它是一个字符串参数第 2536-2542 行则做了关键守卫case C_DNS_SERVERS: /* --dns-servers */ if(!curlinfo-ares_num) /* c-ares is needed for this */ err PARAM_LIBCURL_DOESNT_SUPPORT; else /* IP addrs of DNS servers */ err getstr(config-dns_servers, nextarg, DENY_BLANK);可见工具会先检查运行时探测到的 c-ares 支持情况curlinfo-ares_num。若当前链接的 libcurl 未启用 c-ares则直接返回PARAM_LIBCURL_DOESNT_SUPPORT命令行会拒绝接受该选项并给出相应错误提示而不是默默忽略。DENY_BLANK表示不允许空字符串参数。第 2 层映射为 libcurl 传输选项解析得到字符串后src/config2setopts.c 第 1062 行在构建 easy 句柄时把它转换为 libcurl 选项MY_SETOPT_STR(curl, CURLOPT_DNS_SERVERS, config-dns_servers);程序化使用 libcurl 的开发者也可直接设置CURLOPT_DNS_SERVERS字符串类型选项见 lib/easyoptions.c 第 83 行的类型登记。第 3 层libcurl 存储与 c-ares 落地在 lib/setopt.c 第 2248-2250 行CURLOPT_DNS_SERVERS的分支被#ifdef USE_RESOLV_ARES包裹#ifdef USE_RESOLV_ARES case CURLOPT_DNS_SERVERS: return Curl_setstropt(data, STRING_DNS_SERVERS, ptr);这从库层面再次印证编译时未定义USE_RESOLV_ARES即未启用 c-ares的 libcurl 根本不接受该选项此时无论命令行还是curl_easy_setopt都无法使用自定义 DNS 服务器。真正把服务器列表下发给 c-ares 的逻辑在 lib/vdns/asyn-ares.c 的async_ares_set_dns_servers()第 658-693 行。该函数在创建 c-ares channel 时被调用第 165 行核心是const char *servers CURL_EASY_STR(data, STRING_DNS_SERVERS); ... if(ares ares-channel) ares_result ares_set_servers_ports_csv(ares-channel, servers);即最终调用 c-ares 的ares_set_servers_ports_csv()把逗号分隔的地址列表含可选端口解析并注入 ares channel。代码同时把 c-ares 返回码映射为 curl 错误码c-ares 返回码curl 结果ARES_SUCCESSCURLE_OK成功ARES_ENOMEMCURLE_OUT_OF_MEMORYARES_ENOTINITIALIZED/ARES_ENODATA/ARES_EBADSTR等CURLE_BAD_FUNCTION_ARGUMENT并打印bad servers set调试信息这意味着非法格式的服务器列表会在选项生效检查阶段被拒绝返回参数错误而非在解析时静默失败。调试彩蛋CURL_DNS_SERVER在同文件第 666-669 行还存在一个仅供调试构建DEBUGBUILD使用的环境变量覆盖机制#ifdef DEBUGBUILD if(getenv(CURL_DNS_SERVER)) servers getenv(CURL_DNS_SERVER); #endif也就是说在开启 debug 的 curl 构建中可通过设置CURL_DNS_SERVER环境变量临时覆盖命令行传入的服务器列表方便测试人员在不改动参数的情况下切换上游 DNS。五、与相近 DNS 定制选项的关系--dns-servers属于 curl 的 DNS 定制选项族使用时常与以下选项区分或搭配它们定义于同目录--dns-interface指定发送 DNS 查询所使用的本地网络接口同样要求 c-ares对应CURLOPT_DNS_INTERFACE。--dns-ipv4-addr / --dns-ipv6-addr指定绑定到 DNS 套接字上的本地 IPv4/IPv6 地址源地址对应CURLOPT_DNS_LOCAL_IP4/CURLOPT_DNS_LOCAL_IP6。--doh-url使用 DNS-over-HTTPS 方式解析走 HTTPS 通道而非传统 DNS 服务器不要求 c-ares。--resolve为指定主机名静态固定解析结果可含端口优先级高于任何 DNS 服务器适合就是要连到某个特定 IP的场景。四者的关系可以这样理解--resolve是绕过解析、直接钉死结果--dns-servers是替换查询目标--dns-interface/--dns-ipv4-addr/--dns-ipv6-addr是控制查询报文从哪个本地出口发出。底层上四个 c-ares 相关选项在 lib/vdns/asyn-ares.c 的 channel 初始化流程中按顺序依次应用第 165-179 行互不冲突。在 lib/vdns/asyn-ares.c 第 652-657 行的注释中还揭示了两种特殊场景应用通过CURLOPT_DNS_SERVERS传入NULL表示清除先前设定并重建 ares channel而在 channel 惰性初始化且值为NULL无偏好时不重置既有 channel。这解释了为何在同一个 easy 句柄生命周期内反复设置/清除该选项是安全的。六、常见问题与排查思路Q1提示选项不支持 /curl --help中看不到该选项大概率是链接的 curl 未启用 c-ares。按第二节方法重新编译CMake 开启ENABLE_ARES、autotools 加--enable-ares或换用带 c-ares 的发行包。可先curl --version确认。Q2传入的服务器列表报参数错误确认列表格式纯逗号分隔、端口用冒号、无多余空白、每个地址本身合法。底层ares_set_servers_ports_csv解析失败会映射为CURLE_BAD_FUNCTION_ARGUMENT见第四节错误映射表。Q3指定后仍走了系统 DNS先确认命中 c-ares 后端而不是线程式/阻塞式解析器其次确认没有--resolve或 DoH--doh-url等更高优先级机制在起作用。Q4多个 DNS 服务器如何选择列表以逗号分隔作为整体传入 c-ares由 c-ares 按自身策略使用这些服务器curl 侧不额外做负载均衡因此顺序即策略的期望应由 c-ares 行为决定不同 c-ares 版本对服务器选择/失败切换的策略可能存在差异。七、速查与延伸选项手册原文docs/cmdline-opts/dns-servers.md命令行帮助清单src/tool_listhelp.c 第 158 行参数解析与 c-ares 守卫src/tool_getparam.c 第 120、2536-2542 行选项到 libcurl 的映射src/config2setopts.c 第 1062 行libcurl 选项存储lib/setopt.c 第 2248-2250 行、lib/easyoptions.c 第 83 行c-ares 落地实现lib/vdns/asyn-ares.c 第 658-693 行构建开关CMakeLists.txt 第 184 行、configure.ac 第 4380-4381 行、CMake/FindCares.cmake一句话总结--dns-servers的威力在于把用哪台 DNS 服务器解析的决定权从操作系统交还到 curl 使用者手中但其可用性的根基是 c-ares 编译支持——先确认后端再关注列表格式最后借助错误映射快速定位问题。【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →