With my UDP Flow Copier working as demonstrated by the fact that it is proxying DNS traffic successfully, I am finally writing tests to verify UDP packet filtering. I'm sending packets to a public UDP echo server and reading the response successfully. In my initial testing however the TransparentProxyProvider System Extension is not intercepting my UDP traffic. handleNewUDPFlow() is being called for DNS but not for my test case UDP echo sends and receives. I've tried sending UDP with both GCDAsyncSocket and NWConnection as:
connection = NWConnection(host: host, port: port, using: .udp)
Is there some other criteria for UDP datagrams to be intercepted? Google search suggests this might be a known issue for connected or async UDP sockets.
The most obvious cause for a problem like this is your NETransparentProxyNetworkSettings
, and specifically the value for includedNetworkRules
. How do you set that up?
In my test project I do this:
let includedNetworks = [("0.0.0.0", 0), ("::", 0)]
.map { addr, prefix -> NENetworkRule in
let endpoint = NWHostEndpoint(hostname: addr, port: "12345")
return NENetworkRule(destinationNetwork: endpoint, prefix: prefix, protocol: .any)
}
I tried this out on macOS 15.5 and it seems to work. Specifically:
-
I enabled the transparent proxy.
-
On another Mac, I started a UDP server using
nc
:nc -u -l 12345
-
I connect to it from three clients:
-
nc
, which uses a connected UDP socket -
QNWTool
, a test tool I wrote that usesNWConnection
-
UDPSocketTest
, a test tool I wrote that uses a non-connected BSD SocketsIn all cases my provider saw the flow:
type: debug
time: 12:57:49.912415+0100
process: com.example.apple-samplecode.QNE2TransparentProxyMac.SysEx
subsystem: com.example.apple-samplecode.QNE2TransparentProxyMac
category: proxy
message: will let system handle flow, old, app: com.apple.nc, type: UDP, remote endpoint: 192.168.1.39:12345
type: debug
time: 12:58:19.749922+0100
process: com.example.apple-samplecode.QNE2TransparentProxyMac.SysEx
subsystem: com.example.apple-samplecode.QNE2TransparentProxyMac
category: proxy
message: will let system handle flow, old, app: QNWTool, type: UDP, remote endpoint: 192.168.1.39:12345
type: debug
time: 12:58:48.658703+0100
process: com.example.apple-samplecode.QNE2TransparentProxyMac.SysEx
subsystem: com.example.apple-samplecode.QNE2TransparentProxyMac
category: proxy
message: will let system handle flow, old, app: UDPSocketTest, type: UDP, remote endpoint: 192.168.1.39:12345
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"