第十四章 处理NAT

        NAT(Network Address Translation,网络地址转换)是时代原因遗留的最大问题:它源自互联网没有广泛使用,恐龙自由漫游的年代。那时候…大约是20年前?网络地址资源非常充足(通常分配一个C类网络地址,有254个公共互联网可路由地址。我个人拥有两个C类地址,一个用于iol.it,另一个用于matrice.it),没有人意识到IPV4地址资源池会永远耗尽。因此,互联网上的大部分机器都有它们自己的公网地址。此外,安全、加密等方面没有问题。那时互联网上没有钱,因此没有犯罪。

        电信上最理想的状态是让两台公网主机直接点对点连接。起初,SIP正是按这个思路设计的。因此,它完全脱离了自然环境,几年之后,大部分使用VOIP的主机都会发现自己位于防火墙和NAT之后。你在私网内部和在互联网一侧访问同一台机器,你会发现用的IP地址是不同的。路由器和“猫”会在数据包的最低层(0层和1层)上对这些数据进行自动转换。问题是,SIP需要一个文本部分(SDP),它是在数据进入互联网之前写入的。里面包含了媒体流地址的文本描述。而路由器是不会转换这些文本的(有些路由器会尝试这个转换,比如说ALG,但这往往带来更大的伤害)。很多时候,你会碰到这些问题:呼叫振铃了,你的小伙伴可以接听,但是听不到音频、看不到视频,或者是通道的,你不得不挂断电话;或者双向通话正常,但在大约30秒后被莫名其妙地拆线了(超时)。这类现象,极可能就是NAT在搞怪。

        这一章,我们将讨论以下主题:

  • NAT的简介,包括它的一点历史
  • NAT的四种陷阱
  • FreeSWITCH中克服NAT的设置
  • 故障排除技巧

NAT简介

        向一个完全不关心技术的人解释NAT的一种好办法是做个类比。想想一栋办公大楼和它的收发室。10楼的一位员工把包裹放在一楼的收发室里,然后寄给你。包裹被送到邮局,然后送到你家。包裹上的寄件人地址实际上是整个办公楼的地址,而不是10楼办公室的地址。现在,假设你需要退回包裹。你通过邮政系统退回包裹,邮递员把包裹送回办公大楼,收发室的职员必须先通过你的姓名或办公室号码找出分发的具体位置,最终把包裹带给10的员工。收发室就像一个NAT路由器,因为它在邮政系统和大楼内部之间代理邮件。办公室位置就像是局域网地址,因为邮件不能直接抵达这个位置。如果发送邮件的办公室名字被弄乱或没写在包裹上,而且收发室的员工不知道退回的包裹要送到哪个办公室,该怎么办?这将是一个NAT问题,你的包裹可能像之前的电话一样,最终丢失了。假设你在收到包裹并决定退回时发现上面没有联系人信息或办公室信息,但是因为这个包裹是你期待中的(你事先知道谁发给你的,译者注),那么你在退回包裹时,你可能会在标签上注明退回的办公室号码或联系人?这将是你所创建的一种反向NAT功能。

        当涉及到网络时,NAT本质上是这样一种技术:整个局域网(即不直接接入互联网的网络)都连接到一台可以访问互联网的设备,他们使用同一个公网IP地址(即接入互联网那台设备的IP),通过直接连入互联网那台设备为跳板,为整个局域网提供公网接入能力。它主要用于减少必要的公网IP地址数量,因为它很快就会耗尽。它刚开始时有四十亿,但在我写这本书时,基本上已经用完了。

        把你的局域网放在NAT之后有另一个作用,那就是保护的你计算机和其它设备免受攻击,因为它们在互联网上不可见。专家并不认为这是安全性的最终解决方案,因为在NAT背后仍然存在着危害设备的方法,但在与其他良好的安全实践一起使用时,将其视为额外保护。顺便说一个,当你阅读第15章VoIP 安全后,你会学到更多的安全相关知识。

