为什么流量没有通过iOS的网络扩展隧道提供商正确路由?

时间:2016-02-22 16:08:46

标签: ios objective-c iphone networking vpn

我正在尝试iOS的网络扩展隧道提供程序,它使用NETunnelProviderManager和相关的类,以及Apple的示例提供程序SimpleTunnel,它与测试服务器tunnel_server一起使用。

我可以让工作正常工作,以便将我的iPhone设备映射到地址192.168.2.2,然后我就可以在tunnel_server上运行本地运行的apache web服务器(在我的macbook pro上运行) IP地址。我相信这证明隧道正在工作,因为通常我无法从我的iPhone访问192.168.2.2(虽然我可以从不同的电子邮件地址访问同一个macbook pro)。此外,当我在客户端和服务器端添加日志记录时,我可以看到此情况下的TCP / IP数据包流动。

但是,当我尝试从同一个iPhone访问yahoo.com时(保持我的VPN连接),它无法访问。然后我测试了从我的手机ping一个yahoo.com地址(例如98.138.253.109),当VPN启动时我无法达到。这就解释了为什么DNS解析不能在iPhone上运行。我似乎也无法通过iPhone访问任何其他地址。

奇怪的是,对于这些不起作用的情况,没有数据包流经tunnel_server或扩展提供程序中的日志记录。因此,即使我没有指定任何此类限制,流量现在也受到限制。

如果有人知道如何进一步分类,请告诉我。

更新:

我确认SimpleTunnel程序正在添加默认路由,以便来自iPhone的所有IP流量都路由到隧道中(这在PacketTunnelProvider.swift:createTunnelSettingsFromConfiguration(...)中完成)。

通过这条路线,我有效地看到设备上的所有流量都被阻止了,好像它正试图路由它但在它到达隧道之前在某处丢失,因为我没有看到它在扩展(特别是在ClientTunnelConnection.swift:handlePackets())。

由于它显然没有到达服务器端,我很确定在这方面没有问题,这在客户端留下了一些配置。但是,我不确定在哪里看。

更新2:

我尝试在使用tunnel_server并检查utun2接口的机器上使用WireShark,当我尝试通过192.168.2.2(指定的地址)从我的iPhone访问服务器机器时,我可以看到流量进入。 / p>

但是,我在此界面上没有看到太多其他TCP或ICMP流量。例如,如果我尝试从我的iPhone ping我的一个DNS服务器(使用它的IP地址),我看不到在utun2接口上打包任何ICMP。

我也尝试将分配的地址从192.168.2.2更改为与我的服务器(10.15.68.160)在同一子网上的地址10.15.68.200,但没有运气。

这就是生成的utun2接口在服务器端的样子:

utun2: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
    inet 10.15.68.200 --> 10.15.68.200 net mask 0xfffff800

我还发现this post暗示了一个类似的问题,但它并没有太大的帮助。

更新3:

我在iPhone的日志中发现这些条目就在隧道连接的时候。我觉得它们可能与事情不起作用的原因有关,但不确定究竟发生了什么。

Feb 23 09:28:06 iPhone PacketTunnel[1260] <Warning>: Tunnel connection state changed to Connecting
Feb 23 09:28:06 iPhone networkd[97] <Error>: -[NETClient sendMessage:replyHandler:] attempting to send an XPC message to a suspended client PacketTunnel.1260! This is a bug!
Feb 23 09:28:06 iPhone configd[38] <Notice>: network changed
Feb 23 09:28:06 iPhone PacketTunnel[1260] <Warning>: Tunnel connection state changed to Connected
Feb 23 09:28:06 iPhone configd[38] <Notice>: network changed: v4(utun0+:10.15.68.200, en0, pdp_ip0) DNS! Proxy!

Feb 23 09:28:06 iPhone networkd[97] <Error>: __42-[NETClientConnection     evaluateNetworkPath]_block_invoke apsd.103 connection 75: trigger network agents (<NULL>) error Error Domain=NWPathEvaluatorErrorDomain Code=1 "(null)"
Feb 23 09:28:06 iPhone networkd[97] <Error>: __42-[NETClientConnection evaluateNetworkPath]_block_invoke com.apple.Safar.1236 connection 4: trigger network agents (<NULL>) error Error Domain=NWPathEvaluatorErrorDomain Code=1 "    (null)"
Feb 23 09:28:06 iPhone networkd[97] <Error>: __42-[NETClientConnection evaluateNetworkPath]_block_invoke com.apple.Safar.1236 connection 5: trigger network agents (<NULL>) error Error Domain=NWPathEvaluatorErrorDomain Code=1 "(null)"
Feb 23 09:28:06 iPhone nesessionmanager[355] <Notice>: NESMVPNSession[Demo VPN:296CC30E-E2BD-4C73-8C29-E5264E9C4285]: status changed to connected

更新4:

使用iPhone上的“IT工具”应用程序查看路由表显示以下内容:(仅显示IPv4路由的顶部)

default        link#16       utun0   UCS
default        10.15.64.1    en0     UGSci
10.15.64.0/21  link#8        en0     UCS
10.15.64.1/32  link#8        en0     UCS
...
10.15.68.200   10.15.68.200  utun0   U
...

第一个奇怪的是,有两个默认网关,似乎永远不会发生。话虽如此,第一个网关是utun0,这是我所期望的,虽然我没有看到所有流量进入网络隧道提供商扩展。这些路由中的最后一个似乎是唯一正在工作的路由,因为我实际上可以看到进入该IP地址的数据包通过隧道。

更新5:

我发现流量实际上是从我的服务器上的utun2到en0,但由于某种原因没有从外面回到服务器。查看源IP地址显示数据包没有正确出现,因为它们的源地址仍然是192.168.2.2

通过将以下规则添加到pf.conf(对于pfctl),我能够在那里工作,以便将源地址更改为我服务器的地址:

nat on en0 inet from !(en0) to any -> (en0)

现在我实际上看到来自我的最终目的地的返回数据包进入en0。但是,我没有看到这些路由回到utun2。似乎我可能需要添加另一个NAT规则,但在尝试了许多不同的东西之后,没有任何作用。

1 个答案:

答案 0 :(得分:0)

我对你的帖子不是很确定,但是如果你在macbook上运行并且你的手机顶部有VPN图标,这意味着隧道已经建立,但无法访问网络手机 - 这可能意味着你的Mac上存在路由问题。

这就是我修复它的方法......

  1. tunnel_server / config.plist

    Account
  2. 配置NAT

    <?xml version="1.0" encoding="UTF-8"?>  
    <!DOCTYPE plist PUBLIC "-/  
    <plist version="1.0">  
    <dict>  
      <key>IPv4</key>  
      <dict>  
      <key>Routes</key>  
      <array>  
      <dict>  
      <key>Netmask</key>  
      <string>255.255.255.0</string>  
      <key>Address</key>  
      <string>10.10.5.0</string>  
      </dict>  
      </array>  
      <key>Pool</key>  
      <dict>  
      <key>EndAddress</key>  
      <string>10.10.5.10</string>  
      <key>StartAddress</key>  
      <string>10.10.5.3</string>  
      </dict>  
      </dict>  
    </dict>  
    </plist> 
    

    添加以下内容:

    sudo vi /etc/pf.conf
    

    虽然请记住pf.conf有一个订单,但需要进行设置。

    所以在添加之后,我看起来像这样:(在擦洗锚之后添加规则)

    nat-anchor "simpleTunnel"  
    load anchor "simpleTunnel" from "/etc/pf.anchors/simpleTunnel"  
    
  3. 编辑:

    scrub-anchor "com.apple/*"
    nat-anchor "simpleTunnel"
    load anchor "simpleTunnel" from "/etc/pf.anchors/simpleTunnel"
    nat-anchor "com.apple/*"
    rdr-anchor "com.apple/*"
    dummynet-anchor "com.apple/*"
    anchor "com.apple/*"
    
  4. 运行以下命令:

    sudo vi /etc/pf.anchors/simpleTunnel
    nat on en0 from 10.10.0.0/16 to any -> en0 
    
  5. 现在回复可以到达en0

  6. 如果有帮助,请告诉我。