Hi All,
I am working on a macOS System Extension using Apple’s Network Extension Framework, designed to observe and log network activity at multiple layers. The system extension is currently stable and working as expected for HTTP and DNS traffic with 3 providers, getting Socket, HTTP, and DNS logs.
Current Architecture Overview
The project consists of two Xcode targets:
1. Main App Process
Responsible for:
Managing system extension lifecycle (activation, configuration)
Establishing IPC (XPC) communication with extensions
Receiving structured logs from extensions
Writing logs efficiently to disk using a persistent file handle
Uses:
OSSystemExtensionManager
NEFilterManager, NETransparentProxyManager, NEDNSProxyManager
NWPathMonitor for network availability handling
Persistent logging mechanism (FileHandle)
2. System Extension Process
Contains three providers, all running within a single system extension process:
a) Content Filter (NEFilterDataProvider)
Captures socket-level metadata
Extracts:
PID via audit token
Local/remote endpoints
Protocol (TCP/UDP, IPv4/IPv6)
Direction (inbound/outbound)
Sends structured JSON logs via shared IPC
b) Transparent Proxy (NETransparentProxyProvider)
Intercepts TCP flows
Creates a corresponding NWConnection to the destination
Captures both HTTP and HTTPS traffic, sends it to HTTPFlowLogger file which bypasses if it's not HTTP traffic.
Uses a custom HTTPFlowLogger:
Built using SwiftNIO library (NIO HTTP1)
Parses up to HTTP/1.1 traffic
Handles streaming, headers, and partial body capture (with size limits)
Maintains per-flow state and lifecycle management
Logs structured HTTP data via shared IPC
c) DNS Proxy (NEDNSProxyProvider)
Intercepts UDP DNS traffic
Forwards queries to upstream resolver (system DNS or fallback)
Maintains shared UDP connection
Tracks pending requests using DNS IDs
Parses DNS packets (queries + responses) using a custom parser
Logs structured DNS metadata via shared IPC
Shared Component: IPCConnection
Single bidirectional XPC channel used by all providers
Handles:
App → Extension registration
Extension → App logging
Uses Mach service defined in system extension entitlements
Project Structure
NetworkExtension (Project)
│
├── NetworkExtension (Target 1: Main App)
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── Info.plist
│ ├── NetworkExtension.entitlements
│ ├── Main.storyboard
│ └──ViewController.swift
│
├── SystemExtensions (Target 2: Extension Process)
│ ├── common/
│ │ ├── IPCConnection.swift
│ │ └── main.swift
│ │
│ ├── DNSProxyProvider/
│ │ ├──DNSDataParser.swift
│ │ └──DNSProxyProvider.swift (DNS Proxy)
│ │
│ ├── FilterDataProvider/
│ │ └── FilterDataProvider.swift
│ │
│ ├── TransparentProxyProvider/
│ │ ├── HTTPLogParser.swift
│ │ ├── LogDataModel.swift
│ │ └──TransparentProxyProvider.swift
│ │
│ ├── Info.plist
│ └── SystemExtensions.entitlements
│
Current Capabilities
Unified logging pipeline across:
Socket-level metadata
HTTP traffic (HTTP/1.1)
DNS queries/responses
Efficient log handling using persistent file descriptors
Stable IPC communication between app and extensions
Flow-level tracking and lifecycle management
Selective filtering (e.g., bypass rules for specific IPs)
What's the best approach to add TLS Inspection with MITM proxy setup?
Some context and constraints:
Existing implementation handles HTTP parsing and should remain unchanged (Swift-based).
I’m okay with bypassing apps/sites that use certificate pinning (e.g., banking apps) and legitimate sites.
Performance is important — I want to avoid high CPU utilization.
I’m relatively new to TLS inspection and MITM proxy design.
Questions
Is it a good idea to implement TLS inspection within a system extension, or does that typically introduce significant complexity and performance overhead?
As NETransparentProxyProvider already intercepting HTTPS traffic, can we redirect it to a separate processing pipeline (e.g., another file/module), while keeping the existing HTTP parser(HTTPFlowLogger - HTTP only parser) intact?
What are the recommended architectural approaches for adding HTTPS parsing via MITM in a performant way?
Are there best practices for selectively bypassing pinned or sensitive domains while still inspecting other traffic?
Any guidance on avoiding common pitfalls (e.g., certificate handling, connection reuse, latency issues)?
I’m looking for a clean, maintainable approach to integrate HTTPS inspection into my existing system without unnecessary complexity or performance degradation.
Please let me know if any additional details from my side would help in suggesting the most appropriate approach.
Thanks in advance for your time and insights—I really appreciate it.
Topic:
App & System Services
SubTopic:
Networking
Tags:
Network Extension
System Extensions
Security
1
0
54