了解NAT的演变

        这些年来,因为互联网的发展,对IPv4地址的需求一直在增长。随着需求的增长,可用地址池已经枯竭,可用IPv4地址已经严重不足。随着时间的推移,处理这种形势的两种主要尝试变得流行起来:NAT和IPv6。

        NAT已经成为一种相当流行的方式,它占用少量的公网IP地址并服务于大量的网络设备。NAT在20世纪90年代作为一种缓解IP饥饿问题的方法出现,直到IPv6出现,但现在它如此流行,以至于很多人不想放弃它。同时,系统管理员不得不接受NAT遗留的问题,因为它的流行,必须确保我们的软件和设备能够兼容它。

        一种叫IPv6的新的IP地址标准可以解决IP地址饥饿问题,它添加了海量的公网IP地址,足够我们为地球表面的每平方英寸上分配数万亿个IP地址。以我们现在所知道的整个互联网的大小,我们可以给地球上的每一个生物一个IP块,即使这样也不会对IPv6地址的可用池造成影响。IPv6规范于1998年发布,并一直在缓慢地发展。如今IPv6仍然只是IPv4的后盾,后者从20世纪70年代开始发展,拥有着广泛的使用场景。最有可能的是,即使我们完全采用了IPv6,NAT在一段时间内仍然不会消失。

        我们面临的主要问题是:当我们尝试解决VoIP相关的NAT问题时,这些设备是在NAT之后的,从互联网一侧根本不能访问,当你想要呼叫它时,很难联系上它。下一个大问题是协议问题,比如说SIP,在NAT下可能会中断。

 

NAT的四个陷阱

        NAT有四个基本陷阱,每个人都应该学习。了解这些陷阱,你就能很好地处理NAT场景,你无疑会面临:

  • 即使你不知道,NAT也可能存在。互联网不必参与其中。
  • 任何两种抵御NAT的技术一起混用,都可能彼此相互抵消。
  • 有些设备使用SIP ALG(Application Layer Gateway,应用层网关)来抵御NAT。它们甚至没有告诉你就直接做了。
  • NAT校正技术(比如ALG)可能错误识别具体情况,实际上把事情弄得更糟糕。

 

        熟悉这些陷阱。它们在本章中经常被引用。让我们更详细地讨论每一个问题:

  • 即使你不知道,NAT也可能存在。互联网不必参与其中。如果你使用的是有线或电话公司的家庭互联网服务,甚至有些商务级服务,他们有时会使用NAT将所有客户置于一个单独的网络中,然后将该网络转换为基础设施中的其他部分。在你的设备到目标设备之间,这种事情不会只出现一次,而会是多次出现,而你没有任何控制手段。这会给试图使用VoIP的人带来实质性的问题。大多数VoIP协议只有处理NAT的基本规定,并且经常出现不足。这可能是大多数家庭用户在家中使用VoIP时遇到的第一个问题。在一个局域网内部也可以使用NAT方式连接多个局域网,而不需要真正连接到互联网。连接互联网只是NAT的最常见的用法而已,但它也可以在内部做网络隔离用。如果你正在向你友好、邻居、网络电话专家寻求帮助,而他提出了一个NAT问题,不要仅仅因为你没有使用互联网,或者你不知道NAT在哪里就把它排除在外。
  • 任何两种抵御NAT的技术一起混用,都可能彼此相互抵消。这是一个棘手的问题,在VoIP用户中很常见。把它形象化的最好方法就是想象一场奥赛罗的比赛。每当你移动一步去阻挡NAT时,它都会翻转周围的一切。如果你做一个反向移动,所有东西又将翻转回来。实际发生的甚至比你想像的多(看一下第一个陷阱)。只要尝试的次数是奇数,并且开始时是不工作状态,那么你应该结束,但你应该注意只做尽可能小的修改,以免混淆和痛苦。如果你的话机上支持NAT功能,你在话机侧启用了它,并且在FreeSWITCH侧同时启用,你可能会碰到单向通话或没有声音的问题。更令人困惑的是,有很多方法可以取消NAT。有些只需要在NAT后面的话机上进行更改;有些只需要在FreeSwitch上进行更改;有些则需要在两端进行更改。
  • 有些设备使用SIP ALG来抵御NAT。“哼,该死的SIP ALG”。我们已经无数次在IRC或社区会议中听到这样的抱怨了。ALG的本意是好的,但它通常好心干坏事。它们就像前两种陷阱的组合,因为它们通常是你的网络路由器内部实现的,并且在你不知道的情况下默认开启。在所有反向NAT技术中,它们做得最差,即在SIP包经过路由器时修改SIP的文本。这会导致错误的行为和错误的路由导向,呈现在你眼前的完全是一个谜。注意我的话。如果你发现自己说出了“这完全没有意义”这句话,你首先要检查的是,你是否被邪恶的SIP ALG所迷惑。很多时候,禁用SIP ALG就能解决NAT相关的问题。
  • NAT校正技术可能错误识别具体情况,实际上把事情弄得更糟糕。它有助于了解你的环境,至少足以知道你是否真的需要启用反NAT功能。一些SIP代理利用了SIP的一些更神秘的东西,并对(SIP)包中的网络地址做了一些非常奇妙的事情。对于那些不熟悉SIP的人来说,是的,我知道这很神秘,但我们需要洞察事物的本质。所以问题是,完全合法的数据包以一种类似于NAT的方式进行操作,可以触发我们用来检测NAT的一些特性。所以你需要小心,尤其是思科的话机,因为它的NAT性能很差,同时还容易被误检。

 

