ios - 为什么无法通过iOS的网络扩展隧道提供程序正确路由流量?

标签 ios objective-c iphone networking vpn

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

我可以使工作正常进行,以便将iPhone设备映射到地址192.168.2.2,然后可以从同一IP地址访问在tunnel_server(在macbook pro上运行)本地运行的apache网络服务器。我认为这证明了隧道正在正常工作,因为通常我无法从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:

我尝试在使用tunnelSharp的计算机上使用WireShark并检查utun2接口,当我尝试通过192.168.2.2(分配的地址)从iPhone上访问服务器计算机本身时,可以看到流量进入。

但是,我在此接口上看不到其他任何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规则,但是尝试了许多不同的操作后,没有任何效果。

最佳答案

从您的帖子中我不能完全确定,但是如果您使用的是Macbook,并且手机顶部有VPN图标,则表示隧道已建立,但无法通过手机访问网络-这可能意味着您的Mac上存在路由问题。

这就是我解决的方法...

  • tunnel_server / config.plist
    <?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> 
    
  • 配置NAT
    sudo vi /etc/pf.conf
    

    添加以下内容:
    nat-anchor "simpleTunnel"  
    load anchor "simpleTunnel" from "/etc/pf.anchors/simpleTunnel"  
    

    在记住pf.conf的顺序时,需要在其中进行设置。

    因此,添加后,我的看起来像这样:(在灌丛锚点之后添加了规则)
    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/*"
    
  • 编辑:
    sudo vi /etc/pf.anchors/simpleTunnel
    nat on en0 from 10.10.0.0/16 to any -> en0 
    
  • 运行以下命令:
    sudo sysctl net.inet.ip.forwarding=1  
    sudo sysctl net.inet.ip.fw.enable=1  
    sudo pfctl -evf /etc/pf.conf  
    
  • 现在响应可以到达en0

  • 让我知道是否有帮助。

    关于ios - 为什么无法通过iOS的网络扩展隧道提供程序正确路由流量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35558376/

    相关文章:

    iphone - 使用 AVAudioPlayer 快进歌曲

    ios - CLLocationManager 无法获取用户在设备中的位置,但无法在模拟器中获取

    ios - 想要 UITableView 到 "snap to cell"

    iphone - UICollectionView - 类似 iOS7 日历的缩放过渡

    ios - iOS 7 Matchismo作业1斯坦福的问题

    iphone - 从 plist 读取对象到 NSArray

    iphone - 确定 iPhone Screen Tapped 是否在区域中?

    iphone - 如何停止在 mkmapview 中滚动?

    ios - 通过 AVAudioMix 导出带有淡入淡出的 AVAsset

    ios - 从 Genric BLE 扫描仪应用程序中隐藏 BLE 设备