Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
工具/GitHubGitHub/yarrick/iodine
IDS/IPS规避数据泄露网络安全渗透测试命令与控制红队远程访问工具数据泄露 分类第 2 名IDS/IPS规避 分类第 13 名
8.0k5981073天前Kitploit 审核通过
GitHub
yarrick/iodine

iodine

通过 DNS 服务器隧道传输 IPv4 数据,以绕过防火墙限制,并为渗透测试提供隐蔽的网络访问。

查看仓库网站

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

iodine - https://code.kryo.se/iodine

这是一款软件,可让你通过 DNS 服务器隧道传输 IPv4 数据。在互联网访问被防火墙限制但允许 DNS 查询的各种场景中,它都能派上用场。

编译

编译 iodine 需要 meson。 在 build 目录中运行以下命令进行编译:

meson setup build
cd build
ninja

构建并运行测试需要 check 库。在 build 目录中运行 ninja test 即可启动测试。

快速开始

在你自己的局域网中试用一下吧!按照以下简单步骤操作:

  • 在服务器上运行:./iodined -f 10.0.0.1 test.com。 如果你已经使用了 10.0.0.0 网络,请改用其他内部网段,例如 172.16.0.0。
  • 输入密码。
  • 在客户端上运行:./iodine -f -r 192.168.0.1 test.com。 将 192.168.0.1 替换为你的服务器 IP 地址。
  • 输入相同的密码。
  • 现在客户端拥有隧道 IP 10.0.0.2,服务器拥有 10.0.0.1。
  • 尝试通过隧道互相 ping。
  • 完成!:)

要通过中继域名服务器实际使用它,请参阅下文。

使用方法

注意:服务器和客户端必须使用完全相同的协议。在大多数情况下,这意味着运行相同版本的 iodine。遗憾的是,实现向后和向前协议兼容通常是不可行的。

服务器端

要使用此隧道,你需要控制一个真实域名(例如 mydomain.com), 以及一台拥有公网 IP 地址的服务器来运行 iodined。如果该服务器 已经在运行 DNS 程序,请更改其监听端口,然后使用 iodined 的 -b 选项让 iodined 转发 DNS 请求。(请注意,此做法 不建议在生产环境中使用,因为 iodined 的 DNS 转发 并非完全透明,例如区域传送将无法工作。) 或者,你可以将 DNS 服务器中的子域转发到 iodined, 此时 iodined 必须运行在不同的端口上(-p)。

然后,将一个子域(例如 t1.mydomain.com)委派给 iodined 服务器。 如果你使用 BIND 管理域名,请在区域文件中添加如下两行:

t1		IN	NS	t1ns.mydomain.com.		; 注意末尾的点!
t1ns		IN	A	10.15.213.99

NS 行是将 t1 子域的查询路由到 t1ns 服务器所需的全部内容。 我们为子域使用短名称,以便尽可能为数据流量保留更多空间。 NS 行的末尾是你的 iodined 服务器名称。这可以是任何名称,指向任何位置, 但在本例中,它方便地保留在同一个区域文件中。它必须是一个名称 (而非 IP 地址),并且该名称本身必须有一条 A 记录 (而非 CNAME)。

如果你的 iodined 服务器拥有动态 IP,请使用动态 DNS 提供商。只需 将 NS 行指向它,并省略 A 行:

t1		IN	NS	myname.mydyndnsprovider.com.	; 注意末尾的点!

然后重新加载或重启你的域名服务器程序。现在,任何以 t1.mydomain.com 结尾的域名的 DNS 查询都将发送到你的 iodined 服务器。

最后,在服务器上启动 iodined。第一个参数是隧道内部的 IP 地址, 可以来自你尚未使用的任何网段(例如 192.168.99.1),第二个参数是指定的域名(在本例中 为 t1.mydomain.com)。使用 -f 选项将使 iodined 保持在前台运行, 这在测试时很有帮助。iodined 将打开一个虚拟接口 ("tun 设备"),并开始在 UDP 端口 53 上监听 DNS 查询。 可以在命令行中输入密码(-P pass),也可以在服务器启动后输入。现在一切就绪,可以连接客户端了。