解密FreeSWITCH的NAT设置

        既然我们已经了解了NAT的常见缺陷,那么我们可以仔细检查可能遇到的各种类型的NAT。基本上,你可能会遇到这样的情况:你的话机或PBX在NAT之后,与不在NAT之后的SIP终端通信(或者相反)。更糟糕的是,你可能最终会遇到可怕的双向NAT情况,在这种情况下,连接双方同时独立存在于各自的NAT路由器之后。

       双向NAT的情景,网络结构看起来是这样的:


        让我们从一个理智但充满挑战的场景开始:你家里有一部话机,NAT情况未知,而你希望把它注册到公网上的FreeSWITCH服务器。好消息是,FreeSwitch演示配置示例已经涵盖了这种情况。FreeSWITCH内核有一个特性叫ACL(Access Control Lists,访问控制列表)。ACL允许您创建网络地址列表,并根据特定设备是否源自由ACL定义的地址来控制访问权限。确定一个地址是否与列表元素匹配,在此基础上确定清单上的内容是好是坏,是否继续保留(或不保留)在列表中,值是对等的。

        这个特性允许某些设备根据其IP地址进行身份验证,或者你可以列出敌人设备的列表,以便完全阻止列表中的任何人。在本案例中,我们将用ACL来确定一台设备是否在NAT之后,并决定如何处理。

        NAT背后的设备很可能拥有一个特殊范围内的IP地址,这由RFC-1918定义。对此最简单的解释是,有一组特殊的IP地址段永远不会连接到互联网,因为它们保留在局域网内私有使用。这基本上是以192.168.x.x、172.16.x.x到172.31.x.x或10.x.x.x开头的任何IP地址。从现在起我们就叫他们局域网地址。人们也会根据RFC来称呼它们,例如“RFC1918地址”。

        因为这些地址是私有的,所以可能有无数个网络中使用完全相同的IP地址,但它们永远不能直接相连。现在,当你把这些网络连接到一台NAT路由器之后,所有这些私网中的话机就都能够访问你的FreeSWITCH服务器了。路由器的工作原理是跟踪来自LAN地址的所有流量,并将其发送到互联网,就像它来自路由器上的公网 IP一样。然后,当互联网上的目标网元把应答消息回给NAT路由器时,它根据映射关系把数据包传递给原始的发送方。FreeSWITCH看到的源地址可能永远不会相同,这使得向话机发送来电变得困难。这就是ACL大显身手的时候了。

        FreeSWITCH的mod_sofia profile有一个配置参数叫apply-nat-acl。这个参数可以在同一个profile内多次使用,并且需要ACL列表的名称。当mod_sofia收到SIP REGISTER或INVITE时,它查看联系人地址,并根据指定的ACL检查Contact报头中引用的IP。如果有匹配,则得出结论,设备位于NAT之后。很难说哪一个IP代表了NAT背后的设备,但我们有一些线索。还记得我们说过的RFC-1918或局域网地址吗?因为它是一个定义的IP地址范围,所以我们可以得出这样的结论:如果你来自这些地址中的一个,那么你是从NAT后面发起呼叫的。

        小心!别忘记第四个陷阱,假设每个来自局域网地址的设备都在NAT之后,这并不是百分之百的安全。事情并不总是如此,但肯定的时候居多。保持警惕是件好事。有一种情况可能不是这样,那就是FreeSWITCH也部署在NAT后,拥有同样的私网地址。好吧,我们有一个特殊的ACL,在FreeSwitch启动时创建,称为nat.auto。这个特殊的acl已经包含了整个RFC-1918地址空间,它同时检查了机器的本地网络地址,并排除了该地址空间,这样当它接到与FreeSWITCH在同一局域网上的电话的呼叫时,就不会有任何误判。同时,这个ACL可以检测到一部话机实际上位于NAT后面的远程位置。FreeSWITCH通过apply-nat-acl指向nat.auto预先设置,能够纠正FreeSWITCH部署在公网环境中的大部分NAT背后的典型设备。

        我们如何解决这个问题呢?基本上,当检测到话机从NAT后面注册时,我们把我们见到的源IP和端口(网络层的源地址)保存下来,并把它与我们不可访问的局域网地址一并存储在内部数据库中,毫无疑问,这个局域网地址是话机注册信令中提供给我们的。当我们需要联系这部话机时,我们检查数据库并确定消息应该发送的IP:port。在SIP报头中,依然填写远程话机所期望的内网IP:port。我们同时告诉话机提高注册频率以保证映射的开放状态,因为大部分NAT路由器只在短时间内找开转换路径。这项技术有效地避开了第四种陷阱的风险,因为我们从来没有像邪恶的ALG那样篡改预期的地址。

        这里给出一个FreeSWITCH  CLI上的输出示例。客户端是一个NAT后面的软电话,注册到一个运行在公网上的FreeSWITCH实例。注意Contact字段用的IP  10.0.1.85是一个局域网地址。Status字段显示:由于nat.auto ACL列表的存在,检测到UDP-NAT。技巧体现在Contact的结尾之外。在话机注册的Contact地址之后,追加了fs_nat和fs_path参数,指出如何绕过NAT。考虑以下内容:

