DNS Settings and our favorite Captive Portals

We are using a DNS Settings profile with On Demand rules pushed to macOS devices and that is working swimmingly... until users try to use a network with a captive portal present.

Upon connecting to a network with a captive portal that is preventing access to the internet, the DNS Settings take effect and start routing all DNS requests – namely those that are required to clear the captive portal itself – towards the DNS Settings defined name servers. Those name servers exist on the public internet.

Of course, those DNS packets are dropped by the network because the captive portal isn't cleared, so the user is stuck staring at a blank Captive Portal Assistant login screen since the DNS requests required to load the captive portal UI are failing.

We've tried all sorts of hacks to try to get the DNS Settings profile to disconnect using creative On Demand rules, but alas, since the interface is only in a "half connected" state while pending Captive Portal Assistant completion, those On Demand rules are never even evaluated.

It seems like Apple needs to fix this with logic to the effect of "if there are no network interfaces with an active gateway, disconnect/deactivate the DNS Settings ". Right now, it defaults to the "Connected" state, so "half connected" interfaces when a captive portal is present will always be bricked.

As a workaround: is there a programmatic way to disable the DNS Settings configuration on the device? networksetup doesn't seem to have remit over the DNS Settings config, only physical network interfaces, and I can't find anything similar. It is possible to set the DNS Settings config to "Inactive" in the Network preferences pane (through the ... menu), but I can't seem to find a way to do this programmatically.

Or, is there a prescribed way to support captive portals?

Thanks for the help!

It is possible to set the DNS Settings config to "Inactive" in the Network preferences pane (through the ... menu), but I can't seem to find a way to do this programmatically.

A few things come to mind here:

  1. Using NEDNSSettingsManager are you able to set the configuration to enabled = false and then save the configuration again?

  2. Using NEDNSSettingsManager are you able to call removeFromPreferences and then once the captive portal traffic is finished call the load sequence again?

  3. You could also try matching only a subset of your network traffic with the matchDomains array. For example, capture only a small subset of business level domains and then let all other traffic traverse the system as normal. This would presumably let the captive portal traffic traverse the system untouched as well.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Thanks Matt! One detail: we are deploying agentlessly and not using an app with a bundled dns extension.

Specifically we are deploying a DoH configuration via an MDM mobile configuration profile: https://developer.apple.com/documentation/devicemanagement/dnssettings

Therefore we don’t have an app available to modify these settings.

That being said… could a macOS app (that we would have to build to solve this use case) modify the behavior of an MDM deployed DNS settings configuration?

DNS Settings and our favorite Captive Portals
 
 
Q