macosdnsresolverdnssec

How To Enable Unbound DNSSEC DNS Resolver On Mac OS X 10.10.3 Yosemite


I'm using Mac OS X 10.10.3 Yosemite. Very recently upgraded from Snow Leopard (10.6.8) to Yosemite.

Step A

On my MacBook, I login into an Admin type privileged account. I installed the latest free XCode from the Apple App Store. With XCode, I also installed Command Line Tools, etc.

Step B

I installed Homebrew from https://brew.sh/. This is the command-line code I ran in Terminal, from the Homebrew website:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

The script above checks for the presence of various necessary software & settings, and it showed (info & status inside Terminal window, on) what other commands or tools are needed to be obtained or executed. I followed those.

Step C

When Homebrew & related installation steps were done, I then installed openssl & unbound with the brew tool, via command-lines in Terminal:

brew help
brew update
brew install unbound openssl
sudo cp -fv /usr/local/opt/unbound/*.plist /Library/LaunchDaemons
sudo chown root /Library/LaunchDaemons/homebrew.mxcl.unbound.plist
sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.unbound.plist
brew upgrade --all

Step D

I restarted my MacBook once, and then tried the dig commands below. They did not show the ad flags in DNS query result, which indicates that DNSSEC authenticated DNS resolving is still not working and disabled!

dig @127.0.0.1 in TLSA _443._tcp.www.dnssec-validator.cz. +dnssec
dig @127.0.0.1 in TLSA _443._tcp.www.isc.org. +dnssec
dig @192.168.10.1 in TLSA _443._tcp.www.dnssec-validator.cz. +dnssec
dig @192.168.10.1 in TLSA _443._tcp.www.isc.org. +dnssec

The 192.168.10.1 is my (internet router) gateway for my primary network interface/adapter which is connected to the internet. My net adapter is currently using 192.168.10.50, a dynamic (not fixed) DHCP based IP address.

Unfortunately, the developers at https://unbound.net/ do not provide a standalone Unbound .pkg or .dmg installer file for Mac OS X. They do not actively develop the DNSSEC-Trigger app, either. In Snow Leopard, I was only using the Unbound portion of the DNSSEC-Trigger bundle. I was able to disable the DNSSEC-Trigger portion, and kept the Unbound portion running, after following tips shown in their mailing-list archive. In that way, I did not need to install any XCode command-line tools or Homebrew.

What should I do now so that all apps on my MacBook can use the Unbound DNSSEC resolver for all apps/clients? I want Unbound's resolver to be listening on 127.0.0.1 port 53 for DNSSEC & DNS queries.


Solution

  • These set of steps worked on Mac OS X Yosemite MacBook.

    I'm self-answering with general elaboration to make it more clear for newbies, if you are not newbie then please skip whatever is unnecessary for you.

    If you don't want to install very large installation of XCode, then see Step E below, first. Otherwise, start with the steps in the original question.

    Step E

    E1

    My own account in Mac OS is Erik-user. It is a standard user account, which I generally use for general purposes. But the Erik account is for administrative purposes. It is an "Admin" type, privileged user account. I'm using the Erik account.

    E2

    To enable showing hidden files inside Finder file browser, use the commands below in Terminal:

    defaults write com.apple.Finder AppleShowAllFiles TRUE
    defaults write com.apple.finder AppleShowAllFiles TRUE
    

    and then log out & log back into your MacOS user account, or restart MacOS. Now "Finder" should show you all files & folders, in [ | | ] column mode.

    If you have already installed "XCode" and homebrew, then skip the rest of Step E and continue from Step F.

    E3

    If you want to avoid installing the multi-gigabyte XCode,

    Mac OS X Yosemite allows you to install only the CLT portion. Some previous Mac OS X versions did not allow CLT without XCode.

    Also check if the gcc tool is now present or not: in Terminal, run: gcc --version

    E4

    Install Homebrew. In Terminal run:

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    

    Please see https://brew.sh/ website for the actual & current ruby command.
    Then in Terminal, run these commands:

    brew help
    brew update
    brew install unbound openssl
    

    E5

    sudo cp -fv /usr/local/opt/unbound/*.plist /Library/LaunchDaemons
    sudo chown root:wheel /Library/LaunchDaemons/homebrew.mxcl.unbound.plist
    sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.unbound.plist
    

    If you followed Steps E3 to E5, then skip Step F, and start to follow from Step G.

    Step F

    The homebrew.mxcl.unbound.plist file (which starts the Unbound DNS server) specifically needs to have proper ownership, so that Mac OS X's system itself can start it during boot or restart. Execute this command in Terminal:

    sudo chown root:wheel /Library/LaunchDaemons/homebrew.mxcl.unbound.plist
    

    Note: After upgrading Homebrew apps, we may need to execute this command again, if Unbound fails to start after a reboot.

    Step G

    Download Lingon from SourceForge. Install it. Start Lingon.

    Step H

    Inside Lingon, locate homebrew.mxcl.unbound under "USER DAEMONS." In the "What" textbox, it is supposed to show like below:
    /usr/local/opt/unbound/sbin/unbound -d -c /usr/local/etc/unbound/unbound.conf
    Select & copy that last portion /usr/local/etc/unbound/unbound.conf.

    Step I

    Open /usr/local/etc/unbound/unbound.conf with your favorite text editor.

    Step J: unbound.conf file content

    The unbound.conf file has many pages of configuration info & config-command examples.
    See below codes, add only these below config-command code lines at bottom of unbound.conf file or in appropriate section.

    server:
        verbosity: 1
        num-threads: 2
        interface: 127.0.0.1
        interface: ::1
        port: 53
        do-ip4: yes
        do-ip6: yes
        do-udp: yes
        do-tcp: yes
        do-daemonize: yes
        #module-config: "[dns64] [validator] iterator"
        module-config: "validator iterator"
        auto-trust-anchor-file: "/usr/local/etc/unbound/root.key"
        #dlv-anchor-file: "/usr/local/etc/unbound/dlv.isc.org.key"
    

    Note: I skipped showing instruction for DLV DNSSEC, so added the (shown-above) # symbol in front of the dlv-anchor-file line, to disable it. And one of the module-config lines is also disabled, as I don't want DNS64 related resolution, for now.

    Step K: unbound.conf file permissions

    Set file ownership:

    sudo chown root /usr/local/etc/unbound/unbound.conf
    

    Set file permissions for different ownerships:

    sudo chmod 644 /usr/local/etc/unbound/unbound.conf
    

    A short discourse on file permission and ownership

    Permission level 4 = read, 2 = write, 1 = execute. 3-digit number is for 3-types of ownership: Owner-Group-Other.
    By using Finder's GUI interface, you can also set permissions & ownerships of a file, instead of using command-lines in Terminal: select a file in Finder, press Cmd+i buttons together, go below in "Sharing & Permissions" section, the "Name" column shows list of users/groups who owns ownership, the "Privilege" column shows file's read/write permissions level for different ownership. Change into recommended choices & preference level shown here.
    Except for very reliable person, and only-this computer's core (operating-system) system components, no one else (and no other entity) should have the ability to (edit & change or) write, into some of the sensitive files & folders, that is why we need to set "Permissions-level" on files & folders. The "6" in "644" (which is used in "chmod" command-line) is indicating current-user's (aka "Me") permissions-level, and current user ("Me") has ("6" can be broken down into 4+2) read+write level permissions. The middle "4" in "644" is permission for user-type or user-group, and that group/type of users have ("4") read level permissions. Then right-most side "4" in "644" is permission for Everyone/Other/World users and they have ("4") read level permissions.

    Step L: Verify unbound.conf

    Check if unbound.conf file configuration has any error, by using this command, in Terminal:

    sudo /usr/local/opt/unbound/sbin/unbound-checkconf  "/usr/local/etc/unbound/unbound.conf"
    

    Step M: Obtaining a root.key anchor

    Follow instruction shown in OPTION-1, if you dont have a "root.key" file for "unbound" DNS server/Resolver, and you want to manually create an "initial" root.key file by yourself with very thorough checking, and if you want unbound DNS Server daemon to update that initial root.key, with a working full root.key code & timestamps.

    Follow instruction shown in OPTION-2, if you dont have a (initial or working) "root.key" file, and if you want the "unbound-anchor" tool to QUICKLY create it for you.

    Follow instruction shown in OPTION-3, if you dont have a (initial or working) "root.key" file, but you have securely obtained "icannbundle.pem" file, from IANA/ICANN authority website, and you want "unbound-anchor" tool to create it (full working root.key) very securely.

    Follow instruction shown in OPTION-4, if you don't have a (initial or working) "root.key" file, but you have access to another "safe" or "secured" computer, where you can securely obtain files from authority websites, or you can copy a working "root.key" file from it, for your MacOSX computer.

    M option 1: Manually creating a new root.key

    A regular user may want to view or obtain (or manually create) correct "initial" "root.key" (aka, initial root-trust-anchor) via HTTPS (encrypted & non-eavesdropped & secured) connection from IANA authority website: root-anchors.xml, or obtain initial anchor from ICANN authority website, and then regular user MUST compare+verify xml file's content code, with local initial root.key file.
    Click on the above xml URL-link, and then check presence of a LOCK-icon shown in web-browser's url-bar (which is an indicative that a HTTPS encrypted connection is being used), and also check color of "DNSSEC-Validator" (and "TLSA-Validator") status icon, (it must display a picture of green-colored KEY-icon).
    Either download the xml file or copy-paste the content shown in xml file, into the "root-anchors.xml" file, and place/move it in same folder where "unbound.conf" file is located.
    And now copy the file "root-anchors.xml" file in same folder, and rename the "root-anchors Copy.xml" file into "root.key".
    And edit this "root.key" file (by using nano or Bluefish text-editor app). And change/re-arrange existing XML syntax/format, into the format shown in below "DS" code line. Make sure all numbers & hash codes in "root.key" are exactly same number & hash, shown on that IANA authority webpage "root-anchors.xml" file. Format/Syntax will be different in those two files, but code & hash numbers must be same.
    Currently (June, 2015), the 2010-2011 initial trust anchor (initial root.key) for the root zone, looks like below.

    . IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
    

    And then set file ownership: sudo chown root /usr/local/etc/unbound/root.key
    and set permissions: sudo chmod 644 /usr/local/etc/unbound/root.key

    Codes shown in above "DS" code-line, (which must also be present in INITIAL "root.key" file), is known as "Initial Anchor". Unbound server daemon or "unbound-anchor" tool can update initial file with a working full root.key, with appropriate codes & timestamps.

    M option 2: Creating a new root.key with unbound-anchor using local certificates

    Another QUICK (short) way (and not very secure/trustworthy way) to obtain+create the "root.key" file, is to, use the unbound tool "unbound-anchor", via a command in Terminal:
    sudo /usr/local/opt/unbound/sbin/unbound-anchor -a "/usr/local/etc/unbound/root.key"
    With above command, unbound-anchor tool obtains appropriate codes or files from authority websites (if a newer version is found) by using internal certificates, and then creates the "root.key" file, containing working codes & timestamps.
    And then set file ownership on it: sudo chown root /usr/local/etc/unbound/root.key
    and set permissions: sudo chmod 644 /usr/local/etc/unbound/root.key

    M option 3: Creating a new root.key with unbound-anchor using ICANN certificates

    unbound-anchor can also obtain and create a working root.key even more securely, if an icannbundle.pem file is supplied/used.
    So 1st obtain icannbundle.pem file securely from the IANA authority website (and make sure your web browser's address bar is showing LOCK-icon & green-colored dnssec KEY-icon), and download the pem file into this directory: /usr/local/etc/unbound
    And then set file ownership: sudo chown root /usr/local/etc/unbound/icannbundle.pem
    and set permissions: sudo chmod 644 /usr/local/etc/unbound/icannbundle.pem
    Then obtain+create a working root.key very securely, by using this command in Terminal:
    sudo /usr/local/opt/unbound/sbin/unbound-anchor -a "/usr/local/etc/unbound/root.key" -c "/usr/local/etc/unbound/icannbundle.pem"
    With above command, unbound-anchor tool obtains appropriate codes or files from authority websites (if a newer version is found) by using internal certificates, and then checks authenticity of received code by using the icannbundle.pem cryptographic key file, and then creates the "root.key" file, containing working codes & timestamps.
    And now we can set file ownership on root.key: sudo chown root /usr/local/etc/unbound/root.key
    and set permissions: sudo chmod 644 /usr/local/etc/unbound/root.key
    For more detail info, goto: https://unbound.net/documentation/howto_anchor.html and also check https://unbound.net/documentation/unbound-anchor.html

    M option 4: Obtaining a root.key from another computer where it has been created

    Note: User/visitor suppose to use already pre-setup safe computer & web-browser software to "securely" obtain/download those files (root-anchors.xml, or, icannbundle.pem, etc) from ICANN or IANA authority website. Web-browser software, MUST have "DNSSEC-Validator" (and "TLSA-Validator") (also known as DNSSEC/TLSA-Validator) extension/addon (from this https://www.dnssec-validator.cz/ website), and that computer must also have a local full DNSSEC supported DNS Server or resolver.
    And then in such web-browser, a user/visitor can see correct DNSSEC & DANE/TLSA status icon (green-colored KEY-icon), for each visiting websites (which are appropriately DNSSEC-Signed).
    If an "unbound" DNS Server/Resolver is used in that "SAFE" & "SECURED" computer, then you can copy that "root.key" file from it, into your MacOSX computer, when you want to avoid going into authority websites & want to avoid checking very thoroughly, and when you want to quickly configure a 2nd/other computer.
    Also load these firefox extensions/addons, and then enable "add-on bar" (similar to statusbar) at bottomside of firefox, for viewing more info on web server location & reverse DNS address, and more info on server's TLS/SSL certificate:
    CipherFox, Cert Viewer Plus, Calomel SSL Validation, HTTPS-Everywhere, WorldIP, Classic Theme Restorer, etc.

    Step N

    In your Mac OS X computer, goto "System Preferences" > Network > choose each "WiFi" and each "Ethernet" Network Interface Card/Adapter, which is/are connected with internet in your Apple MacBook computer > goto/click "Advanced" > goto "DNS" tab > (write-down which adapter has which set of DNS Servers in a paper, and then, one by one adapter) remove the DNS-servers which are listed there, and make sure, that, only one DNS server is listed/specified: 127.0.0.1

    Above steps will create+add "nameserver 127.0.0.1" code, inside /etc/resolv.conf file.

    Step O

    If you are using 10.10.3 or earlier, then keep mDNS (mDNSResponder) completely disabled. By using "Lingon" app, look for mDNS ("com.apple.mDNSResponder"), check all 4 sections inside Lingon, specially under SYSTEM DAEMONS, click on the text "Show" next to each section, to view full list.
    mDNS is re-included back in 10.10.4 (by Apple updates), so if you are using 10.10.4 then disable it temporarily just for these steps-o.
    If it is active or found in 10.10.3 or earlier, then uncheck/unselect the "Enabled" option in Lingon to disable it, enter administrative user pass, save/ok.
    When mDNS is active, it starts to resolve DNS and it also does bunch of other activity automatically, (like, discovering & configuring UPnP IGD & NAT-PMP, etc) without taking computer-owner's permission or without showing any info (or table of info) to computer's owner, what exactly its doing. So mDNS does not show computer's owner, any information on which apps are allowed by it, to do what, and what port/traffic activities are going on on or through your computer, etc, none are displayed to computer's owner, so mDNS is not an app with some good technologies for people & their computer's safety & security & privacy in mind. And mDNS by itself does not support full DNSSEC either, unless at-least one local/remote BIND or Unbound full dnssec dns server is used.

    Step P

    If you are using 10.10.3 or earlier, then disable it temporarily just for these steps-p. By using Lingon, find "com.apple.networking.discoveryd" under SYSTEM DAEMONS. Uncheck/unselect the "Enabled" option in Lingon to disable it temporarily, enter administrative user pass, save/ok. We are disabling it, so that it can completely forget the previous/old DNS Servers, which were obtained from network adapter's DNS setting, (it will forget after one restart from this stage).
    Discoveryd is removed from 10.10.4 (by Apple updates), so if you are using 10.10.4 then disable it completely, if still exists.

    Step Q

    By using Lingon, find "com.apple.dnsextd" under SYSTEM DAEMONS. Uncheck/unselect the "Enabled" option in Lingon to disable/de-activate it, enter administrative user pass, save/ok.

    Step R

    In Terminal, run

    dig @127.0.0.1 in TLSA _443._tcp.www.isc.org. +dnssec
    

    And open "App Store" and see if it can pull homepage contents/items.

    Reboot/restart MacOSX once.

    Step S

    S1

    If you are using 10.10.3 or earlier, then enable "discoveryd" back, now, at this stage of this instruction steps-s. Again use Lingon, find the "com.apple.networking.discoveryd". Select/checkmark the "Enabled" option, enter administrative user pass, save/ok.
    Discoveryd is removed from 10.10.4 (by Apple updates), so if you are using 10.10.4, then still keep "discoveryd" disabled, if still exists.

    S2

    If you are using 10.10.4 or later, then enable "mDNS" back, now, at this stage. Again use Lingon, find the "com.apple.mDNSResponder" under SYSTEM DAEMONS. Select/checkmark the "Enabled" option, enter administrative user pass, save/ok.

    S3

    Many apps use system/default DNS resolving when allowed & serviced by the (above shown) "discoveryd" daemon (aka, Discovery Daemon), in 10.10.3 & earlier Mac OS X, or DNS resolving service is allowed to be accessed by mDNS daemon in 10.10.4 or later Mac OS X. Either of this daemon should be now able to learn & allow other apps to use the new DNSSEC DNS Server service running at 127.0.0.1 port-53, which is specified in Network adapter's DNS settings, (after one restart from this stage).

    Step T

    In Terminal, run

    dig @127.0.0.1 in TLSA _443._tcp.www.isc.org. +dnssec
    

    And open "App Store" and see if it can pull homepage contents/items.

    Reboot/restart one more time again.

    Step U

    Now in Terminal, run below "dig" commands, and check if query results are showing "ad" in flag, and status is showing "NOERROR". If those indicators are present, then full dnssec dns resolving is working from a local dnssec resolver, running-at & listening-on 127.0.0.1 port 53/DNS. :)

    dig @127.0.0.1 in TLSA _443._tcp.www.dnssec-validator.cz. +dnssec
    dig @127.0.0.1 in TLSA _443._tcp.www.isc.org. +dnssec
    dig @127.0.0.1 in TLSA _443._tcp.www.statdns.net. +dnssec
    ping yahoo.com
    nslookup yahoo.com
    

    If nslookup or ping worked, then it indicates that the default DNS Server is working.
    Remove the "@127.0.0.1" portion from above "dig" commands, and check if results are same (that is, "ad" flag is still shown, and if dig results are still showing it has by-default used the 127.0.0.1 as DNS server), then it is indicating, by default local 127.0.0.1 DNS Server is being used as system-wide DNS Server/Resolver (for allmost all apps/tools), and dnssec based resolving is also working.

    Step V

    Some tools & apps do not completely use other DNS servers, they contain their own internal full DNSSEC/DNS resolving library & related codes or contains partial library-codes, so checking DNS with only such tools are not enough.
    You must check it via other apps (which you daily use or) which are known to use system network adapter's DNS servers.

    So you must fireup Firefox and Apple App Store, and check if you can see & visit all websites normally, as those apps will be using the "default" (aka, "system") DNS resolver/server, which is now set-to 127.0.0.1 by us, what we have specified inside network adapter configuration.

    Step W

    Firewall based restrictions & assistance:
    By using application-aware firewall + network port/packet control firewall, if we set firewall-rules shown below, then entire system can be FORCED TO USE, only ONE full dnssec DNS Server/Resolver 127.0.0.1 & nothing else:
    system-wide/global firewall rule #1: only "unbound" app can connect with any other DNS-Server's port 53/DNS using TCP or UDP connection.
    system-wide/global firewall rule #2: any app/software which is NOT-"unbound", can only use one "unbound" DNS-Server running-at & listening-on 127.0.0.1 port 53/DNS using TCP or UDP connection. (So all other port 53 traffics are dropped for non-unbound app/software).

    Steps X and Y

    (Deleted)

    Step Z: Notes, Disclaimers, and References

    I have followed (and borrowed instructions, and discussion comments from) various other websites, (and copy-pasted instructions & comments here with slight modifications done by me). Some references i showed, under the paragraph, when related content was first mentioned, in this article/answer page. So, for even more detail understanding, please search in ddg/yahoo/bing/google engines with terms/words taken from here.
    Different computer may & very likely to have different versions and configurations and components. So you MUST research & use your own best educated knowledge & judgement, before using any of these shown instructions on your own computer at your own risk.