如果你有可能在意外环境中使用 iodine 隧道,请在启动 iodined 时加上 -c 选项。 本例中生成的命令行如下:

./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com

客户端

所有设置已完成,只需启动 iodine。它接受一个或两个参数, 第一个是本地中继 DNS 服务器(可选),第二个是你使用的域名(t1.mydomain.com)。如果不指定第一个参数, 将使用系统当前的 DNS 设置。

如果允许向任何计算机发送 DNS 查询,你可以直接将 iodined 服务器的地址作为第一个参数(在本例中:t1ns.mydomain.com 或 10.15.213.99)。在这种情况下,也可能允许向任何计算机的 DNS 端口(53 UDP)发送_任何_流量。Iodine 会检测到这一点,并在可能的情况下切换到原始 UDP 隧道。如果要在任何情况下强制使用 DNS 隧道,请使用 -r 选项(在你自己网络内测试时特别有用)。

客户端的隧道接口将获得一个与服务器相近的 IP(在本例中 为 192.168.99.2 或 .3 等)以及合适的 MTU。输入与 服务器相同的密码,可以作为命令行选项,也可以在客户端启动后输入。 使用 -f 选项将使 iodine 客户端保持在前台运行。

本例中生成的命令行如下,添加 -r 会强制使用 DNS 隧道, 即使原始 UDP 隧道可行:

./iodine -f -P secretpassword t1.mydomain.com

现在,从任意一端都应该能够 ping 通隧道另一端的 IP 地址。 在本例中,从 iodine 客户端执行 ping 192.168.99.1,从 iodine 服务器执行 192.168.99.2。

其他信息

IPv6

隧道内的数据仅支持 IPv4。

服务器默认同时监听 IPv4 和 IPv6 的传入请求。 使用 -4 或 -6 选项可以只监听一种协议。原始模式将 尝试使用与登录时相同的协议。

客户端可以使用 IPv4 或 IPv6 域名服务器连接到 iodined。中继 域名服务器会在需要时自动在协议之间进行转换。使用 -4 或 -6 选项可以强制客户端为其 DNS 查询使用特定的 IP 版本。

如果你的服务器监听 IPv6 且可访问,请在其 DNS 设置中添加一条 AAAA 记录。 扩展上面的示例,如下所示:

t1		IN	NS	t1ns.mydomain.com.		; 注意末尾的点!
t1ns		IN	A	10.15.213.99
t1ns		IN	AAAA	2001:db8::1001:99

路由

可以通过 DNS 隧道路由所有流量。为此,首先 通过有线/无线接口添加一条到 iodine 所用域名服务器的主机路由, 以默认网关作为网关。然后将默认 网关替换为 iodined 服务器在 DNS 隧道内部的 IP 地址,并 配置服务器进行 NAT。

但是请注意,隧道内的数据流量完全没有加密,外部各方 可以相对容易地读取和修改。为了最大 安全性,请通过 DNS 隧道运行 VPN(=双重隧道),或使用安全 shell(SSH)访问,可以配合端口转发。后者也可以用于 网页浏览,只要你在服务器上运行 Web 代理(例如 Privoxy)。

测试

iodined 服务器会回复发送到隧道域子域的 NS 请求。如果你的 iodined 子域是 t1.mydomain.com,请发送一个针对 foo123.t1.mydomain.com 的 NS 请求,以查看委派是否正常工作。 dig 是一个很好的工具:

% dig -t NS foo123.t1.mydomain.com
ns.io.citronna.de.

此外,iodined 服务器会回复以 'z' 开头的任何受支持请求类型的请求,例如:

dig -t TXT z456.t1.mydomain.com
dig -t SRV z456.t1.mydomain.com
dig -t CNAME z456.t1.mydomain.com

在所有这些情况下,回复应该看起来像乱码文本。

Mac OS X

在 Mac OS X 10.6 及更高版本上,iodine 支持操作系统内置的原生 utun 设备——使用 -d utunX。

运行信息

DNS 响应分片大小通常会自动探测以获得最大带宽。 要强制指定特定值(并加快速度),请使用 -m 选项。

DNS 主机名通常使用到其最大长度,即 255 个字符。 已发现一些 DNS 中继在回复全长查询时相当不可靠, 在重复尝试时给出的分片大小自动探测结果差异很大(且大多非常糟糕)。在这些情况下,请使用 -M 开关 将 DNS 主机名长度减少到例如 200 个字符,这会使 这些 DNS 中继稳定得多。这对于一些"去优化" DNS 中继也很有用,它们会在响应中塞入两份完整的查询副本,留给 下行数据的空间非常少(也不支持 EDNS0)。-M 开关可以用一些上行带宽换取下行带宽。请注意, -M 的最小值约为 100,因为协议只能将数据包(最大 1200 字节)分成 16 个分片,每个分片至少需要 75 个真实数据字节。

上行数据以 Base32 进行 gzip 编码发送;如果中继 服务器支持域名中的大小写混合和 +,则使用 Base64;如果支持 _ 代替,则使用 Base64u;如果支持高字节值字符,则使用 Base128。 这种上行编码是自动检测的。DNS 协议允许每个 数据包一个查询,一个查询最多 256 个字符。每个域名部分最多 63 个字符。因此你的域名和子域应尽可能短,以 允许最大的上行吞吐量。

支持多种 DNS 请求类型,其中 NULL 和 PRIVATE 类型 预计提供最大的下行带宽。PRIVATE 类型使用 私有使用范围内的值 65399。其他可用类型有 TXT、SRV、 MX、CNAME 和 A(返回 CNAME),按带宽递减顺序排列。 通常会自动检测并使用"最佳"请求类型。然而,DNS 中继 可能对例如 NULL 和 TXT 施加限制,使得 SRV 或 MX 实际上成为最佳 选择。这不会被自动检测,但可以使用 -T 选项强制指定。 建议尝试各种替代方案,尤其是当自动检测到的 请求类型提供的下行分片大小小于 200 字节时。

请注意,SRV、MX 和 A(返回 CNAME)查询可能/将会导致 "智能"缓存域名服务器进行额外查询以获取实际 IP 地址, 这可能会减慢速度或完全失败。

非 NULL/PRIVATE 查询的 DNS 响应可以使用与上行数据相同的 编解码器进行编码。这通常也是自动检测的,但没有进行完全 详尽的测试,因此在选择更高级的编解码器时可能不会注意到一些问题。在这种情况下,你会在 分片大小自动探测中看到失败/损坏。特别是,已发现一些 DNS 中继 在返回主机名(SRV、MX、CNAME、A)的回复时,仅当主机名超过约 180 个字符时将其改为小写。在这些及类似情况下,请使用 -O 选项尝试其他下行编解码器;Base32 应该总是有效。

现在的正常操作是服务器在下一个 DNS 请求到来之前_不_回复 DNS 请求,即所谓的"懒惰"模式。这样,当需要发送新的下行数据时,服务器 总是手头有一个 DNS 请求可用。 这大大提高了(交互式)性能和延迟,并允许 将静默 ping 请求默认减慢到 4 秒间隔,甚至可能更慢。事实上,现在 ping 的主要目的是强制 回复上一个 ping,并防止 DNS 服务器超时(通常至少 5-10 秒,依据 RFC1035)。一些 DNS 服务器更不耐烦,会在没有隧道数据流量的时段 给出 SERVFAIL 错误(超时)。在這些情况下所有 数据仍应能通过,但 iodine 会将 ping 间隔减少到 1 秒(-I1)以减少错误消息的数量。这对于像 dnsadvantage.com(ultradns)这样非常不耐烦的 DNS 中继可能没有帮助, 它们会在 1 秒甚至更短时间内超时。但数据仍能通过, 你可以忽略 SERVFAIL 错误。

如果你在没有任何中间 DNS 服务器的本地网络上运行,请尝试 -I 50(iodine 和 iodined 在静默 60 秒后关闭连接)。 你唯一会注意到速度变慢的时候,是 DNS 回复数据包丢失时; iodined 服务器此时必须等待新的 ping 来重新发送数据。你可以 通过产生一些上行流量(按键、ping)来加速。如果这种情况 经常发生,请检查你的网络是否存在瓶颈,和/或使用 -I1 运行。

懒惰模式下的延迟应答会导致一些"运营商级"商业 DNS 中继反复向 iodined 服务器重新发送相同的 DNS 查询。 如果 DNS 中继实际上是由一组并行服务器实现的, 重复请求甚至可能来自多个来源。这种效应 只会在 iodined 服务器的网络流量中可见,不会 影响客户端的连接。Iodined 会注意到这些重复请求,并在时机到来时 将相同的应答发送给原始查询和 最新的重复请求。之后,完整应答会被短暂缓存。 更晚到达服务器的延迟重复请求,会得到 iodine 客户端将忽略的回复(如果它最终到达那里的话)。

如果你遇到问题,请尝试使用 tcpdump 或 ethereal/wireshark 等网络监控工具 检查流量,并确保中继 DNS 服务器 没有缓存响应。缓存的错误消息可能意味着你在服务器之前 启动了客户端。服务器上的 -D(和 -DD)选项 也可以显示接收和发送的查询。

提示与技巧

如果你的特定接口上的 53 端口被一个不使用它的应用程序占用, 请在 iodined 上使用 -p 指定备用端口(例如 -p 5353), 并使用例如 iptables(在 Linux 上)转发流量:

iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353

(由 Tom Schouten 提交)

Iodined 将拒绝来自超过 60 秒未活动(数据/ping)的客户端的数据。 同样,iodine 在 60 秒内未收到下行数据时会退出。在长时间网络中断或 类似情况下,只需重启 iodine(重新登录),可能需要多次,直到你取回 原来的 IP 地址。完成后,只需等待一段时间,你最终会 看到隧道 TCP 流量从中断前的位置继续流动。

随着服务器中下行数据包队列的引入,其内存在默认配置下 增加了数兆字节。 在低内存环境中使用(例如在你的 DSL 路由器上运行),你可以在 user.h 中 减少 USERS 并取消定义 OUTPACKETQ_LEN,不会有任何不良后 果,假设任何时候最多只有一个客户端连接。仍然建议设置较小的 DNSCACHE_LEN,最好为 2 或更高,但你也可以取消定义它以再节省几 KB。

一个 iodine 服务器可以处理多个域名。在同一域名上设置不同的 NS 记录 全部指向同一主机,并在 topdomain 参数开头使用通配符 (例如 *.mydomain.com)。iodine 将接受所有匹配该模式的域名的隧道流量。通配符 必须位于 topdomain 参数的开头,后面跟一个点。

性能

本节列出了一些性能测量数据。要正确查看,请使用 等宽字体,如 Courier。

测量在协议 00000502 的懒惰模式下进行;上行编码 始终为 Base128;iodine -M255;iodined -m1130。网络条件 并非极其有利;结果不是基准测试,而是对类似情况下可预期的 真实世界性能的现实指示。

上行/下行吞吐量通过 scp 传输一个先前从 /dev/urandom 读取的文件 (即不可压缩)来测量,并在单独的非隧道连接上使用 ls -l ; sleep 30 ; ls -l 测量大小。鉴于 scp 的大块大小 16 kB,这给出了 4.3 kbit/s 的分辨率,这 解释了为什么某些值完全相等。 Ping 往返时间使用 ping -c100 测量,呈现的是平均 rtt 和平均偏差(表示围绕平均值的分布),单位为毫秒。

情况 1:Laptop -> Wifi AP -> Home server -> DSL provider -> Datacenter

 iodine    DNS "relay"        bind9           DNS cache        iodined

                        downstr.  upstream downstr.  ping-up       ping-down
                        fragsize   kbit/s   kbit/s  avg +/-mdev   avg +/-mdev
-----------------------------------------------------------------------------

iodine -> Wifi AP :53
  -Tnull (= -Oraw)           982    43.6    131.0   28.0    4.6   26.8    3.4

iodine -> Home server :53
  -Tnull (= -Oraw)          1174    48.0    305.8   26.6    5.0   26.9    8.4
下载工具