{"id":555,"date":"2013-01-07T10:00:55","date_gmt":"2013-01-07T16:00:55","guid":{"rendered":"https:\/\/www.foell.org\/justin\/?p=555"},"modified":"2019-10-21T11:52:32","modified_gmt":"2019-10-21T16:52:32","slug":"diy-dynamic-dns-with-openwrt-bind","status":"publish","type":"post","link":"https:\/\/www.foell.org\/justin\/diy-dynamic-dns-with-openwrt-bind\/","title":{"rendered":"DIY Dynamic DNS with OpenWrt &amp; BIND"},"content":{"rendered":"<p>This article assumes you fave a few things:<\/p>\n<ol>\n<li>A Linux server with:\n<ul>\n<li>root SSH access<\/li>\n<li>BIND installed<\/li>\n<li>a domain already set up and working with BIND<\/li>\n<\/ul>\n<\/li>\n<li>An OpenWrt router at home to send updates<\/li>\n<\/ol>\n<p>The OpenWrt router isn&#8217;t strictly necessary.\u00a0 You could, of course do the dynamic DNS updates with a cheap Linux firewall, but I&#8217;ll cover the configuration for OpenWrt.<\/p>\n<p><!--more--><\/p>\n<h2>DNS Server Configuration<\/h2>\n<p>The file naming conventions used here are for a BIND installation on Debian. Your distribution may use a different naming convention, however, the concepts should be the same.<\/p>\n<p>On the DNS server (as root):<\/p>\n<pre># dnssec-keygen -C -a HMAC-MD5 -b 512 -n HOST sub.domain.com.<\/pre>\n<p>You can use your domain name (or subdomain) as the key name if you&#8217;d like. That&#8217;s what I did in this example &#8211; it helps me keep things straight. The <code>-C<\/code> switch is for compatibility mode since it&#8217;s likely the <code>nsupdate<\/code> binary on OpenWrt will be older than the BIND installation on your DNS server. The contents of the key file will look something like this:<\/p>\n<pre># cat Ksub.domain.com.+157+54658.key\r\nsub.domain.com. IN KEY 512 3 157 GWruXog5QO20QSB2YvLJp60DwlfJhq0hQ9KiAXFRNDHlrhSSjGBtGlM8 wSJpWNlUbhdkBnV3Or41s1iedLoDwg==<\/pre>\n<p>I like to keep BIND&#8217;s key configuration in a separate file to make sure it doesn&#8217;t get overwritten with software upgrades, so I created a file called <code>\/etc\/bind\/keys.conf<\/code>. Using the MD5 from the key file (the cryptic string(s) that ends in &#8216;==&#8217;, after the sets of numbers), create a <code>keys.conf<\/code> file:<\/p>\n<pre>key sub.domain.com.\r\n{\r\n\talgorithm HMAC-MD5;\r\n\tsecret \"GWruXog5QO20QSB2YvLJp60DwlfJhq0hQ9KiAXFRNDHlrhSSjGBtGlM8 wSJpWNlUbhdkBnV3Or41s1iedLoDwg==\";\r\n};<\/pre>\n<p>Then in <code>\/etc\/bind\/named.conf<\/code>, add this at the top:<\/p>\n<pre>include \"\/etc\/bind\/keys.conf\";<\/pre>\n<p>In my <code>\/etc\/bind\/named.conf.local<\/code> (which has all of the zones actually hosted on the server), the zone for the domain I want to make dynamic has the following:<\/p>\n<pre>zone \"domain.com\" IN {\r\n        type master;\r\n        file \"\/etc\/bind\/db.domain\";\r\n        update-policy {\r\n               grant sub.domain.com. name sub.domain.com. A TXT;\r\n        };\r\n        notify no;\r\n};<\/pre>\n<p>You would substitute your domain for &#8220;domain.com&#8221; and &#8220;sub.domain.com,&#8221; and have your own zone file in a different file named after your domain (<code>\/etc\/bind\/db.yourdomainname<\/code>).<\/p>\n<p>The &#8220;update-policy&#8221; section is the part that is added.\u00a0 The first parameter to the &#8220;grant&#8221; statement is the name of the key, and the &#8220;name&#8221; parameter is the domain name &#8211; which I&#8217;ve made the same in this case. There&#8217;s nothing different about <code>\/etc\/bind\/db.domain<\/code> than any of my other zone db files, except it&#8217;s owned by the &#8220;bind&#8221; user &amp; group &#8212; that way when it receives a DNS update, it can change the file (dynamically!).<\/p>\n<p>Also the <code>\/etc\/bind<\/code> directory should be owned by group &#8220;bind&#8221; so that it can create <code>\/etc\/bind\/db.domain.jnl<\/code> &#8212; a journal file BIND will use.<\/p>\n<h2>OpenWrt Configuration<\/h2>\n<p>Install the &#8220;bind-client&#8221; package on your OpenWrt router. \u00a0I like to use the LuCI web interface. \u00a0In LuCI you can find it by searching under the software administration menu.<\/p>\n<p>SCP the private &amp; key files you created on your DNS server to your OpenWrt router. \u00a0I keep my DNS files in root&#8217;s home directory: <code>\/root<\/code>.<\/p>\n<p>Create a hotplug file to update the DNS when the WAN interface obtains an address. Put it in\u00a0<code>\/etc\/hotplug.d\/iface\/30-nsupdate<\/code>:<\/p>\n<pre>[ \"$INTERFACE\" != \"wan\" ] &amp;&amp; ( [ \"$ACTION\" != \"ifup\" ] || [ \"$ACTION\" != \"update\" ] ) &amp;&amp; exit 0\r\n\r\nrdate -s time.nist.gov\r\ninclude \/lib\/network\r\nscan_interfaces\r\nconfig_get ipaddr wan ipaddr\r\n\r\necho \"server your.bindserver.com\r\nzone domain.com\r\nupdate delete sub.domain.com A\r\nupdate add sub.domain.com. 86400 A $ipaddr\r\nshow\r\nsend\" | nsupdate -k \/root\/Ksub.domain.com.+157+54658.key -v<\/pre>\n<p>Again, Replace &#8220;domain.com&#8221; with the name of your zone, and &#8220;sub.domain.com&#8221; with the name of your dynamic domain (they could be named the same).\u00a0 Replace &#8220;your.bindserver.com&#8221; with the name or IP of your DNS server.\u00a0 The <code>rdate<\/code> command is in there to make sure your time is set correctly before running <code>nsupdate<\/code>.\u00a0 BIND will complain if the time difference between the client &amp; server differs too much.\u00a0 While only the key file is referenced in the script, both files need to be present (usually in the same directory as each other) for <code>nsupdate<\/code> to make a valid request.<\/p>\n<p>You can (and should) test the script without disrupting your network connection by SSHing into your OpenWrt router and running the following command:<\/p>\n<pre># ACTION=update INTERFACE=wan \/sbin\/hotplug-call iface<\/pre>\n<p>Often BIND will complain about time, permissions, auth keys, etc. Running the test above is the best way to find out what&#8217;s going on. If there&#8217;s no output, the update probably went through. Try to ping your dynamic domain name and see if all is well.<\/p>\n<div class='kindleWidget kindleLight' ><img decoding=\"async\" src=\"https:\/\/www.foell.org\/justin\/wp-content\/plugins\/send-to-kindle\/media\/white-15.png\" \/><span>Send to Kindle<\/span><\/div>","protected":false},"excerpt":{"rendered":"<p>This article assumes you fave a few things: A Linux server with: root SSH access BIND installed a domain already set up and working with BIND An OpenWrt router at home to send updates The OpenWrt router isn&#8217;t strictly necessary.\u00a0 You could, of course do the dynamic DNS updates with a cheap Linux firewall, but&hellip; <a href=\"https:\/\/www.foell.org\/justin\/diy-dynamic-dns-with-openwrt-bind\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1,17],"tags":[61,166,24],"class_list":["post-555","post","type-post","status-publish","format-standard","hentry","category-business","category-dns","tag-bind","tag-linux","tag-openwrt"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/posts\/555","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/comments?post=555"}],"version-history":[{"count":18,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/posts\/555\/revisions"}],"predecessor-version":[{"id":648,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/posts\/555\/revisions\/648"}],"wp:attachment":[{"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/media?parent=555"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/categories?post=555"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/tags?post=555"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}