fs_nat=yes fs_path=sip%3A1006%40206.22.109.244%3A43425%3Brinstance%3Db67dbafc

9baa9465%3Btransport%3Dudp.

 

        其中fs_path字段是一个SIP URI (Uniform Resource Identifier,统一资源标识符),它是绕过NAT联系话机的实际地址。这个URL是经过编码的,因此URI中的特殊字符不会与实际联系地址冲突。这个字段解码后的版本是这样的:

sip:[email protected]:43425;rinstance=b67dbafc9baa9465;transport=udp

 

          因此,当我们向这部话机发起呼叫时,INVITE消息会发到206.22.109.244:43425,但信令中我们会保留它原来的地址10.0.1.85:5060(信令中的文本),这正是对端路由器NAT转换前的地址,它负责把INVITE信令转递给话机终端。通过”sofia status profile internal reg”命令,你可以看到完整的注册信息。下面是具体输出实例:

 

freeswitch@myhost> sofia status profile internal reg Registrations:

================================================================ Call-ID:                                      ZWU1MjdiZTI2MTg2MmVhNTc5NTk3MDY5YjFmOTVkMTU.

User:                           [email protected] Contact:

"TEST"<sip:[email protected]:10118;rinstance=b67dbafc9baa9465;transport=udp;fs

_nat=yes;fs_path=sip%3A1006%40184.58.189.244%3A43425%3Brinstance%3Db67dbafc 9baa9465%3Btransport%3Dudp>

Agent:                        eyeBeam release 1104g stamp 54685

Status:                      Registered(UDP-NAT)(unknown) EXP(2012-12-09 10:18:07) EXPSECS(88)

Host:                           myhost

IP:                                206.22.109.244

Port:                           43425

Auth-User:               1006

Auth-Realm:             myhost.freeswitch.org

MWI-Account:          [email protected] Total items returned: 1

================================================================

 

        注意里面的Contact内容,包含了fs_nat和fs_path两个参数。FreeSwitch发送给用户1006的任何SIP通信都将使用fs_path参数中指定的URI。

         下面我们给出另一个示例,使用一种更现代的客户端,处理客户端和服务器处理不同NAT后面的普遍场景。在这个案例中,客户端能够利用FreeSWITCH发给它的数据纠正自己的地址。

        我们的Linphone第一次发发的SIP 注册包是这样的:

 

