iOS 14, mobileconfig, DNS over HTTPS with DNSDomainMatch whitelist support

3.6k views Asked by At

I run my own dns over https server. I'm wanting most DNS requests to go through it, but any requests from "apple.com", "icloud.com" domains/subdomains to bypass my DOH server and just use the phone's default DNS for that.

I've created a .mobileconfig profile as seen below (I replaced the doh server url and the probe url):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>PayloadContent</key>
  <array>
    <dict>
      <key>Name</key>
      <string>DOH</string>
      <key>PayloadDescription</key>
      <string>DOH</string>
      <key>PayloadDisplayName</key>
      <string>DNS over HTTPS</string>
      <key>PayloadIdentifier</key>
      <string>com.apple.dnsSettings.managed.AFCA1444-5AEB-44CD-B23D-5D2B5ADCD1EE</string>
      <key>PayloadType</key>
      <string>com.apple.dnsSettings.managed</string>
      <key>PayloadUUID</key>
      <string>8E3D6F57-0EB4-4C89-A068-2D6EF5FAC976</string>
      <key>PayloadVersion</key>
      <integer>1</integer>
      <key>DNSSettings</key>
      <dict>
          <key>DNSProtocol</key>
          <string>HTTPS</string>
          <key>ServerURL</key>
          <string>https://dns.google/dns-query</string>
          <key>ServerName</key>
          <string>doh-test</string>
      </dict>
      <key>OnDemandRules</key>
      <array>
        <dict>
          <key>Action</key>
          <string>Disconnect</string>
          <key>DNSDomainMatch</key>
          <array>
            <string>*.apple.com</string>
            <string>*.icloud.com</string>
          </array>
        </dict>
        <dict>
          <key>Action</key>
          <string>Connect</string>
          <key>URLStringProbe</key>
          <string>https://google.com</string>
        </dict>
        <dict>
          <key>Action</key>
          <string>Disconnect</string>
        </dict>
      </array>
    </dict>
  </array>
  <key>PayloadDescription</key>
  <string>DNS over Https</string>
  <key>PayloadDisplayName</key>
  <string>DNS over HTTPs</string>
  <key>PayloadIdentifier</key>
  <string>com.cam.me.8A4244E4-7802-46D9-9BA9-06EA71975740</string>
  <key>PayloadRemovalDisallowed</key>
  <false/>
  <key>PayloadType</key>
  <string>Configuration</string>
  <key>PayloadUUID</key>
  <string>2066753F-6CD2-43CE-AA24-C26C4F656B71</string>
  <key>PayloadVersion</key>
  <integer>1</integer>
</dict>
</plist>

However my DOH server logs still show tons of requests coming from *.apple.com and *.icloud.com domains. After doing some testing, I'm unable to tell if it's whitelisting any of them.

See documentation at https://developer.apple.com/documentation/devicemanagement/dnssettings/ondemandruleselement. The DNSDomainMatch documentation indicates (boldness added):

An array of domain names. This rule matches if any of the domain names in the specified list matches any domain in the device’s search domains list. A single wildcard * prefix is supported, but is not required. For example, both *.example.com and example.com match against mydomain.example.com and your.domain.example.com, but do not match against mydomain-example.com.

I've played with variations of the wildcard, and it doesn't appear to make a difference. Perhaps I'm misunderstanding this though--what does it mean by the device's search domains list?

Is there another way for me to whitelist specific domains using a mobileconfig? I've also attempted to use ActionParameters's NeverConnect but it doesn't appear to work either.

1

There are 1 answers

0
Christian1982 On

The following configuration seems to work.

I run my own DNS server (dnsdist -> pihole --EDNS0--> unbound)

Links:

