[macOS] Wanted to capture inbound DNS traffic using NETransparentProxyProvider

Hi Team,

I'm trying to capture inbound traffic for DNS responses and have experimented with the following rules, but they did not work.

NENetworkRule *dnsInboundTraffic = [[NENetworkRule alloc] initWithRemoteNetwork:nil remotePrefix:0 localNetwork:[NWHostEndpoint endpointWithHostname:@"0.0.0.0" port:@"53"] localPrefix:0 protocol:NENetworkRuleProtocolUDP direction:NETrafficDirectionInbound];
    
settings.includedNetworkRules = @[dnsInboundTraffic];

Could you please correct me if I'm making any mistakes while setting the rules?

Replies

If you configure your proxy to watch a different port and then run a simple UDP transaction on that port — you can use nc with the -u option for that — does your proxy see that traffic? That is, is this problem specific to port 53?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi @eskimo,

We tried acquiring whole UDP/TCP traffic with NETrafficDirectionInbound but we are not getting anything in handleNewUDPFlow or handleNewFlow

Also, we have tried to set NETrafficDirectionAny but nothing is coming in handleNewUDPFlow or handleNewFlow

Could u pls suggest?

Hi @eskimo, We attempted to capture all TCP/UDP traffic using NETrafficDirectionInbound or NETrafficDirectionAny, but we did not receive any data in handleNewUDPFlow(...) or handleNewFlow(...)

Hmmm, so it’s not that you don’t see DNS flows, it’s that you don’t see any flows. Right?

Pasted in below is the code I use to create the settings for my test transparent proxy. As you can see, it aims to capture outgoing TCP connections to port 12345. If you (temporarily, just for testing) use this code to configure your proxy, do you see handleNewFlow(_:) called when you make an outgoing TCP connection to 12345?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

private func makeSettings() -> NETransparentProxyNetworkSettings {

	// We want to see all outbound connections to port 12345.
	
	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: .TCP)
		}
	
	// The address you pass to `tunnelRemoteAddress` is intended to be
	// the IP address of the actual VPN server that you connected to.  A
	// real VPN would connect to
	// `self.protocolConfiguration.serverAddress` and then report the
	// remote address here.  In our case we are not actually using a VPN
	// server, so `self.protocolConfiguration.serverAddress` is
	// `localhost`, and thus we simply pass in the loopback IP address.

	let settings = NETransparentProxyNetworkSettings(tunnelRemoteAddress: "127.0.0.1")

	// `NETunnelNetworkSettings` properties:
	//
	// `dnsSettings` and `proxySettings` are irrelevant to us.
	
	// `NETransparentProxyNetworkSettings` properties…
	//
	settings.includedNetworkRules = includedNetworks
	// `excludedNetworkRules`
	
	return settings
}

Hi @eskimo,

We have tried the code provided above and we have observed outgoing packets on port 12345, but there are no incoming packets.


NSArray<NENetworkRule *> *includedNetworks = @[
        @[@"0.0.0.0", @0],
        @[@"::", @0]
    ];

    NSMutableArray<NENetworkRule *> *networkRules = [NSMutableArray array];
    for (NSArray *network in includedNetworks) {
        NSString *addr = network[0];
        NSNumber *prefix = network[1];
                
        NWHostEndpoint *endpoint = [NWHostEndpoint endpointWithHostname:addr port:@"12345"];
        NENetworkRule *networkRule = [[NENetworkRule alloc] initWithDestinationNetwork:endpoint prefix:prefix.intValue protocol:NENetworkRuleProtocolTCP];
        
        [networkRules addObject:networkRule];
    }
settings.includedNetworkRules = networkRules;

there are no incoming packets.

To be clear, we’re talking about flows here, not packets.

But, yeah, that’s to be expected. I’m using the init(destinationNetwork:prefix:protocol:) convenience initialiser. If you want to specify the direction, you need to use the initialiser with all the bells and whistles, namely init(remoteNetwork:remotePrefix:localNetwork:localPrefix:protocol:direction:).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi @eskimo,

Sorry for the confusion; I was referring specifically to the flow.

I attempted the settings below in order to receive incoming flow.


NENetworkRule *dnsInboundTraffic = [[NENetworkRule alloc] initWithRemoteNetwork:nil remotePrefix:0 localNetwork:[NWHostEndpoint endpointWithHostname:@"0.0.0.0" port:@"12345"] localPrefix:0 protocol:NENetworkRuleProtocolTCP direction:NETrafficDirectionInbound];

settings.includedNetworkRules = @[dnsInboundTraffic];

But I'm not receiving incoming flow; it is functioning correctly for outgoing flow.

Please correct me if I'm doing anything wrong while creating the NENetworkRule.

@eskimo, Any suggestion on this?

I’m not sure why this isn’t working.

If you set localNetwork to nil as well, do you see any incoming flows?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@eskimo, I tried, but I'm not getting any flow.

NENetworkRule *traffic = [[NENetworkRule alloc] initWithRemoteNetwork:nil remotePrefix:0 localNetwork:nil localPrefix:0 protocol:NENetworkRuleProtocolTCP direction:NETrafficDirectionInbound];

Weird.

I’ve got no idea what’s going on here. I recommend that you open a DTS tech support incident so that I can allocate more time to look into this.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"