iOS NetworkExtension.FrameWork

NetworkExtension

  1. NEAppProxyTCPFlow

  2. NEAppProxyUDPFlow

  3. NEAppProxyFlow

NEAppProxyFlow

  • NEAppProxyFlow 用于从网络套接字读取数据并向其写入数据。
  • 应用程序代理服务器接受网络连接,以NEAppProxyFlow对象的形式进行代理,这些对象通过以下方式传递给-[NEAppProxyProvider handleNewFlow:]方法。
  • NEAppProxyFlow对象最初处于未打开状态。在使用它们传输网络数据之前,必须使用openWithLocalEndPoint: completionHandler: 的方法打开它们。完成流程之后,你应该调用closeReadWithError: 和colseWriteWithError: 的方法然后释放NEAppProxyFlow对象。

管理流程的生命周期

  • openWithLocalEndpoint:completionHandler:
    打开流程,向系统指示主叫方已经准备好开始接收和发送数据流

  • closeReadWithError:
    关闭流程以进行进一步的读取操作

  • closeWriteWithError:
    关闭流程以进行进一步的写入操作

/*
* This header is generated by classdump-dyld 0.1
* on Wednesday, September 20, 2017 at 9:28:09 PM Eastern European Summer Time
* Operating System: Version 11.0 (Build 15A372)
* Image Source: /System/Library/Frameworks/NetworkExtension.framework/NetworkExtension
* classdump-dyld is free of use, Copyright © 2013 by Elias Limneos.
*/


@protocol OS_dispatch_queue;
#import <NetworkExtension/NetworkExtension-Structs.h>
@class NEFlowMetaData, NSObject, NSData;

@interface NEAppProxyFlow : NSObject {

    NEFlowMetaData* _metaData;
    NEFlowRef _flow;
    NSObject<OS_dispatch_queue>* _queue;

}

@property (assign) NEFlowRef flow;                               //@synthesize flow=_flow - In the implementation block
@property (retain) NSObject<OS_dispatch_queue>* queue;           //@synthesize queue=_queue - In the implementation block
@property (retain) NSData* applicationData; 
@property (readonly) NEFlowMetaData* metaData;                   //@synthesize metaData=_metaData - In the implementation block
+(id)flowErrorForVPNFlowError:(long long)arg1 ;
+(CFErrorRef)copyVPNFlowErrorFromFlowError:(id)arg1 ;
-(void).cxx_destruct;
-(void)dealloc;
-(unsigned long long)hash;
-(id)queue;
-(void)setQueue:(id)arg1 ;
-(NEFlowRef)flow;
-(void)clearEventHandlers;
-(id)initWithNEFlow:(NEFlowRef)arg1 queue:(id)arg2 ;
-(void)openWithLocalEndpoint:(id)arg1 completionHandler:(/*^block*/ id)arg2 ;
-(void)closeReadWithError:(id)arg1 ;
-(void)closeWriteWithError:(id)arg1 ;
-(void)setFlow:(NEFlowRef)arg1 ;
-(id)metaData;
-(void)setApplicationData:(id)arg1 ;
-(id)applicationData;
@end


NEAppProxyTCPFlow

NEAppProxyTCPFlow 继承自NEAppProxyFlow
NEAppProxyTCPFlow 用于从应用程序代理提供程序代理的TCP套接字中读取数据和将数据写入该套接字,应用程序代理服务器以NEAppProxyTCPFlow对象的形式接受TCP代理。

处理流量数据


- writeData:withCompletionHandler:

  • 写入流量数据
- readDataWithCompletionHandler:

  • 读取流量数据

获取流量信息

remoteEndpoint
一个NWEndPoint 对象,其中包含有关流的预期远程端点的信息。

NEAppProxyUDPFlow

官方文档


NEAppProxyUDPFlow is used to read data from and write data to a UDP socket that is being proxied by an App Proxy Provider.

NEAppProxyUDPFlow用于从应用程序代理提供程序代理的UDP套接字读取数据和写入数据。

读取信息流数据

  • readDatagramsWithCompletionHandler:

写入信息流数据

  • writeDatagrams:sentByEndpoints:completionHandler:

获取信息流信息
localEndPoint

/*
* This header is generated by classdump-dyld 0.1
* on Wednesday, September 20, 2017 at 9:28:09 PM Eastern European Summer Time
* Operating System: Version 11.0 (Build 15A372)
* Image Source: /System/Library/Frameworks/NetworkExtension.framework/NetworkExtension
* classdump-dyld is free of use, Copyright 漏 2013 by Elias Limneos.
*/

#import <NetworkExtension/NetworkExtension-Structs.h>
#import <NetworkExtension/NEAppProxyFlow.h>

@class NWEndpoint;

@interface NEAppProxyUDPFlow : NEAppProxyFlow {

    NWEndpoint* _localEndpoint;

}

@property (readonly) NWEndpoint* localEndpoint;           //@synthesize localEndpoint=_localEndpoint - In the implementation block
-(void).cxx_destruct;
-(id)description;
-(id)initWithNEFlow:(NEFlowRef)arg1 queue:(id)arg2 ;
-(void)openWithLocalEndpoint:(id)arg1 completionHandler:(/*^block*/ id)arg2 ;
-(id)localEndpoint;
-(void)readDatagramsWithCompletionHandler:(/*^block*/ id)arg1 ;
-(void)writeDatagrams:(id)arg1 sentByEndpoints:(id)arg2 completionHandler:(/*^block*/ id)arg3 ;
@end


利用Network Extension 改Host
https://www.jianshu.com/p/bac67bee0431

++++++++++++++++++++++++++++++

4. NEAppProxyProvider

5. NEAppProxyProviderManager

6. NEAppRule

NEAppProxyProvider

  • 该类为App Proxy Provider应用程序扩展创建一个主要类

  • NEAppProxyFlow对象的形式提供对网络数据流的访问。每个NEAppProxyFlow对象对应于由当前应用程序代理配置中指定的应用程序规则匹配的应用程序打开的套接字。你的App Proxy Provider作为其接受的网络数据流的透明网络代理。

  • 注意点:
    需要使用com.apple.developer.networking.networkextension授权才能使用NEAppProxyProvider类。在开发者账户中创建应用程序ID时启用此权限。

DNS处理

除了来自应用程序的原始网络数据流之外,App Proxy Provider还可以从NEAppProxyUDPFlow对象的形式接收DNS查询流。仅对使用低级DNS解析API(例如DNSServiceGetAddrInfo())的应用程序接收DNS查询流。App Proxy Provider可以使用setTunnelNetworkSettings:completionHandler:方法指定这些应用程序将使用的DNS解析器配置。
使用更高级网络API(如NSURLSession何NSURLConnection)的应用程序不会生成DNS查询。而是链接的目标主机名包含在NEAppProxyFlow对象的端点信息中。

创建App Proxy Provider扩展

App Proxy Provider以com.apple.networkextension.app-proxy扩展指示App Extensions运行。

要创建App Proxy Provider扩展,请先在项目中创建一个新的App Extension目标

一旦你有一个App Proxy Provider扩展目标,创建一个NEAppProxyProvider的子类。然后,将扩展后的info.plist中的NSExtensionPrincipalClass键设置为子类的名称。

如果尚未完成,请将扩展名的info.plist中的NSExtensionPointIdentifier键设置为com.apple.networkextension.app-proxy,如下图:

<key>NSExtension</key>
<dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.networkextension.app-proxy</string>
    <key>NSExtensionPrincipalClass</key>
    <string>MyCustomAppProxyProvider</string>
</dict>

最后,将App Proxy Provider 扩展目标添加到应用程序的"嵌入应用程序扩展"构建阶段。

子类注释
为了创建App Proxy Provider扩展,你必须创建NEAppProxyProvider的子类,并覆盖下列方法。

startProxyWithOptions:completionHandler:

启动网络代理

stopProxyWithReason:completionHandler:

停止网络代理

handleNewFlow:

从App Proxy Provider停止网络代理,并且该方法可以处理新的网络数据流

NEAppProxyProviderManager

  • 配置和控制由App Proxy provider应用程序扩展提供的网络隧道
    对象不能直接实例化。而是通过配置文件中的com.apple.vpn.managed.applayer有效内容专门创建App Proxy配置

  • App Proxy 配置只能与Per-App VPN路由规则一起使用。创建App Proxy配置和配置Per-App VPN,可参阅NETunnelProviderManager

  • 注意:需要使用需要使用com.apple.developer.networking.networkextension授权才能使用NEAppProxyProviderManager类。 在开发者帐户中创建应用程序ID时启用此权限

管理应用程序代理配置

  • loadAllFromPreferencesWithCompletionHandler:
    将与以前保存的呼叫应用程序相关联的所有App Proxy配置加载到网络分机首选项

NEAppRule

NEAppRule包含用于根据源应用程序匹配网络链接的规则的匹配条件。

相关的API

- initWithSigningIdentifier:

创建一个与具有给定签名标识符的应用程序相匹配的应用规则。

- initWithSigningIdentifier:designatedRequirement:

创建一个与具有给定签名标识符和给定指定要求的应用程序相匹配的应用规则

AppRule配置参数

matchSigningIdentifier

与规则匹配的应用程序的签名标识符

matchDesignatedRequirement

与规则匹配的应用程序的指定要求

matchPath

与规则匹配的应用程序的文件系统路径


matchDomains

与规则匹配的主机名域。

头文件

/*
* This header is generated by classdump-dyld 1.0
* on Thursday, December 22, 2016 at 6:08:29 PM Eastern European Standard Time
* Operating System: Version 10.1.1 (Build 14B100)
* Image Source: /System/Library/Frameworks/NetworkExtension.framework/NetworkExtension
* classdump-dyld is licensed under GPLv3, Copyright 漏 2013-2016 by Elias Limneos.
*/

#import <NetworkExtension/NetworkExtension-Structs.h>
#import <libobjc.A.dylib/NEConfigurationValidating.h>
#import <libobjc.A.dylib/NEPrettyDescription.h>
#import <libobjc.A.dylib/NEConfigurationLegacySupport.h>
#import <libobjc.A.dylib/NSSecureCoding.h>
#import <libobjc.A.dylib/NSCopying.h>

@class NSString, NSArray;

@interface NEAppRule : NSObject <NEConfigurationValidating, NEPrettyDescription, NEConfigurationLegacySupport, NSSecureCoding, NSCopying> {

    BOOL _noRestriction;
    BOOL _noDivertDNS;
    NSString* _matchSigningIdentifier;
    NSString* _matchDesignatedRequirement;
    NSString* _matchPath;
    NSArray* _matchDomains;
    NSArray* _additionalExecutables;
    NSArray* _matchAccountIdentifiers;

}

@property (copy) NSArray * additionalExecutables;                        //@synthesize additionalExecutables=_additionalExecutables - In the implementation block
@property (assign) BOOL noRestriction;                                   //@synthesize noRestriction=_noRestriction - In the implementation block
@property (copy) NSArray * matchAccountIdentifiers;                      //@synthesize matchAccountIdentifiers=_matchAccountIdentifiers - In the implementation block
@property (assign) BOOL noDivertDNS;                                     //@synthesize noDivertDNS=_noDivertDNS - In the implementation block
@property (readonly) NSString * matchSigningIdentifier;                  //@synthesize matchSigningIdentifier=_matchSigningIdentifier - In the implementation block
@property (readonly) NSString * matchDesignatedRequirement;              //@synthesize matchDesignatedRequirement=_matchDesignatedRequirement - In the implementation block
@property (copy) NSString * matchPath;                                   //@synthesize matchPath=_matchPath - In the implementation block
@property (copy) NSArray * matchDomains;                                 //@synthesize matchDomains=_matchDomains - In the implementation block
+(BOOL)supportsSecureCoding;
-(id)initWithCoder:(id)arg1 ;
-(void)encodeWithCoder:(id)arg1 ;
-(id)copyWithZone:(NSZone*)arg1 ;
-(BOOL)checkValidityAndCollectErrors:(id)arg1 ;
-(id)descriptionWithIndent:(int)arg1 options:(unsigned long long)arg2 ;
-(id)copyLegacyDictionary;
-(NSString *)matchSigningIdentifier;
-(id)initFromLegacyDictionary:(id)arg1 ;
-(NSArray *)matchDomains;
-(void)setMatchDomains:(NSArray *)arg1 ;
-(BOOL)overlapsWithRule:(id)arg1 ;
-(NSArray *)additionalExecutables;
-(id)initWithSigningIdentifier:(id)arg1 ;
-(NSString *)matchPath;
-(void)setMatchPath:(NSString *)arg1 ;
-(NSArray *)matchAccountIdentifiers;
-(void)setMatchAccountIdentifiers:(NSArray *)arg1 ;
-(BOOL)noRestriction;
-(void)setNoRestriction:(BOOL)arg1 ;
-(void)setNoDivertDNS:(BOOL)arg1 ;
-(BOOL)noDivertDNS;
-(BOOL)signingIdentifierAllowed:(id)arg1 domainsRequired:(out BOOL*)arg2 ;
-(NSString *)matchDesignatedRequirement;
-(void)setAdditionalExecutables:(NSArray *)arg1 ;
@end


  1. NEDNSProxyManager
  2. NEDNSProxyProvider
  3. NEDNSProxyProviderProtocol
  4. NEDNSSettings

NEDNSProxyManager

  • 管理DNS代理的对象

  • DNS代理允许你的应用拦截设备上生成的所有DNS流量,你可以使用此功能提供DNS流量加密等服务,通常是将DNS流量重定向到你自己的服务器。你通常在托管设备的上下文中执行此操作。

  • 你可以基于ENDNSProxyProvider 类的自定义子类创建DNS代理作为应用程序扩展,你可以使用NEDNSProxyManager类的sharedManager类型方法提供的单例代理管理器实例在应用程序中启用和配置此代理。例如,对于执行简单重定向的代理,你可以使用代理管理器来定义和动态配置重定向流量的目标IP地址。

  • 使用NEDNSProxyManager,Xcode需要配置capability.


    image.png

相关API

创建一个DNS代理的单例

+sharedManager

加载一个DNS代理的配置的回调

- (void)loadFromPreferencesWithCompletionHandler:(void (^)(NSError *error))completionHandler;

保存一个DNS代理的completionHandler


- (void)saveToPreferencesWithCompletionHandler:(void (^)(NSError *error))completi   onHandler;

移除


- (void)removeFromPreferencesWithCompletionHandler:(void (^)(NSError *error))completionHandler;

NEDNSProxyProvider

  • DNS代理允许你的应用拦截设备上生成的所有DNS流量。你可以使用此公布功能提供DNS流量加密等服务,通常是将DNS流量重定向到你自己的服务器。你通常在托管设备的上下文中执行此操作

  • 你可以基于NEDNSProxyProvider类的自定义子类创建DNS代理作为应用程序扩展。一旦激活,代理就会以NEAppProxyFlow实例的形式接收对DNS流量的访问。每个流对应于应用程序打开的套接字到UDP端口或TCP端口,你的DNS代理提供程序充当它接收的网络数据流的DNS代理。

相关API

  • 启动DNS 代理

- (void)startProxyWithOptions:(NSDictionary<NSString *,id> *)options 
            completionHandler:(void (^)(NSError *error))completionHandler;


  • 停止DNS代理

- (void)stopProxyWithReason:(NEProviderStopReason)reason 
          completionHandler:(void (^)(void))completionHandler;

  • 取消DNS代理
- (void)cancelProxyWithError:(NSError *)error;

image.png
image.png

image.png

配置证书的时候,要创建两个bundle ID 同时要有两个证书

image.png

第二个证书的格式应该是app的Target的Bundle ID + 扩展的target名字


image.png

参考
How to use NEDNSProxyProvider in iOS 11

iOS11中网络层的一些变化(Session707&709脱水版)

利用Network Extension 改Host

什么是扩展

NEDNSProxyProviderProtocol

  • NEDNSProxyProviderProtocol DNS代理提供的网络扩展的配置设置
  • NEDNSProxyProviderProtocol 类头文件如下:
/*
* This header is generated by classdump-dyld 0.1
* on Wednesday, September 20, 2017 at 9:28:10 PM Eastern European Summer Time
* Operating System: Version 11.0 (Build 15A372)
* Image Source: /System/Library/Frameworks/NetworkExtension.framework/NetworkExtension
* classdump-dyld is free of use, Copyright 漏 2013 by Elias Limneos.
*/

#import <NetworkExtension/NetworkExtension-Structs.h>
#import <NetworkExtension/NEVPNProtocol.h>

@class NSDictionary, NSString;

@interface NEDNSProxyProviderProtocol : NEVPNProtocol {

    NSDictionary* _providerConfiguration;
    NSString* _providerBundleIdentifier;
    NSString* _pluginType;

}

@property (copy) NSString* pluginType;                          //@synthesize pluginType=_pluginType - In the implementation block
@property (copy) NSDictionary* providerConfiguration;           //@synthesize providerConfiguration=_providerConfiguration - In the implementation block
@property (copy) NSString* providerBundleIdentifier;            //@synthesize providerBundleIdentifier=_providerBundleIdentifier - In the implementation block
+(bool)supportsSecureCoding;
-(id)providerBundleIdentifier;
-(id)providerConfiguration;
-(id)init;
-(void).cxx_destruct;
-(id)initWithCoder:(id)arg1 ;
-(void)encodeWithCoder:(id)arg1 ;
-(id)copyWithZone:(NSZoneRef)arg1 ;
-(bool)checkValidityAndCollectErrors:(id)arg1 ;
-(id)descriptionWithIndent:(int)arg1 options:(unsigned long long)arg2 ;
-(void)setPluginType:(id)arg1 ;
-(id)initWithPluginType:(id)arg1 ;
-(id)pluginType;
-(void)setProviderBundleIdentifier:(id)arg1 ;
-(void)setProviderConfiguration:(id)arg1 ;
@end


参考:How to use NEDNSProxyProvider in iOS 11

如何在iOS 11中使用NEDNSProxyProvider

NEDNSSettings

  • NEDNSSettings主要对DNS解析器设置。

相关的API

初始化NEDNSSetting对象


- (instancetype)initWithServers:(NSArray<NSString *> *)servers;

DNS服务器IP地址。

@property(readonly) NSArray<NSString *> *servers;

用于完全限定单标签主机名的域字符串列表

@property(copy) NSArray<NSString *> *searchDomains;

域名

@property(copy) NSString *domainName;

一个布尔值,指定matchDomains列表中的域是否不应附加到解析程序的搜索域列表中。

@property BOOL matchDomainsNoSearch;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容