资讯动态

容器之间互相找不到:名字解析到底在哪一步断的

发布时间:2026/10/16 14:29:19 来源:尧图企业网站定制
授权与合规声明本文全部操作对象均为自建隔离靶场本机容器或隔离虚拟机涉及安全测试的环节必须以取得合法授权为前提。未经授权的渗透测试违反《中华人民共和国网络安全法》与《刑法》相关条款须承担相应法律责任。本文只讲环境配置、版本对照与靶场隔离不含任何攻击步骤、利用载荷与绕过手法请勿将文中环境指向任何非自有系统。一、现象三种连不上长得一样1.1 现场一套两三个容器的靶场在隔离环境里用容器搭一套靶场是很常见的做法一个容器跑 Web 应用另一个容器跑数据库可能再加一个跑缓存。它们各自都能正常启动状态栏里一排都是运行中。真正让人卡住的时刻通常出现在你从一个容器里向另一个容器发请求的时候——请求发出去了对方却没有回应。⚠️代码待验证# 示意两个容器都跑起来之后从其中一个去连另一个本机无 docker未实测dockerrun-d--nameapp1$IMAGEdockerrun-d--nameapp2$IMAGEdockerexec-itapp1你的客户端命令http://app2:端口/1.2 三种连不上症状几乎一样第一个坑是连不上不是一个现象而是一类现象。至少三种不同的故障都会表现为我这边发不出、对方那边没反应第一种地址对但连不通。用名字不行换成对方的容器 IP 也不行。第二种名字不行IP 可以。用名字发不出去把这串名字换成 IP 立刻就好。第三种时好时坏。同一个名字有时候解析得出来有时候解析不出来。这三种如果只看失败了这一层看不出区别。它们唯一的共通点是你手里拿的是一个名字而最终发包用的是一个 IP 地址。名字到地址之间少了一环或者地址到对方之间少了一环最后都长成同一副样子。这里还要先打消一个常见的预设不一定是谁配错了。容器网络的相当一部分行为是默认设定——不写网络就落到一个默认网络上写了自定义网络就是另一套名字规则。也就是说很多连不上不是配置写错而是你用了哪一套默认值的自然结果。先把默认值是什么弄清楚比急着改配置有效得多。1.3 本篇的支点与边界本文的全部论证压在一句话上名字能解析和连接能到达是两个独立的判断一个推不出另一个。先把边界划清容器编排里的启动顺序谁先起、要不要等依赖是另一条轴本文只谈名字能不能解析出来不展开顺序把容器端口发布到宿主机是另一条路本文只在需要区分时提一句宿主机自身的 DNS 解析与/etc/hosts机制是另一个题目本文不重复展开只讲容器这一侧看到的东西。本章可以带走的一句三种连不上长得一样是因为它们都被压在了失败了这一层先把名字解析与连接可达分开才是往下走的起点。二、先把两件事分开名字解析与连接可达2.1 名字解析把名字换成地址的那一段你在容器里写下一个名字程序要做的第一件事是把这个名字翻译成一个 IP 地址。这一步叫名字解析name resolution。它不是应用自己算出来的而是走一套固定的解析流程先看本机的解析配置指向哪里再把查询交给对应的解析服务。这一步的产物只有一个一个地址或者找不到。它不产生任何网络连接也不代表对方是否在等你。2.2 连接可达拿到地址之后的那一段拿到地址之后才是第二步从你的容器向这个地址发起连接。这一步要成立需要网络层的条件——两个容器得处在能互相看见的位置上并且对方确实在等这个连接。所以两步的判据完全不同前者的判据是有没有一条解析路径能把名字换成地址后者的判据是这个地址在你当前所处的网络里是不是真的能到。一个容易串线的点是“可达不等于对方会应答”。网络能到只说明包能从你这边出去、走到对方那个地址对方那一侧有没有程序在等这个连接是它自己的状态。所以名字成功、连接失败这类现象可能落在可达这一层也可能落在对方那一侧还没有程序在应答上——后一种属于另一条轴本文不展开。2.3 两者失败的样子为什么不同你看到的现象名字解析连接可达名字失败、换成 IP 也失败可能成立也可能不成立不成立名字失败、换成 IP 成功不成立成立名字成功、连接失败成立不成立把名字换成 IP 再试一次是这条轴上性价比最高的一次动作它一刀就把解析和可达分开了。名字和 IP 都不行问题在可达IP 行、名字不行问题就在解析。至于换成哪个 IP官方给过口径容器每接入一个 Docker 网络就会从该网络的子网里分到一个地址DK04。也就是说同一个容器身上可能有多个地址分别属于它接入的每一个网络。用 IP 试的时候要确认用的是和目标容器处于同一个网络的那个地址。本章可以带走的一句名字解析只负责把名字换成地址连接可达只负责这个地址能不能到把名字换成 IP 重试一次一刀就能把两者分开。三、默认 bridge 为什么不能按名字找3.1 默认 bridge 是什么如果你从没显式指定过网络那起出来的容器大概率都在同一个网络上。官方对它的描述是When Docker Engine on Linux starts for the first time, it has a single built-in network called the “default bridge” network. When you run a container without the--networkoption, it is connected to the default bridge.DK03——Linux 上的 Docker Engine 第一次启动时会有一个唯一的内置网络叫default bridge不带--network选项运行的容器就接在它上面。也就是说不写网络不等于没有网络而是都进了同一个默认网络。3.2 官方原句它们不能按名字互相引用那么接在同一个默认网络上的容器能不能互相按名字找到官方给的是否定答案They cannot refer to each other by name.DK01——它们不能按名字互相引用。这句话出现在User-defined networks一节里紧邻的前一句还说明它们确实有不受限制的网络访问但那个访问建立在容器 IP 地址之上。containers attached to the default bridge network have unrestricted network access to each other using container IP addresses.DK01——默认 bridge 上的容器之间用容器 IP 地址可以不受限制地互相访问。能互相访问但不能按名字访问——这就是名字不行、IP 可以这一种现象的来源。3.3 那它们靠什么互访这就解释了为什么第二种现象那么典型默认 bridge 上名字这条路本来就不存在而IP 这条路是通的。所以你在上面用名字去连失败是这类网络的既定行为而不是你把配置写错了。官方文档在这里只给了结论没有展开默认网络里为什么没有一张名字表的机制细节。本文不替它补这套推导——本文未核到一手依据的部分就停在结论这一层默认网络上可以按 IP 互访不能按名字互访。⚠️代码待验证# 示意默认 bridge 上按名字与按 IP 各试一次本机无 docker未实测dockerrun-d--nameapp1$IMAGEdockerrun-d--nameapp2$IMAGEdockerexec-itapp1你的客户端命令http://app2:端口/# 按名字dockerexec-itapp1你的客户端命令http://app2的IP:端口/# 按 IP顺带看另一个容易被误判的地方宿主机自己的 hosts 条目也不会自动进到容器里。官方在Custom hosts一节写得明白Custom hosts, defined in/etc/hostson the host machine, aren’t inherited by containers.DK14——在宿主机的/etc/hosts里自定义的条目不会被容器继承。所以我在宿主机上把某个名字指向了某个 IP容器里却还是不行这件事同样是既定行为而不是解析服务坏了。容器里的/etc/hosts只有它自己的 hostname、localhost和几个常见条目DK14。本章可以带走的一句默认 bridge 上的容器可以按 IP 不受限制地互访但不能按名字互访宿主/etc/hosts的自定义条目也不会被容器继承这两条都不是配置错误。四、用户自定义网络里的 embedded DNS4.1 自定义网络能按名字了官方给出的对策是自建网络把一组需要互相访问的容器接到同一个自定义网络上。Once connected to a user-defined network, containers can communicate with each other using container IP addresses or container names.DK02——一旦接入用户自定义网络容器之间就可以用容器 IP 地址、或者用容器名互相通信。区别就在那个或者容器名上这正是默认 bridge 缺掉的那一半。可以把两类网络看成分工不同的两把钥匙默认 bridge 面向的是容器要能出网它的解析配置基本是把宿主那一套原样搬进容器自定义网络面向的是一组容器要互相说话它额外装了一个内嵌的解析服务专门回答这一组内部的名字。这也是为什么换个网络能修好一类问题却对另一类问题毫无作用。⚠️代码待验证# 示意建一个自定义网络把两个容器都接上去本机无 docker未实测dockernetwork create-dbridge my-netdockerrun-d--nameapp1--networkmy-net$IMAGEdockerrun-d--nameapp2--networkmy-net$IMAGEdockerexec-itapp1你的客户端命令http://app2:端口/4.2 两类容器两种 DNS 来源为什么加一个自定义网络名字就突然能用了关键在容器拿到的是哪一套解析配置。官方把两类情况并列写在一起Containers that attach to the default bridge network receive a copy of this file.DK05——接入默认 bridge 的容器收到的是宿主/etc/resolv.conf这份文件的一份副本。Containers that attach to a custom network use Docker’s embedded DNS server.DK06——接入自定义网络的容器用的是Docker 的 embedded DNS server。这个内嵌的解析服务会把外部的解析请求转发给宿主机上配置的 DNSThe embedded DNS server forwards external DNS lookups to the DNS servers configured on the host.DK06——embedded DNS server 会把外部的 DNS 查询转发给宿主机上配置的 DNS。也就是说外部域名的解析最终仍然落在宿主那一套配置上多出来的是容器之间的名字由这个内嵌服务自己回答。4.3 地址是127.0.0.11embedded DNS server 在容器里有一个固定的地址The embedded DNS server address is127.0.0.11. There is no IPv6 equivalent; the IPv4 address works even in IPv6-only containers.DK07——embedded DNS server 的地址是127.0.0.11没有 IPv6 的对应地址即使在 IPv6-only 的容器里这个 IPv4 地址也照样可用。官方还补了一句给那些需要在应用里写死 DNS 地址的场景如果应用要求一个显式的 DNS 服务器地址就用127.0.0.11DK07。这条很实用在自定义网络上名字到底交给了谁是可以验证的——去看容器里的解析配置指向哪里。4.4 多个上游时的行为差异最后一段差异最容易被忽略但它解释时好时坏。当配置了多个上游 DNS 服务器时两类网络的行为并不一样。默认 bridge 上Some resolvers query the servers in order. Others query them in parallel and use the first response received, even if that response is NXDOMAIN.DK08——默认 bridge 上由容器自己的解析库决定怎么查有的按顺序问有的并行问、并采用最先到达的那个响应哪怕那个响应是 NXDOMAIN查无此名。自定义网络上则是固定顺序On a custom network, Docker’s embedded DNS server queries upstream servers in order and stops after a successful response or an NXDOMAIN response.DK08——自定义网络上embedded DNS server按顺序查上游拿到一个成功响应、或者拿到 NXDOMAIN 就停下。前者把谁先回答交给了环境和实现后者把顺序固定在了内嵌服务里——这就是同一套上游配置在不同网络下表现不一致的原因之一。本章可以带走的一句自定义网络之所以能按名字找是因为容器用的是 Docker 的 embedded DNS server127.0.0.11而不是宿主机/etc/resolv.conf的副本配置了多个上游时两者的查询行为也不相同。五、--dns、--dns-search、--hostname、--alias各改什么5.1--dns与--dns-opt改的是问谁容器默认用的就是宿主机那套 DNS官方一句话说得清楚容器默认使用与宿主机相同的 DNS 服务器可以用--dns覆盖DK05。对--dns本身的描述是The IP address of a DNS server. To specify multiple DNS servers, use multiple--dnsflags. DNS requests will be forwarded from the container’s network namespace so, for example,--dns127.0.0.1refers to the container’s own loopback address.DK09——--dns给的是一个 DNS 服务器的 IP要用多个就写多个--dns解析请求是从容器的网络命名空间里发出去的所以--dns127.0.0.1指的是容器自己的回环地址不是宿主的。最后这半句值得记一下同一个127.0.0.1在宿主里和容器里指的不是同一个东西。--dns-opt改的是带着什么选项去问A key-value pair representing a DNS option and its value. See your operating system’s documentation forresolv.conffor valid options.DK11——它是一对键值表示一个 DNS 选项和它的值合法取值要看操作系统关于resolv.conf的文档。这里要克制本文不列具体选项名因为它们的合法取值由系统文档定义不是 Docker 这边规定的。⚠️代码待验证# 示意在启动时改写容器看到的 DNS 配置本机无 docker未实测dockerrun-d--nameapp1\--dnsDNS服务器A--dnsDNS服务器B\--dns-opt选项值\$IMAGE5.2--dns-search改的是补全时补什么--dns-search管的是另一件事——不完整的主机名在补全时按什么后缀去补A DNS search domain to search non-fully qualified hostnames. To specify multiple DNS search prefixes, use multiple--dns-searchflags.DK10——它是一个搜索域供查找非完全限定主机名时使用要指定多个搜索前缀就写多个--dns-search。这一条与能不能解析出某个完整名字是两回事它影响的是当你只写了一个短名字时解析器会拿哪些后缀去拼。5.3--hostname与--alias改的是我叫什么前面几个开关都在改问谁这两个改的是我自己叫什么。关于--hostnameThe hostname a container uses for itself. Defaults to the container’s ID if not specified.DK12——--hostname是容器给自己用的主机名不指定时默认取容器 ID。官方在别处也重复了这一点容器的 hostname 默认就是它在 Docker 里的容器 ID可以用--hostname覆盖DK12。而--alias加的是在网络里的别名且它出现在连接既有网络的场合When connecting to an existing network usingdocker network connect, you can use the--aliasflag to specify an additional network alias for the container on that network.DK13——用docker network connect连到一个既有网络时可以用--alias为容器在该网络上指定一个额外的网络别名。注意两个词additional额外的和on that network在那个网络上——它是加不是改而且只在指定的那个网络上生效。到这里可以把名字这件事拆成三种避免继续串线容器名是创建容器时给它起的名字官方说自定义网络上的容器可以用它互相通信DK02hostname是容器给自己用的主机名由--hostname控制默认取容器 IDDK12网络别名是--alias在某一个网络上额外加的名字DK13。三者各自落在不同位置上。要留意的另一点是它们都不改变容器接在哪张网上——换网络这件事靠的是--network或docker network connect。至于这几个名字分别由谁采纳、按什么次序回答本文未核到逐字说明就不往下推断了。⚠️代码待验证# 示意给容器起名字、以及在某个网络上加别名本机无 docker未实测dockerrun-d--nameapp1--hostnameapp1--networkmy-net$IMAGEdockernetwork connect--aliasdb-alias my-net app2dockerexec-itapp1cat/etc/resolv.conf本章可以带走的一句--dns与--dns-opt改问谁、带什么选项--dns-search改短名字怎么补全--hostname改容器自己叫什么默认是容器 ID--alias是在某个网络上额外加一个名字。完整版容器网络排障自查表这一章四个开关的改动点连同第四章127.0.0.11与两类 DNS 来源的对照汇总进资料包扫码即可获取六、按现象定位的顺序6.1 先问一句这个容器接在哪个网络上前五章讲完回到动作层面。第一步不是去翻配置文件而是先确认一件基础事实这两个容器是不是在同一个网络上。因为第三章和第四章的结论都建立在这上面——同一个默认 bridge 上名字不好使同一个自定义网络上名字好使不在同一个网络上名字和 IP 都可能不好使。一个容器可以同时接入多个网络也可以被docker network connect接进另一个网络官方在Connecting to multiple networks里把这比作给主机多插一根网线。所以接没接在同一个网这件事是要具体到网络名去核对的。⚠️代码待验证# 示意确认容器接了哪些网络、以及容器内的解析配置本机无 docker未实测dockerinspect-f{{json .NetworkSettings.Networks}}app1dockerexec-itapp1cat/etc/resolv.conf6.2 按现象定位的对照表看到的现象最可能的所在层先做什么为什么名字失败、换成 IP 也失败连接可达确认两个容器是否在同一网络、对方是否在等这个连接解析与可达都不成立先排除根本不在一张网名字失败、换成 IP 成功名字解析确认是不是都接在默认 bridge上默认 bridge 上容器不能按名字互相引用DK01名字失败、容器在自定义网络上名字解析确认两个容器是否接在同一个自定义网络自定义网络上的名字只在同一网络内有效DK02名字成功、连接失败连接可达确认对方那一侧是否已经在等这个连接解析已经完成问题在可达那一层外部域名失败、容器间名字正常上游 DNS看容器里/etc/resolv.conf与--dns设置外部查询由 embedded DNS 转发给宿主的 DNSDK06同一个外部名字时好时坏上游 DNS 顺序看是否配了多个上游、以及属于哪类网络两类网络在多上游时行为不同DK086.3 一条固定顺序以及本文不碰的部分把上面的表压成一条顺序先确认在不在同一张网 → 再用 IP 试一次分开两层 → 名字不行就去看是默认 bridge 还是自定义网络 → 外部名字不行再看上游 DNS 与两类网络的差异。这条顺序里每一步都指向一个可以核对的事实而不是一个猜测。再划一次边界启动顺序谁先起、要不要等依赖是另一条轴本文不展开它与名字能不能解析出来无关把端口发布到宿主机是另一条路本文只提一句、不再深入端口相关的读法是另外一个题目本文同样不展开。还有一点值得记住这条顺序是排除法不是找到一处改掉就好了。不少场景下你查完一圈会发现两边的默认值本来就在正常工作问题只是你在一张不提供名字的网络上找名字。把这种场景识别出来本身就是一个结论。本章可以带走的一句定位顺序是先看在同一张网没有 → 再按 IP 试一次分开两层 → 再分默认 bridge 与自定义网络 → 再看上游 DNS 与两类网络的差异每一步都落在一个可核对的事实上。七、收束7.1 回到标题那个问题回到最初那句两个容器互相找不到名字解析到底在哪一步断的。到这里可以按事实回答先分清断的是哪一层。如果按 IP 也通不了那断的不是名字解析而是连接可达——两个容器可能压根不在同一张网上。如果按 IP 通、按名字不通那才轮到名字解析而此时要看的是容器接在哪类网络上接在默认 bridge上容器之间本来就不能按名字互相引用DK01这不是配置错误。接在自定义网络上容器之间可以按 IP 或按容器名互相访问DK02因为此时容器用的是 Docker 的 embedded DNS server127.0.0.11DK07而不是宿主机/etc/resolv.conf的那份副本DK05。四个开关的归属也要摆正--dns、--dns-opt改的是问谁、带什么选项--dns-search改的是短名字怎么补全--hostname改的是容器自己叫什么默认是容器 IDDK12--alias是在某个网络上额外加一个名字DK13。它们都不改变容器接在哪张网络上这件事——而这件事才是能不能按名字找的开关。7.2 边界与待验证再补几句边界。本文涉及的全部docker命令本机没有 Docker 环境、未实测相应代码块一律保留待验证标记文中命令里的镜像名一律用$IMAGE这类占位符不写具体镜像与版本。容器编排里的启动顺序是另一条轴本文不展开端口发布的读法是另外一条轴本文不展开。全文不涉及任何攻击面也不描述任何利用方式。最后一句提醒本文引用的是 Docker 官方 Networking overview 在2026-10-15抓取的文本官方文档会更新遇到具体问题时以你所用版本对应的官方文本为准。本章可以带走的一句名字解析断在哪一步取决于容器接在哪张网上把两层分开、两张网分清这两件事做实绝大多数容器互相找不到都能落到一个可核对的事实上。容器网络现象对照卡把本文第六章的按现象定位对照表与第二、四章的两层划分、两类 DNS 来源做成一张可打印的卡片放在资料包里扫码即可获取附表 A本文引用事实与官方出处对照表#事实照抄口径可含英文原句出处文档名 章节号 链接核验日期本文位置DK01逐字默认 bridge 上的容器可用容器 IP 不受限制地互访“They cannot refer to each other by name.”Docker Docs · Docker Engine · Networking · Networking overview · User-defined networkshttps://docs.docker.com/engine/network/2026-10-15第 3、6、7 章DK02逐字“Once connected to a user-defined network, containers can communicate with each other using container IP addresses or container names.”同上 · User-defined networks2026-10-15第 4、6、7 章DK03逐字Linux 上 Docker Engine 首次启动时有唯一内置网络 “default bridge”不带--network的容器接在其上同上 · Container networks2026-10-15第 3 章DK04逐字容器从所接入网络的子网中分到一个 IP“A container receives an IP address out of the IP subnet of the network.”同上 · IP address and hostname2026-10-15第 2 章DK05逐字容器默认使用与宿主相同的 DNS 服务器可用--dns覆盖“Containers that attach to the default bridge network receive a copy of this file.”指宿主/etc/resolv.conf的副本同上 · DNS services2026-10-15第 4、5、7 章DK06逐字“Containers that attach to a custom network use Docker’s embedded DNS server.”且“The embedded DNS server forwards external DNS lookups to the DNS servers configured on the host.”同上 · DNS services2026-10-15第 4、6 章DK07逐字“The embedded DNS server address is127.0.0.11.”、“There is no IPv6 equivalent; the IPv4 address works even in IPv6-only containers.”应用需显式 DNS 地址时用127.0.0.11同上 · DNS services2026-10-15第 4、7 章DK08逐字默认 bridge 多上游时由容器解析库决定次序“Some resolvers query the servers in order. Others query them in parallel and use the first response received, even if that response is NXDOMAIN.”自定义网络“queries upstream servers in order and stops after a successful response or an NXDOMAIN response.”同上 · DNS services2026-10-15第 4、6 章DK09逐字--dns给出 DNS 服务器 IP可写多个请求从容器的网络命名空间发出--dns127.0.0.1指容器自身回环同上 · DNS services · Flag 表2026-10-15第 5 章DK10逐字--dns-search用于查找非完全限定主机名的搜索域可指定多个前缀同上 · DNS services · Flag 表2026-10-15第 5 章DK11逐字--dns-opt是表示 DNS 选项及其值的键值对合法取值见操作系统关于resolv.conf的文档同上 · DNS services · Flag 表2026-10-15第 5 章DK12逐字“Defaults to the container’s ID if not specified.”--hostname不指定时默认取容器 ID同上 · DNS services · Flag 表IP address and hostname2026-10-15第 5、7 章DK13逐字“you can use the--aliasflag to specify an additional network alias for the container on that network.”用于docker network connect同上 · IP address and hostname2026-10-15第 5、7 章DK14逐字“Custom hosts, defined in/etc/hostson the host machine, aren’t inherited by containers.”容器/etc/hosts只有自身 hostname、localhost等常见条目同上 · Custom hosts2026-10-15第 3 章边界-1本文全部docker命令本机未实测本机无 Docker 环境代码块一律保留⚠️ 代码待验证本批执行记录未实测2026-10-15全文边界-2本文命令中的镜像名一律以$IMAGE等占位符表示不写具体镜像与版本号本批写作约定2026-10-15全文边界-3各上游 DNS 服务器与各容器基础镜像的具体解析实现差异本批未核正文只引官方两类网络的口径不作推断本批核验边界未核2026-10-15第 4、6 章附表 B术语速查表术语一句话解释名字解析把名字翻译成 IP 地址的那一步产出只有一个地址或找不到连接可达拿到地址之后能不能真正连上属于网络层判断default bridgeLinux 上 Docker Engine 首次启动时的唯一内置网络不带--network的容器接在其上用户自定义网络自建网络接入同一网络后容器可用容器名或容器 IP 互相通信embedded DNS serverDocker 在自定义网络容器中提供的解析服务地址为127.0.0.11127.0.0.11embedded DNS server 在容器里固定的地址无 IPv6 对应地址/etc/resolv.conf解析配置的来源默认 bridge 容器拿到的是宿主该文件的副本--dns/--dns-opt改问谁与带什么选项去问--dns请求从容器的网络命名空间发出--dns-search改短名字补全时用哪些后缀--hostname改容器给自己的主机名不指定时默认为容器 ID--alias用docker network connect时在某网络上为容器额外加的一个名字Custom hosts宿主/etc/hosts中的自定义条目不会被容器继承写在最后这篇用到的资料写这篇文章时我一直在想那个特别容易绕进去的现场——两个容器都在跑从这边去连那边就是连不上第一反应总是是不是网络配错了。答案其实很朴素先看你是不是一直在同一个默认网络上找名字而默认网络本来就不提供按名字互访这件事。顺手也整理了几份配套的东西靶场环境对照表DVWA、upload-labs 在 Windows / macOS / Linux 三平台的可行性与推荐路径Web 安全学习路线图从基础打牢到安全管理四个阶段各学什么常用靶场清单每个靶场练什么、适合哪个阶段资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「靶场」优先通过。拿到之后建议先看环境对照表那一份再回头对照本文第六章那张按现象定位对照表过一遍——下次再遇到容器之间互相找不到先按 IP 试一次把两层分开再去问这两个容器到底接在哪张网上。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