REGISTER sip:lab.opentelecomsolutions.com SIP/2.0

Via: SIP/2.0/UDP 192.168.1.200:5060;branch=z9hG4bK.znT45Avvt;rport From: "Sara"<sip:[email protected]>;tag=cfurzFSzg To: "Sara"<sip:[email protected]>

CSeq: 20 REGISTER

Call-ID: kMq3GlIAVx Max-Forwards: 70

Supported: replaces, outbound Accept: application/sdp Accept: text/plain

Accept: application/vnd.gsma.rcs-ft-http+xml Contact:

<sip:[email protected];transport=udp>;+sip.instance="<urn:uuid:ba010749-62 14-4a35-bfb1-ac9c9181c24d>"

Expires: 3600

User-Agent: Linphone/3.9.1 (belle-sip/1.4.2)

 

        你可以看到,原始的"Contact"报头中,携带的地址是“192.168.1.200”,局域网私网地址。但是,经过完成注册所需要的几次数据交换之后,Linphone会向FreeSWITCH发送正确的“联系地址”,而我们最终得到:

 

生成媒体流

        既然SIP消息可以正常地从FreeSWITCH传输到话机,那么媒体呢?如果你连对方的声音都听不能,那么能不能看到对方的视频就不重要了,对吧?我们碰到过许多问题,呼叫可以正常建立,直到NAT击中呼叫中实际提供媒体的RTP包,最后呈现的是单向音频或者干脆双向没有音频,才意识到问题的存在。鉴于这种不公平现象,我们创建了一种单独的特性,它总是启用的,只有在极少数情况下会手动禁用,这些情况都是由第四种陷阱引发的。这个特性叫RTP自动调整(auto-adjust)。我们需要它的原因是,当话机试图从NAT后面给我们打电话时,它会天真地向FreeSWITCH宣告它(FreeSWITCH)无法到达的LAN私有地址,告诉我们向哪里发送媒体流(如SDP文本中所写的地址)。

        我们可以合理地猜测:既然设备处理NAT之后,那么我们应该把音频包发给处理SIP消息时保存的同一地址。但情况并非总是如此,因为各种类型的NAT都有限制,端口映射有时需要NAT背后的设备实际发送了一个数据包之后才能建立。因此,现实中,我们可能完全没办法知道怎样才能把音频流成功地发给话机。由于有自动调整功能,我们还有一丝战斗的机会。只要我们给话机的地址是有效的,它就可以向我们发音频,我们可以等到对方向我们发几个包之后,通过RTP的起始地址来决定向哪里回送RTP包。这种方式并不保证100%有效,据我们所知,在其它方式无望的情况下,这种方式还是非常有效的。为了安全起见,我们只允许这种神奇的调整发生在通话刚开始的时候,否则坏人可能会试图窃取人们的音频流。

        如前所述,RTP自动调整在默认情况下几乎是启用的,并且会自动打开。你可以通过查找下面这样的日志消息来判断它是否正常工作。该消息显示原始媒体目的地和检测到的新媒体目的地。这个日志在任何触发自动调整的话务的开始处打印。

        这个特性有大约2%的机率触发第四个陷阱,如果你万幸碰到了,而且它实质上破坏你的工作了,你所需要做的只是在你的SIP profile中添加这么一个参数设置:

<param name="disable-rtp-auto-adjust" value="true"/>

 

        此外,你还可以通过设置通道变量rtp_auto_adjust=false来为单路呼叫禁用这个特性。唯一需要注意的是变量必须在媒体流开始前设置。

 

高级选项和设置

        现在我们已经了解了它是如何工作的,我们可以看看其他触发NAT检测的方法。有些情况下,ACL是不够的,因为可能是鬼鬼祟祟的ALG弄乱了数据包,也可能是流量需要经过代理中转,也可能是话机终端自认为能够处理NAT但它做得并不正确。

        我们有另一个默认禁用的选项,因为它面对第四个陷阱时笑了,基本上认为任何稍微不寻常的东西都是NAT。这个参数是危险的,但当你束手无策时,它或许是一个有效的选择。这个参数的名字是aggressive-nat-detection在你的SIP profile中把它设置为true就能启用它,并对所有呼叫生效。基本上,它查看SIP数据包,如果在不同的头中看到不同的IP地址,则使用逻辑推导来确定哪个是源地址。从这里开始,它执行ACL相同的操作,只是它可能没能把源地址写入数据库。