With the following ios config I can automatically deactivate the DOH server in the WLAN (SSID: WLAN-TEST) and use the local DNS server.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>PayloadContent</key>
    <array>
        <dict>
            <key>Name</key>
            <string>DoT - example.com</string>
            <key>PayloadDescription</key>
            <string>Configures device to use example.com Encrypted DoT</string>
            <key>PayloadDisplayName</key>
            <string>DoT - example.com</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.dnsSettings.managed.AFCA1444-5AEB-44CD-B23D-5D1B3ADCD1EE</string>
            <key>PayloadType</key>
            <string>com.apple.dnsSettings.managed</string>
            <key>PayloadUUID</key>
            <string>A6F9CB2D-F00E-4C3A-90EB-E19E5B872C4F</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>DNSSettings</key>
            <dict>
                <key>DNSProtocol</key>
                <string>TLS</string>
                <key>ServerAddresses</key>
                <array>
                    <string>xxxx:xxxx:xxxx::xx11</string>
                    <string>x.x.1.1</string>
                </array>
                <key>ServerName</key>
                <string>ns.example.com</string>
            </dict>
        </dict>

        <dict>
            <key>Name</key>
            <string>DoH - doh.example.com/pihole</string>
            <key>PayloadDescription</key>
            <string>Configures device to use example.com Encrypted DoH</string>
            <key>PayloadDisplayName</key>
            <string>DoH - doh.example.com/pihole</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.dnsSettings.managed.AFCA1444-5AEB-44CD-B23D-5D1B3ADCD1F1</string>
            <key>PayloadType</key>
            <string>com.apple.dnsSettings.managed</string>
            <key>PayloadUUID</key>
            <string>293af945-8bcd-4a52-9f08-4071c22d8b85</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>DNSSettings</key>
            <dict>
                <key>DNSProtocol</key>
                <string>HTTPS</string>
                <key>ServerAddresses</key>
                <array>
                    <string>xxxx:xxxx:xxxx::xx11</string>
                    <string>x.x.1.1</string>
                </array>
                <key>ServerURL</key>
                <string>https://doh.example.com/doh_174653_pihole</string>
            </dict>
        </dict>

        <dict>
            <key>Name</key>
            <string>DoH - doh.example.com/pihole (except local wifi)</string>
            <key>PayloadDescription</key>
            <string>Configures device to use example.com Encrypted DoH</string>
            <key>PayloadDisplayName</key>
            <string>DoH - doh.example.com/pihole (except local wifi)</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.dnsSettings.managed.AFCA1444-5AEB-44CD-B23D-5D1B3ADCD1F1</string>
            <key>PayloadType</key>
            <string>com.apple.dnsSettings.managed</string>
            <key>PayloadUUID</key>
            <string>ca9d0419-c215-41cd-be2d-0870bf550134</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>DNSSettings</key>
            <dict>
                <key>DNSProtocol</key>
                <string>HTTPS</string>
                <key>ServerAddresses</key>
                <array>
                    <string>xxxx:xxxx:xxxx::xx11</string>
                    <string>x.x.1.1</string>
                </array>
                <key>ServerURL</key>
                <string>https://doh.example.com/doh_174653_pihole</string>
            </dict>

            <!-- Start DNS on-demand definition -->
            <key>OnDemandEnabled</key>
              <integer>1</integer>
            <!-- rules: "always DNS to our network (if possible) unless on our network" -->
            <key>OnDemandRules</key>
              <array>

                <!-- Turn off DNS if on our WiFi network -->
                <dict>
                  <key>InterfaceTypeMatch</key>
                    <string>WiFi</string>
                  <key>SSIDMatch</key>
                    <array>
                      <string>WLAN-TEST</string>
                    </array>
                  <!-- <key>DNSServerAddressMatch</key> -->
                    <!-- <array> -->
                      <!-- <string>10.x.x.1</string> -->
                    <!-- </array> -->
                  <key>Action</key>
                    <string>Disconnect</string>
                </dict>

                <!-- Turn on DNS if WiFi network -->
                <dict>
                  <key>Action</key>
                    <string>Connect</string>
                  <key>InterfaceTypeMatch</key>
                    <string>WiFi</string>
                </dict>

                <!-- Turn on DNS if Cellular network -->
                <dict>
                  <key>Action</key>
                    <string>Connect</string>
                  <key>InterfaceTypeMatch</key>
                    <string>Cellular</string>
                </dict>

                <!-- Catch-All rule to turn off DNS -->
                <dict>
                  <key>Action</key>
                    <string>Disconnect</string>
                </dict>
              </array>
            <!-- End DNS on-demand definition -->

        </dict>
    </array>
    <key>PayloadDescription</key>
    <string>Adds the example.com DNS to Big Sur and iOS 14 based systems</string>
    <key>PayloadDisplayName</key>
    <string>example.com Encrypted DNS</string>
    <key>PayloadIdentifier</key>
         <string>r.macOSBeta.0BD60CF6-64B5-4D16-BEA4-7294E93BDD4C</string>
    <key>PayloadRemovalDisallowed</key>
    <false/>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>01DA864C-C3AF-4039-A8D0-A00D982B1569</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

I used the following sources to create it: