We gets NEPacket during packetFlow.readPacketObjects. Each packet contains src ip as packet tunnel utun virtual interface address.
for example if packet tunnel utun address is 10.10.10.10, then src ip of every packet is 10.10.10.10.
Can we configure packet tunnel in such a way that it gives src ip as ip assigned to system via dhcp/static (primary Ethernet interface en0) instead of 10.10.10.10? I want to do this because tunnel server uses this src ip to perform some business logic.
What if we assigns primary Ethernet interface en0 address to packet tunnel utun address?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi,
I want to know if i can ask NEPacketTunnelProvider to reroute traffic from virtual utun to physical interface?
Let me break it down:
As per includedRoutes, Traffic came on NEPacketTunnelProvider virtual interface(utun).
After parsing packet if in case for some condition matches (such as port number etc), i want to route it via physical interface. Can we achieve this?
Raw Socket can't be opened in System Extension hence i can't go via this route.
I don't see any ways in NEPacketTunnelProvider / NEPacketTunnelNetworkSettings to achieve this.
Hi,
We have following settings for NEPacketTunnelProvider with include rules having all IPv4 network traffic be routed. Exclude rule having 8.8.8.8 & 10.212.24.222. In this case dns request packets are not going out.
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "xxxxx")
settings.ipv4Settings = NEIPv4Settings(addresses: ["10.10.10.10"], subnetMasks: ["255.255.255.255"])
settings.ipv4Settings?.includedRoutes = [NEIPv4Route(destinationAddress: "0.0.0.0", subnetMask: "0.0.0.0")]
or the below one
settings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()]
settings.ipv4Settings?.excludedRoutes = [
NEIPv4Route(destinationAddress: "8.8.8.8", subnetMask: "255.255.255.255"),
NEIPv4Route(destinationAddress: "10.212.24.222", subnetMask: "255.255.255.255")]
settings.mtu = 1500
If we are changing tunnel settings as below, then dns request packets are coming out in pcap dumps.
settings.ipv4Settings?.includedRoutes = [
NEIPv4Route(destinationAddress: "10.0.0.0", subnetMask: "255.0.0.0"),
NEIPv4Route(destinationAddress: "8.0.0.0", subnetMask: "255.0.0.0")
]
settings.ipv4Settings?.excludedRoutes = [
NEIPv4Route(destinationAddress: "8.8.8.8", subnetMask: "255.255.255.255"),
NEIPv4Route(destinationAddress: "10.212.24.222", subnetMask: "255.255.255.255")]
Why the former 0.0.0.0 / defaultcase not working? How to include all traffic be routed in packet tunnel by excluding selective traffic?
Hi,
We have NEPacketTunnelProvider which creates a virtual interface.
I am trying to Read and write virtual interface in separate process(c++ command line project). Read works fine, but write is not working.
Reading packet in separate process as below:
int bpf = 0;
for (int i = 0; i < 99; ++i) {
snprintf(buf, 11, "/dev/bpf%i", i);
bpf = open(buf, O_RDWR);
if (bpf != -1) break;
}
struct ifreq interface;
strcpy(interface.ifr_name, interfaceName.c_str());
if(ioctl(bpf, BIOCSETIF, &interface) > 0) {
return errno;
}
unsigned int one = 1;
if (ioctl(bpf, BIOCIMMEDIATE, &one) == -1) {
return errno;
}
int bufLength = 1;
if (ioctl(bpf, BIOCGBLEN, &bufLength) == -1) {
return errno;
}
if (ioctl(bpf, BIOCPROMISC, NULL) == -1) {
return errno;
}
//Reading bpf as below
readBytes = (int)read(bpf, bpfBuffer, bufLength);
**Whenever traffic routed to Packet Tunnel provider interface as per network rule, Read works fine in this process(separate c++ process). We are able to read valid packet.
**
//Writing as below
ssize_t writtenBytes = write(bpf, packet, size);
if (writtenBytes < 1)
{
return false;
} else {
return true;
}
Above write API is not giving any error, returning byte written correctly.
But after write, packet is not reaching to application which generated traffic. For example, for ping, it is showing 1 packets transmitted, 0 packets received, 100.0% packet loss
I also tried sending it over raw socket. Since separate process is command line and not sandboxed, raw socket getting openned.
`ssize_t bytes = sendto (fRawSocket, packet, size, 0, (sockaddr*) dest, sizeof(*dest)); //dest is packet tunnel virtual interface ip addres`
This also not returning any error but this packet is also not reaching to application which generated traffic.
There is packetFlow.writePacketObjects which works fine in swift.
but due to some architecture constraint, i am reading and writing packet in separate process.
is this something macOS doesn't allow or i am doing something wrong?
Hi,
I have a dynamic library libmowglicore.dylib, which works fine in non sandboxed enviroment(command line cpp project). libmowglicore.dylib is signed, it shows valid on disk.
When i add it to network extension project, network extension getting crash on launch.
0 dyld 0x102c8e81c dyld3::MachOFile::compatibleSlice(Diagnostics&, void const*, unsigned long, char const*, dyld3::Platform, bool, dyld3::GradedArchs const&) + 76
1 dyld 0x102c72b9c invocation function for block in dyld4::JustInTimeLoader::makeJustInTimeLoaderDisk(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, bool, unsigned int) + 96
2 dyld 0x102c72b9c invocation function for block in dyld4::JustInTimeLoader::makeJustInTimeLoaderDisk(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, bool, unsigned int) + 96
3 dyld 0x102c77fcc dyld4::SyscallDelegate::withReadOnlyMappedFile(Diagnostics&, char const*, bool, void (void const*, unsigned long, bool, dyld4::FileID const&, char const*) block_pointer) const + 132
4 dyld 0x102c72b08 dyld4::JustInTimeLoader::makeJustInTimeLoaderDisk(Diagnostics&, dyld4::RuntimeState&, char const*, dyld4::Loader::LoadOptions const&, bool, unsigned int) + 204
Crash Dumps
How to debug it?
Hi,
AFAIK Safari or any macOS apps which uses WKWebview, uses com.apple.WebKit.Networking.xpc to do actual networking.
I am working on a packet tunnel, where I am able to get process id associated with packet read. Based on process id, i am using libproc to get process name.
I am facing below problem:
For Safari or any other apps which uses WKWebview having same process name: com.apple.WebKit.Networking
Any ways to distinguish wether it is from safari or other xyz wkwebview apps?
Related Problem: https://developer.apple.com/forums/thread/693528 In this thread, app proxy can help but in packet tunnel no such options exposed.
I want to understand in which API triggers this below popup.
1.
This below code always trigger popup after fresh install which make sense:
`//manager NETunnelProviderManager
manager.connection.startVPNTunnel(options: [:])`
2. This below code sometime triggers popup intermittently. Ideally this shouldn't trigger or always trigger.
I tried running this code in loop to check this behaviour, some time around 50th or sometime around 88th execution observed this popup.
config.providerBundleIdentifier =“bundleId”
config.serverAddress = "Connection managed by app”Name//
let manager = NETunnelProviderManager()
manager.protocolConfiguration = config
manager.localizedDescription = “xyz”
manager.saveToPreferences(completionHandler: { (saveError) -> Void in
}```
no where startVPNTunnel called in 2nd code sample.
I’m using an NETransparentProxyProvider where I add UDP-53 rules to intercept DNS queries from a private application. These queries are resolved locally on the endpoint by returning a custom DNS response.
Example Rules look like this:
NENetworkRule(destinationHost: NWHostEndpoint(hostname: "mypaapp.com", port: 53),protocol:.UDP)
This works as expected through browser and ping.
handleNewUDPFlow/handleNewFlow with NEAppProxyUDPFlow gets called where custom dns response get written.
Using nslookup mypaapp.com doesn't works.
Why does this behaves differently for nslookup?
Hi, I have applied below rule
let filterRules = ["0.0.0.0", "::"].map { address -> NEFilterRule in
let localNetwork = NWHostEndpoint(hostname: address, port: "0")
let networkRule = NENetworkRule(remoteNetwork: nil,
remotePrefix: 0,
localNetwork: localNetwork,
localPrefix: 0,
protocol: .TCP,
direction: .any)
return NEFilterRule(networkRule: networkRule, action: .filterData)
}
I have written below code in method: override func handleInboundData
if remoteEndpoint.hostname == "10.207.135.79" {
os_log(.debug, log: self.log, "dropping for 10.207.135.79.");
return .drop()
}
From device 10.207.135.79 i am trying to send TCP as below:
1. ssh userName@10.213.175.1
It is getting drop as expected. kex_exchange_identification: Connection closed by remote host
2. Send via netcat(nc) nc 10.213.175.1 8888
During netcat, it's not getting drop.
3. Send via curl(nc) curl 10.213.175.1:8888
During curl, it's not getting drop.
10.213.175.1 is IP where system extension filter provider running.
is this expected behaviour?
Hi,
I am experiencing following crashes intermittently in macOS network extension. Sometime in an hour or two or three. I don't see anywhere references to my project code hence i am unable to understand this crashes. Anyone please point me into right direction from here:
Crash Dumps
Samples:
Process: com.skyhighsecurity.epclient.networkextension [39224]
Path: /Library/SystemExtensions/*/com.skyhighsecurity.epclient.networkextension
Identifier: com.skyhighsecurity.epclient.networkextension
Version: 1.0 (1)
Code Type: ARM-64 (Native)
Parent Process: launchd [1]
User ID: 0
Date/Time: 2023-03-20 13:46:51.6991 +0530
OS Version: macOS 12.6.3 (21G419)
Report Version: 12
Anonymous UUID: 72617D4C-9E91-7141-D71D-9CB5BDADAA25
Sleep/Wake UUID: B462FD28-68B4-4B46-84EB-D16E29760748
Time Awake Since Boot: 32000 seconds
Time Since Wake: 5 seconds
System Integrity Protection: disabled
Crashed Thread: 3 Dispatch queue: NEFilterExtensionProviderContext queue
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000182e26104
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace SIGNAL, Code 5 Trace/BPT trap: 5
Terminating Process: exc handler [39224]
Application Specific Information:
BUG IN CLIENT OF LIBPLATFORM: os_unfair_lock is corrupt
Abort Cause 1949042982
Thread 0:
0 libsystem_kernel.dylib 0x182dd5d70 __sigsuspend_nocancel + 8
1 libdispatch.dylib 0x182c5b5e0 _dispatch_sigsuspend + 48
2 libdispatch.dylib 0x182c5b5b0 _dispatch_sig_thread + 60
Thread 1:
0 libsystem_pthread.dylib 0x182e07078 start_wqthread + 0
Thread 2:
0 libsystem_pthread.dylib 0x182e07078 start_wqthread + 0
Thread 3 Crashed:: Dispatch queue: NEFilterExtensionProviderContext queue
0 libsystem_platform.dylib 0x182e26104 _os_unfair_lock_corruption_abort + 88
1 libsystem_platform.dylib 0x182e21184 _os_unfair_lock_lock_slow + 328
2 libsystem_pthread.dylib 0x182e07640 pthread_mutex_destroy + 64
3 Foundation 0x183d7ac18 -[_NSXPCConnectionClassCache dealloc] + 48
4 libobjc.A.dylib 0x182cb7c58 objc_object::sidetable_release(bool, bool) + 260
5 NetworkExtension 0x19148b798 -[NEFilterSocketFlow .cxx_destruct] + 40
6 libobjc.A.dylib 0x182c9d8e4 object_cxxDestructFromClass(objc_object*, objc_class*) + 116
7 libobjc.A.dylib 0x182c94b0c objc_destructInstance + 80
8 libobjc.A.dylib 0x182c94ab8 _objc_rootDealloc + 80
9 NetworkExtension 0x19148246c -[NEFilterDataExtensionProviderContext handleSocketSourceEventWithSocket:] + 132
10 libdispatch.dylib 0x182c481b4 _dispatch_client_callout + 20
11 libdispatch.dylib 0x182c4b670 _dispatch_continuation_pop + 500
12 libdispatch.dylib 0x182c5e8e0 _dispatch_source_invoke + 1596
13 libdispatch.dylib 0x182c4f784 _dispatch_lane_serial_drain + 376
14 libdispatch.dylib 0x182c50404 _dispatch_lane_invoke + 392
15 libdispatch.dylib 0x182c5ac98 _dispatch_workloop_worker_thread + 648
16 libsystem_pthread.dylib 0x182e08360 _pthread_wqthread + 288
17 libsystem_pthread.dylib 0x182e07080 start_wqthread + 8
I have a system extension which contains 3 capabilities: App Proxy, Content Filter, Packet Tunnel.
System extension process doesn't auto stops on disabling all of its Capabilities: App Proxy, Content Filter, Packet Tunnel
How to make system extension process auto stop if all of its capabilities disabled?
Disable can happens via system extension hosting app or system preference network settings
I have following in mind:
Whenever we disables any capabilities via system extension hosting app, it can check if all others are disabled then
Use KILL bash command to terminate system extension process
System extension hosting app can send message via XPC to extension to terminate it self via NSApp.terminate
On disabling from system preference, ssystem extensions can check if all other disables in delegate method and terminate itself
I wanted to know what is better way to handle system extension process stop
my macOS process is crashing when i keep my mac sleep for about 1 hour.
Under Crash Reports, Console app shows two type of file.
.diag type
.ips type
ips file doesn't shows exact line of crash as you can see below sample.
Thread 67 Crashed:
0 libsystem_kernel.dylib 0x19a4aea60 __pthread_kill + 8
1 libsystem_pthread.dylib 0x19a4e6c20 pthread_kill + 288
2 libsystem_c.dylib 0x19a3f3a30 abort + 180
3 libsystem_malloc.dylib 0x19a303dc4 malloc_vreport + 896
4 libsystem_malloc.dylib 0x19a307430 malloc_report + 64
5 libsystem_malloc.dylib 0x19a321494 find_zone_and_free + 528
6 Firewall.so 0x103c8a744 TunnelSendQueue::ResumeSend() + 460
resource.diag file sgowing warning about exceeding limit of 150 wakeups per second over 300 seconds. attached here.
reasource_consumptions_W36RNW09G.wakeups_resource_diag.txt
is this something macOS stopping app because of some resource consumptions?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
macOS
System Extensions
Security Foundation
We have a NEFilterDataProvider extension that intercepts all TCP and UDP IPv4/6 traffic. At times just after wakeup from sleep, it causes internet access issues, such as showing "This site can't be reached" when opening websites.
The traffic is not being dropped by the extension.
According to the logs, the connection is being closed after approximately 4 minutes.
During the issue, the flow logs are as follows:
Flow 515129771 is connecting
New flow: NEFlow type = stream, app = com.google.Chrome.helper...
Detaching, ref count = 2 (logged after ~4 minutes)
Sending close, how = 2
Removing from group 2, ref count = 2
Destroying, app tx 0, tunnel tx 0, tunnel rx 0
Closing reads, not closed by plugin
Closing writes, not sending close
Any suggestions on the possible cause and how to further debug it?
I haven’t come across any official documentation regarding the limit on the number of Network Extensions macOS can run. However, I did see some discussions suggesting that Apple might restrict this to 5 extensions in macOS Tahoe.
Is there any official confirmation on this?
I am trying to pause NEFilterFlow and then resuming NEFilterFlow from function **handleInboundData**
let goingToApply = someFunctionWithClosure { applied in
if applied {
let verdict: NEFilterNewFlowVerdict = .allow()
self.resumeFlow(flow, with: verdict)
}
}
if goingToApply == true {
return .pause()
}
The line self.resumeFlow(flow, with: verdict) crashing with following exception:
terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NEFilterNewFlowVerdict passBytes]: unrecognized selector sent to instance 0x10b8662a0'
Crash dump showing below logs:
Thread 3 Crashed:: Dispatch queue: NEFilterExtensionProviderContext queue
0 libsystem_kernel.dylib 0x1b7aa6d78 __pthread_kill + 8
1 libsystem_pthread.dylib 0x1b7adbee0 pthread_kill + 288
2 libsystem_c.dylib 0x1b7a16340 abort + 168
3 libc++abi.dylib 0x1b7a96b18 abort_message + 132
4 libc++abi.dylib 0x1b7a86a54 demangling_terminate_handler() + 336
5 libobjc.A.dylib 0x1b797c320 _objc_terminate() + 144
6 libc++abi.dylib 0x1b7a95eb4 std::__terminate(void (*)()) + 20
7 libc++abi.dylib 0x1b7a95e50 std::terminate() + 64
8 libdispatch.dylib 0x1b79181c8 _dispatch_client_callout + 40
9 libdispatch.dylib 0x1b791f8a8 _dispatch_lane_serial_drain + 668
10 libdispatch.dylib 0x1b7920404 _dispatch_lane_invoke + 392
11 libdispatch.dylib 0x1b792ac98 _dispatch_workloop_worker_thread + 648
12 libsystem_pthread.dylib 0x1b7ad8360 _pthread_wqthread + 288
13 libsystem_pthread.dylib 0x1b7ad7080 start_wqthread + 8
Why this exception is occurring for .allow() verdict only. For .drop() it is not crashing.
No where i'm calling passBytes method on NEFilterNewFlowVerdict