<param name="aggressive-nat-detection" value="true"/>

 

下图说明了这种场景:


        FreeSWITCH有一系列参数,我们称之为"No Device Left Behind"NDLB。这些参数表示这样的情况:我们完全模拟或接受设备中的缺陷假装一切都很好,或为设备做准备,这样它仍然可以工作,尽管事实上我们完全被冒犯了,因为我们必须通过修改代码使其工作。这些在处理不完全符合SIP规范的老式客户端时特别有用。

        在与NAT斗争的过程中,有一个参数特别有效,它就是force- rport。SIP协议中,rport属性的目的是在请求消息中添加;rport,以此来克服NAT的最小尝试。当FreeSWITCH见到这个属性时,会在应答消息中添加rport=host:ip,以便终端话机意识到自己处于NAT之后。有趣的是,有些话机在收到应答消息时能够正确处理rport属性,但它自己从不在请求消息中使用它。force-rport参数告诉FreeSWITCH,假装与我们交互的设备都提供了rport参数,因为我们应答时,就按有rport参数的逻辑处理,因此解锁了原本无法获得的功能。

        和其它大部分NDLB选项一样,这个参数缺省是不启用的。它同时打开了第四个陷阱的漏洞,因为它会破坏许多设备。你可以将其设置为true以始终假定rport;也可以将其设置为safe,仅对我们知道需要使其正常工作的设备启用rport。你还可以把它设置与client-only或server-only,即根据呼叫方向进行设置,幸运的是,你将永远不需要这些选项。

 

FreeSWITCH部署在NAT后

        我们已经介绍了一些常用的场景:你的话机在NAT之后,与公网上的FreeSWITCH对接。现在继续讨论下一种场景:你本地的FreeSWITCH副本部署在NAT之后,它连接公网上的SIP供应商或另外一台FreeSWITCH服务器。幸运的是,我们已经设计好示例配置,以便在这些NAT环境中有最好的工作体验。我们建议你每隔一段时间在FreeSwitch测试一下未更改的示例配置,以查看可能遗漏的默认行为。

Freeswitch与路由器对话

        FreeSWITCH默认支持两种NAT协议的客户端:NAT-PMP和UPnP。这两种协议使用的方法略有不同,但基本要点是相同的。这两种方法都使用网络协议来发现你的NAT路由器,并与之通信。因此,它不是在运行中进行NAT映射,而是请求路由器打开一个端口,并实际了解端口映射的详细信息,因此当FreeSwitch与另一台服务器进行对话时,它完全能够在SIP和媒体数据包中携带正确的信息。太酷了!不过要小心,我们正在打开通往第二、第三和第四个陷阱的大门。

        我们现在已经掩盖了我们在Nat后面的事实,这样对方就无法检测到它。我们之间可能隐藏着一个ALG,现在我们不需要它,但它依然自以为是地帮我们替换地址。对端可能使用类似的NAT检测方法,从而触发一个双反NAT陷阱。最重要的是,如果您有一个非常严格的NAT路由器或防火墙,这个功能不仅可以解决地址映射的难题,而且还可以解锁防火墙上原本阻塞的端口。

FreeSWITCH部署在NAT后,单独运行路由器

        SIP profile有一组参数,它们是ext-sip-ip和ext-rtp-ip。这些参数用于提供外部IP地址信息。缺省配置文件中,这两个参数都配置为auto-nat。这与我们刚才讨论的NAT路由器控制功能一起使用,让事情走上正轨。有时候,我们所使用的路由器并不支持NAT-PMP或UpnP,或者更糟糕的是它声称支持其中的一种或两种,但因为固有的破坏,或某些致命的陷阱组合,实际上根本不起作用。

        FreeSWITCH启动时,可以加上-nonat选项来禁用这个功能。当这个功能被禁用时,我们仍然有些技巧可用。如果你已经知道公网使用的静态IP,可以把它设置给上面描述的两个参数。更好的是,你可以将其设置为autonat:x.x.x.x(其中x.x.x.x应替换为你的公共IP),这样它使用您已知的外部IP,并且仍然具有一些动态魔力。

