Skip to content

Instantly share code, notes, and snippets.

@baetheus
Last active December 2, 2017 00:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save baetheus/d1a1b2c227b3cfbf42ad to your computer and use it in GitHub Desktop.
Save baetheus/d1a1b2c227b3cfbf42ad to your computer and use it in GitHub Desktop.
Unbound on OS X Yosemite

Unbound on OS X Yosemite

Introduction

These are instructions for properly setting up unbound as a local caching dns recursor on OS X Yosemite. There's probably some additional stuff that can be done to secure unbound, but I'm still getting into the OS X launchd stuff. Also,

Prerequisites

Bootstrap pkgsrc from joyent as soon as you can. I used to use homebrew, but I'm not a huge fan of ruby. You can of course avoid using the binary package set from joyent if you like, and instead install pkgsrc manually and build unbound yourself. Pkgsrc is also available on a wide array of platforms, so it's nice to have consistency across os x, linux, and illumos.

Install and Configure Unbound

sudo pkgin -y in unbound
sudo unbound-anchor -a /opt/pkg/etc/unbound/root.key
sudo unbound-control-setup -d /opt/pkg/etc/unbound
sudo curl -sk https://gist.githubusercontent.com/baetheus/d1a1b2c227b3cfbf42ad/raw/unbound.conf > /opt/pkg/etc/unbound/unbound.conf
sudo chown -R unbound:unbound /opt/pkg/etc/unbound

Configure Unbound Daemon

First, launchd is context sensitive, so you'll first have to drop into a root shell with sudo su -. All of the following commands should be run from there.

curl -sk https://gist.githubusercontent.com/baetheus/d1a1b2c227b3cfbf42ad/raw/net.unbound.plist > /Library/LaunchDaemons/net.unbound.plist
launchctl bootstrap system /Library/LaunchDaemons/net.unbound.plist
launchctl enable system/net.unbound

Testing

Run the following command dig google.com @localhost. You should get an output like:

; <<>> DiG 9.8.3-P1 <<>> google.com @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32256
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.com.      IN  A

;; ANSWER SECTION:
google.com.   300 IN  A 216.58.219.46

;; Query time: 43 msec
;; SERVER: ::1#53(::1)
;; WHEN: Fri Jul 31 10:54:14 2015
;; MSG SIZE  rcvd: 44

If you received the above and ran the command again you should see the Query time reduce to 0 msec. Congratulations, you are now caching dns! If you received the following, then something went wrong and you'll have to start troubleshooting:

; <<>> DiG 9.8.3-P1 <<>> google.com @localhost
;; global options: +cmd
;; connection timed out; no servers could be reached

I'd start with checking that you followed all of the steps. Then check to see if you have particularly stringent firewall rules. From there, it's up to you.

On to changing your network configuration to use this local dns server.

Using the local caching dns server

OS X Yosemite has a pretty robust network configuration panel. If you go to System Preferences > Network you will see several network connections on the left. If you are using wireless to connect to the internet, you do the following:

  1. Click the lock in the lower left of the panel and validate with an administrative account.
  2. Click Wi-Fi.
  3. Click the Advanced button.
  4. Click the DNS tab.
  5. Click the + icon for the DNS Servers: column on the left.
  6. Add 127.0.0.1 to the list.
  7. Drag 127.0.0.1 to the top of the list, unless it is already.
  8. Additionally, if 127.0.0.1 is the only entry listed in DNS Servers, I would add some fallback public dns servers such as Hurricane Electric's 74.82.42.42 or Google's 8.8.8.8. Keep in mind that Hurricane Electric does not support DNSSEC as of this writing. So if that is important to you, avoid using them until the feature is implemented.

If you are using a wired connection, you will want to follow the same steps with the exception of changing Wi-Fi in step 2 to Thunderbolt Ethernet or Thunderbolt Bridge.

If you're like me and want to keep the option of letting OS X automatically configure your network from time to time, you can add a location named something like Local DNS and apply these changes to that location. To add a location, go back to the main Network panel, and click on the dropdown menu the right of Location:. Then click Edit Locations. You will need to be authenticated via the lock icon for this to work.

I use several locations for various situations such as connecting to a non-dhcp network in a datacenter or pointing to a specific office dns server that has all of the local computers mapped to dns automatically. Once a location is created, you can easily change locations via Apple Menu > Location > *Specific Location*. This is perhaps my favorite feature of OS X.

Changelog

20151117

  • Fixed bitmask for access ip in unbound.conf.

20150801

  • Added prefetching and hardening to unbound.conf for fun and profit.

20150731

  • Finally finished the initial draft.
  • Added Hurricane Electric's IP to unbound.conf
<?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>Label</key>
<string>net.unbound</string>
<key>ProgramArguments</key>
<array>
<string>/opt/pkg/sbin/unbound</string>
<string>-d</string>
<string>-c</string>
<string>/opt/pkg/etc/unbound/unbound.conf</string>
</array>
<key>StandardErrorPath</key>
<string>/var/log/unbound.err</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
server:
verbosity: 1
interface: 127.0.0.1
access-control: 127.0.0.1/32 allow
auto-trust-anchor-file: "/opt/pkg/etc/unbound/root.key"
harden-short-bufsize: yes
harden-large-queries: yes
harden-glue: yes
harden-dnssec-stripped: yes
harden-below-nxdomain: yes
harden-referral-path: yes
prefetch: yes
prefetch-key: yes
pidfile: "/var/run/unbound.pid"
logfile: "/var/log/unbound.log"
remote-control:
control-enable: yes
control-interface: 127.0.0.1
server-key-file: "/opt/pkg/etc/unbound/unbound_server.key"
server-cert-file: "/opt/pkg/etc/unbound/unbound_server.pem"
control-key-file: "/opt/pkg/etc/unbound/unbound_control.key"
control-cert-file: "/opt/pkg/etc/unbound/unbound_control.pem"
forward-zone:
name: "."
forward-addr: 8.8.8.8
forward-addr: 8.8.4.4
@baetheus
Copy link
Author

baetheus commented Feb 9, 2016

Please note that curl -k as root is pretty much one of the worst things you can do. Here is the relevant section from the man page for curl if you don't believe me:

   -k, --insecure
          (SSL)  This  option  explicitly allows curl to perform "insecure" SSL connections and transfers. All SSL connec-
          tions are attempted to be made secure by using the CA certificate bundle installed by default.  This  makes  all
          connections considered "insecure" fail unless -k, --insecure is used.

          See this online resource for further details: http://curl.haxx.se/docs/sslcerts.html

So if you are savvy enough to copy/pasta without using curl -k, please do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment