3. 理解问题

理解问题是解决问题的第一步。

3.1. 为事物命名

如果你想让这个技巧对你有效,你必须了解它的工作原理,这样在出现问题时,你就知道该在哪里查找。

理解问题的第一步是为相关的概念命名。

像往常一样,我们将在此处称“客户端”为决定发起连接的机器,以及该机器上的程序和文件。相反,我们将称“服务器”为等待连接并接受连接的机器,以及该机器上的程序和文件。当两台机器被防火墙分隔时,防火墙穿透非常有用,这样服务器可以接受某种连接,而客户端可能可以或可能无法接受任何连接。将在两台机器之间创建一个隧道,允许完全的 IP 流量通过防火墙。

通常,在进行防火墙穿透时,客户端是位于防火墙后面的机器:它对互联网的访问受限,但可以某种方式打开与服务器的连接。服务器是具有完全互联网访问权限的机器,它将充当客户端访问整个互联网的代理。在 VPN 中,防火墙的角色可能会反转,客户端位于互联网上,而服务器充当客户端访问某些私有网络的代理。

3.2. 主要问题

防火墙穿透的主要问题是创建一个隧道:从客户端机器到防火墙另一侧的服务器机器的连续连接,允许双向信息交换。可选地,此连接应该是安全的。次要问题是将此连接转换为完全的 IP 访问,以供普通程序透明地使用。

对于主要问题,我们假设以下两种情况之一成立:(1)您可以从防火墙客户端建立正常的 TCP/IP 连接到服务器机器上的某个端口,其中 sshd 正在运行或可以设置为运行,或者(2)您可以某种方式通过 telnet 代理建立 telnet 连接。如果您不能,我们将为您提供指向其他软件的指针,这些软件允许您穿透防火墙建立隧道。虽然我们只在第一种情况下给出安全解决方案,但如果您理解原理,您可以在其他情况下破解您自己的安全解决方案(如果您不理解,可以找人,例如我,为您做这件事,以换取报酬)。

3.3. 次要问题

对于次要问题,IP 模拟器(pppdSLiRP)在隧道的每一侧运行。

在想要完全 IP 访问另一侧的一侧,您需要运行 pppd。在另一侧,如果您也想要完全 IP 访问第一侧,则需要运行 pppd;如果您想阻止任何访问,则需要运行 SLiRP。如果您有以下示例未涵盖的特定需求,请查阅您常用的 pppdSLiRP 文档以获取更多信息。

虽然这在概念上很简单,但它仍然需要一些小技巧才能工作,因为 (a) 如果您使用某种编程的交互式 shell 会话来启动任一侧的服务器 IP 模拟器,您需要正确同步另一侧 IP 模拟器的启动,以免将垃圾信息发送到 shell 会话中,并且 (b) IP 模拟器被设计为在 "tty" 接口上运行,因此您必须将隧道的接口转换为 tty 接口。

问题 (a) 只是您通常遇到的同步问题,如果您使用 ssh,则甚至不存在此问题,因为它透明地处理服务器的命令启动。

问题 (b) 需要使用一个简单的外部实用程序。我们为此目的编写了一个,cotty

<开始吐槽>

pppd 维护者目光短浅(在最近的 Linux 版本中已不再如此)造成的愚蠢问题中,您只能通过以下设备运行它:/dev或当前的 tty。您不能通过一对管道(这本应是显而易见的设计)运行它。如果服务器有 pppd,这没问题,因为它可以使用 telnetssh 会话的tty;但对于客户端的 pppd,这与可能使用 telnet 作为建立连接的方式相冲突。

实际上,telnet 也希望在 tty 上运行;它在一对管道上几乎可以正确运行,但它仍然会坚持对当前的 tty 执行 ioctl,这将导致干扰;在没有 tty 的情况下使用 telnet 也会导致竞争条件,从而导致整个连接在“慢速”计算机上失败(fwprc 0.1 在 P/MMX 233 上完美运行,在 6x86-P200+ 上六次中有一次成功,在 486dx2/66 上从未成功)。总而言之,当使用 telnet 时,您需要运行 cotty 作为守护进程,以将运行 pppd 的一个 tty 的输出复制到运行 telnet 的另一个 tty,反之亦然。

如果我找到那个笨蛋(可能是 MULTICS 的人,尽管肯定有 UNIX 的人蠢到复制了这个想法),他发明了 “tty” 设备的原理,通过该原理,您可以从“相同”的伪文件读取和写入,而不是使用干净的管道对,我真想掐死他!

</吐槽结束>