ext-sip-ip="auto-nat:194.20.24.1" ext-rtp-ip="auto-nat:194.20.24.1"

 

设置外部地址的其它方法

        你可以使用动态DNS或STUN服务,指向host:my.domain.com或stun:stun.myhost.com (其中 my.domain.com 或 stun.myhost.com 分别对应你自己的动态域名或STUN服务器),按需查询。这个方案也有缺点,它会降低处理速度甚至停止工作。和往常一样,我们已经默认提供了最好的选项,但是你仍然应该了解其他选项。如果你能够控制路由器,那么你可以建立持久的NAT映射,把特定的流量直接路由给FreeSWITCH或话机,这时ext-sip-ip 和 ext-rtp-ip就可以派上用场。此外,如果你有办法,可以使用VPN来路由两个彼此独立的网络,假设你可以控制两端的网络,那么你可以把它们都放到NAT之后。

 

在NAT环境中的其它创造性用法

可以把FreeSWITCH部署在设备之间,利用它解决NAT问题。你可以配置一台本地的FreeSWITCH,并让所有内部话机向它注册,然后把这个FreeSWITCH实例注册到SIP运营商那里,把它作为所有内部话机的跳板,利用它在NAT上开个洞,让所有人都开心。此外,你也可以把FreeSWITCH部署在公网上,然后让所有内部话机或分布式的其它FreeSWITCH实例向它注册,这样,即使所有局部平台都部署在NAT之后,它们间依然能够畅快自由地通信。

 

NAT 与 WebRTC (解决方案)

        WebRTC昨天才刚刚更新定义,实际上现在正在定义。它完全不受遗留缺陷的影响,特别是在处理NAT时。所以我们说用WebRTC传输解决了所有的NAT问题。

你在SIP profile中定义了ext-rtp-ip和ext-sip-ip,然后在verto.conf.xml中定义ext-rtp-ip,然后准备开始了。

        默认情况下,所有WebRTC客户端都使用ICE的魔力来确定如何连接,FreeSWITCH端也实现了这一点,它几乎可以确保信令和媒体的完美流通。

        如果您有一个非常奇怪的场景,例如您想在LAN内部使用WebRTC而不使用公网地址或DNS,那么你将需要实现自己的ICE/STUN服务器,并让WebRTC客户使用这些服务器。如果你有这样的项目经历,你可能已经知道你所需要的ICE基础设施了。

 

结论

        我们祝愿你在NAT世界的旅途一切顺利! 希望这一章能在你遇到困难或者准备与ALG战斗时派上用场。那真是太糟糕了!如果你记住了这一章中的所有内容,但仍然有问题,你可以随时上网向其他FreeSWITCH社区成员寻求帮助。最后一句能让你看起来很聪明的话是:如果下次有人抱怨他们的电话在开始30秒后被莫名其妙地挂断,那么是的,这就是一个NAT问题。如下图所示:


      在某些情况下,FreeSwitch无法解决这个问题,你需要修复或更换NAT设备。

 

总结

        这一章,我们识别了NAT的陷阱。哪怕只有一个读者能幸免于第一次遇到ALG或NAT路由器所带来的灼痛,那么我们的疯狂之旅就没有白费。

        我们还阐述了FreeSWITCH中用于缓解NAT相关问题的大部分选项。在我们继续讨论VoIP安全之前,我将为你留下更多的锦囊妙计,希望你能在NAT出现问题时正常工作。以下是你应该记住的小贴士:

  • 研究NAT的四个陷阱,并时刻关注它们
  • 很容易分心,成为其中一个陷阱的牺牲品。如果你发现花的时间太长了,重新开始,确保没有在某个地方犯错误,导致你误入歧途。
  • 试着做最少的必要改动让NAT工作
  • 你的NAT配置越混乱,就越容易出错或不兼容。在第二个陷阱的摆布下,很容易出现一端正常,另一端疯狂,来回往复的局面
  • 如果你有权限访问路由器,请将其配置为尽可能有利于NAT的设置
  • 让事情简化的最好方法就是调整环境,这样你就有了一个理想的环境。选择基本的NAT设置,并坚持默认设置,这些设置通常被调优为大多数情况下都是最佳的。

 

        下一章,我们将转移焦点,从克服NAT问题,转向改善VoIP安全的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章