<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Too Far Afield &#187; dns</title>
	<atom:link href="http://blog.nachtarbeiter.net/tag/dns/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nachtarbeiter.net</link>
	<description></description>
	<lastBuildDate>Mon, 09 Jan 2012 05:41:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Monitoring PowerDNS via the internal web server</title>
		<link>http://blog.nachtarbeiter.net/2010/02/16/monitoring-powerdns-via-the-internal-web-server/</link>
		<comments>http://blog.nachtarbeiter.net/2010/02/16/monitoring-powerdns-via-the-internal-web-server/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 07:02:12 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[pdns]]></category>
		<category><![CDATA[powerdns]]></category>

		<guid isPermaLink="false">http://stage.nachtarbeiter.net/?p=585</guid>
		<description><![CDATA[If you want to stay informed about the current status of your PowerDNS server, there is no need to scan the logs or use third party tools like logcheckd. Actually, you might want to do this anyway, but PowerDNS provides an internal web server, which summarizes all the status information (including log messages) in a [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to stay informed about the current status of your <cite>PowerDNS</cite> server, there is no need to scan the logs or use third party tools like <code>logcheckd</code>. Actually, you might want to do this anyway, but <cite>PowerDNS</cite> provides an internal web server, which summarizes all the status information (including log messages) in a very nice and compact way for you to view.</p>
<p>By default, the web server will listen on port <code>8081</code> on <code>localhost</code>. That means, that you can&#8217;t view the status information from the outside network. To view the page, you could use a command line browser like <code>lynx</code>. You could change the interface of the web server to a public IP address, but this is <strong>very insecure</strong> and not recommended. The <cite>PowerDNS</cite> web server provides some sensitive information about your DNS server and you should not expose this information to the public. Also, the <cite>PowerDNS</cite> web server is probably not as thoroughly tested and hardened as <abbr title="for example">e.g.</abbr> <cite>Apache</cite> or <cite>nginx</cite>.  Another problem is, that you can only specify a single password and that you are limited to basic authentication, which is not very secure.</p>
<p>There is a secure way to retrieve the information provided by <cite>PowerDNS</cite> from outside your DNS server host. You could use <cite>Apache</cite>, <cite>nginx</cite> or any other web server you like as a proxy server. That way you can use more advanced authentication methods built into that web server to secure your status page. I will now show you how to do this using Apache 2 on Debian. We&#8217;ll need <code>mod_proxy</code>, <code>mod_proxy_http</code> and <code>mod_headers</code> enabled on the Apache 2 server. If you do not want to run an instance of Apache 2 on your DNS server, you could use an SSL tunnel or a secure back channel link to a remote Apache server to retrieve the status page. But this is beyond the scope of this post.</p>
<p>First, enable the internal <cite>PowerDNS</cite> web server by editing the configuration file.</p>
<ol class="code">
<li><code>webserver=yes</code></li>
<li><code>webserver-address=127.0.0.1</code></li>
<li><code>webserver-port=8081</code></li>
<li><code>webserver-password=PowerDNS</code></li>
</ol>
<p>This tells <cite>PowerDNS</cite> to run the internal web server on port <code>8081</code> of the <code>localhost</code> interface. The user name will be <code>admin</code> and the password will be <code>PowerDNS</code>. Of course you should change the password to something more secure, it&#8217;s just an example. After a restart of <cite>PowerDNS</cite> you can connect to your server from your DNS server host. The password is optional, but it&#8217;s safer that way, especially in an environment where you&#8217;ve got other users on your DNS server box.</p>
<p>Now install and enable the required modules of Apache 2 by executing the following commands.</p>
<ol class="code">
<li><code>apt-get install libapache2-mod-proxy-html</code></li>
<li><code>a2enmod proxy</code></li>
<li><code>a2enmod proxy_http</code></li>
<li><code>a2enmod headers</code></li>
</ol>
<p>The last module is only needed, if you set a password for your internal web server as recommended above. I assume that you&#8217;ve got some kind of virtual host configuration for your Apache server. You&#8217;ll want to add a new virtual host for the DNS status information. If you use a subdirectory, navigation might be a bit odd. Let&#8217;s add a new site to the available sites.</p>
<ol class="code">
<li><code>vi /etc/apache2/sites-available/status.dns.example.net</code></li>
<li><code>&lt;VirtualHost 192.168.0.1:80&gt;</code></li>
<li><code>        ServerName status.dns.example.net</code></li>
<li><code>        DocumentRoot /var/www/</code></li>
<li><code></code></li>
<li><code>        ProxyRequests Off</code></li>
<li><code>        &lt;proxy *&gt;</code></li>
<li><code>               Order deny,allow</code></li>
<li><code>               Allow from all</code></li>
<li><code>                ForceType 'text/html; charset=UTF-8'</code></li>
<li><code>        &lt;/proxy&gt;</code></li>
<li><code>        ProxyPass / http://localhost:8081</code></li>
<li><code>        ProxyPassReverse / http://localhost:8081</code></li>
<li><code></code></li>
<li><code>&lt;/VirtualHost&gt;</code></li>
</ol>
<p>Alright, so what are we doing here? Basically, we&#8217;re adding a new virtual host <code>status.dns.example.net</code> on our main interface of <code>dns.example.net</code>. We&#8217;re using a reverse proxy to to send all requests coming from the outside to our internal <cite>PowerDNS</cite> web server on port <code>8081</code>. Also, we&#8217;re forcing a <code>text/html</code> content type in the proxy request filter, because otherwise we would just get <code>text/plain</code> and we would simply see the source code, which is probably not what you want. Let&#8217;s enable the site for a test:</p>
<ol class="code">
<li><code>a2ensite status.dns.example.net</code></li>
<li><code>/etc/init.d/apache2 reload</code></li>
</ol>
<p>If you point your web browser to <code>status.dns.example.net</code> you should now see the internal status page of <cite>PowerDNS</cite>. If you set a password above, you will see a password dialogue. This is the password dialogue sent by the <cite>PowerDNS</cite> web server. The user name is <code>admin</code> and the password is your password. Try it out now, because we&#8217;ll get rid of this in a minute.</p>
<p>For security reasons, you probably want to use Apache 2 for authentication. E.g. you might want use a SSL connection and authenticate your co-workers using the internal LDAP server of your company intranet. You might even stay with the insecure basic authentication method, but use other user names. This is entirely up to you and beyond the scope of this post. Consult the Apache 2 documentation on how to do this. What you probably don&#8217;t want to do, however, is to authenticate twice (first your secure authentication method and then <cite>PowerDNS</cite> basic authentication. Luckily, we can configure the Apache 2 proxy to do the authentication for us. This is a bit tricky, though.<br />
To authenticate at the <cite>PowerDNS</cite> server, Apache 2 needs to send an additional <code>Authorization</code> header line to the <cite>PowerDNS</cite> server with every request it handles. We use the <code>RequestHeader</code> directive to override any existing <code>Authorization</code> header with our own authentication data. Add the following lines just before the end of the virtual host container.</p>
<ol class="code">
<li><code>        &lt;Location /&gt;</code></li>
<li><code>                RequestHeader Set Authorization "Basic YWRtaW46UG93ZXJETlM="</code></li>
<li><code>        &lt;/Location&gt;</code></li>
</ol>
<p>The above example works only for our example password, which is <code>PowerDNS</code>. Try it for a test. This is, because part of the header value is encrypted using the <code>base64</code> algorithm. You need to change the encrypted part <code>YWRtaW46UG93ZXJETlM=</code>. In plain text the encrypted string would read <code>admin:PowerDNS</code>, where <code>admin</code> is the user name and <code>PowerDNS</code> is the password. To use your own password, you need to encrypt the string <code>admin:yourownpassword</code> using the <code>base64</code> algorithm and replace our example string. Be sure to keep the <code>Basic</code> and the space. It is crucial for success, that you&#8217;ve got the right encrypted string. There are a number of <a href="http://www.motobit.com/util/base64-decoder-encoder.asp">online tools</a>, to encode and decode these strings. To ensure, that you&#8217;ve got the correct encryption method, encode the example string and compare it to the string above for a reference. If you&#8217;ve got the wrong string, it will not work.</p>
<p>Restart the Apache 2 server. To clear your password cache, restart your browser. Now surf to the site again. You will see, that the password dialogue is gone. Now, don&#8217;t forget to secure the page again using Apache 2. Under any circumstances, do <em>not</em> use <code>Directory</code> containers in the configuration. These will not apply to the proxy, because the proxy is not a physical directory on your server. Use <code>Location</code> containers like we did above for setting the <code>RequestHeader</code> directive. Also, you could still use insecure basic authentication to secure the page, if you wanted. It would work regardless of the <code>RequestHeader</code> magic.</p>
<h3>A light-weight alternative</h3>
<p>For those of you, who think that <cite>Apache</cite> is too heavy, here is an example for the <cite>nginx</cite> web server:</p>
<ol class="code">
<li><code>vi /etc/nginx/sites-available/status.dns.example.net</code></li>
<li><code>server {</code></li>
<li><code>   listen 192.168.0.1:80;</code></li>
<li><code>   server_name status.dns.example.net;</code></li>
<li><code>   root /var/www/nginx-default;</code></li>
<li><code>   location / {</code></li>
<li><code>      index index.html</code></li>
<li><code>      proxy_pass http://localhost:8081;</code></li>
<li><code>      proxy_redirect off;</code></li>
<li><code>      proxy_set_header Authorization "Basic YWRtaW46UG93ZXJETlM=";</code></li>
<li><code>   }</code></li>
<li><code>}</code></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.nachtarbeiter.net/2010/02/16/monitoring-powerdns-via-the-internal-web-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Where have all the records gone?</title>
		<link>http://blog.nachtarbeiter.net/2009/08/16/where-have-all-the-records-gone/</link>
		<comments>http://blog.nachtarbeiter.net/2009/08/16/where-have-all-the-records-gone/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 07:12:10 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[botnet]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://blog.nachtarbeiter.net/?p=824</guid>
		<description><![CDATA[I&#8217;m currently working on a web application and I set up a development version of this application on my local box. For my convenience I set up a number of unit tests to ensure that I do not accidentally break stuff when implementing new features. A number of unit tests that involved DNS failed repeatedly [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working on a web application and I set up a development version of this application on my local box. For my convenience I set up a number of <a href="http://en.wikipedia.org/wiki/Unit_testing">unit tests</a> to ensure that I do not accidentally break stuff when implementing new features. A number of unit tests that involved <abbr title="Domain Name System">DNS</abbr> failed repeatedly with a time-out. For various different reasons I&#8217;m using a router provided by my <abbr title="telephone company">telco</abbr>. During my investigation of the matter, I found out that the internal <abbr title="Domain Name System">DNS</abbr> server of the router did only answer requests for <code>A</code> records. Requests for any other record types timed out. I wonder why they do this. The only reason I can think of is that it&#8217;s part of my <abbr title="Internet Service Provider">ISP</abbr>s fight against malware installed on their customers Windows boxes, so this is not exactly evil. On the other hand, it is not very nice of them, because I&#8217;m sure that it cost me a few hours to debug problems that resulted out of this. I think that I&#8217;ll call them and at least tell them that there are customers out there who really need the real, full, unfiltered <abbr title="Domain Name System">DNS</abbr> service to get their work done.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nachtarbeiter.net/2009/08/16/where-have-all-the-records-gone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerDNS on Debian Lenny, Sarge or Woody (2)</title>
		<link>http://blog.nachtarbeiter.net/2009/04/23/powerdns-on-debian-lenny-sarge-or-woody-2/</link>
		<comments>http://blog.nachtarbeiter.net/2009/04/23/powerdns-on-debian-lenny-sarge-or-woody-2/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 11:40:11 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[pdns]]></category>
		<category><![CDATA[powerdns]]></category>
		<category><![CDATA[workshop]]></category>

		<guid isPermaLink="false">http://stage.nachtarbeiter.net/?p=553</guid>
		<description><![CDATA[This post is the second part of a workshop on the PowerDNS DNS server. In the first part of this workshop, we set up the PowerDNS server and it&#8217;s MySQL database backend. In this part of the workshop, I will show you how to add some domain data to your database and how to synchronize [...]]]></description>
			<content:encoded><![CDATA[<p>This post is the second part of a workshop on the <a href="http://www.powerdns.com/"><cite>PowerDNS</cite></a> <abbr title="Domain Name System">DNS</abbr> server. In <a href="http://blog.nachtarbeiter.net/2005/06/04/powerdns-on-debian-woody/">the first part of this workshop</a>, we set up the <cite>PowerDNS</cite> server and it&#8217;s <cite>MySQL</cite> database backend. In this part of the workshop, I will show you how to add some domain data to your database and how to synchronize this data to other <cite>PowerDNS</cite> servers automatically by using the so-called <cite>supermaster</cite> concept of <cite>PowerDNS</cite>. I will also show you how to enable <abbr title="Asynchronous Full Transfer Zone">AXFR</abbr> transfers to ensure compatibility with remote <cite>Bind</cite> slave servers.</p>
<h3>Prerequisites</h3>
<p>For the rest of this workshop it is assumed that you&#8217;ve got two <cite>PowerDNS</cite> installations on two separate physical hosts with the <abbr title="Internet Protocol">IP</abbr> addresses <code>192.168.0.1</code> and <code>192.168.1.2</code>, respectively. The first server has the host name <code>dns.example.net</code> and the second server has the host name <code>dns2.example.net</code>.</p>
<h3>Configure Master and Slave</h3>
<p>You probably want one <abbr title="Domain Name System">DNS</abbr> server to act as the master server and a number of additional servers to act as slaves. <cite>PowerDNS</cite> supports multiple master servers for one domain and it can be slave and master at the same time.</p>
<p>We will now configure <code>dns.example.net</code> as the master and <code>dns2.example.net</code> as the slave. To do this, add <code>master</code> to the configuration file of the first server and <code>slave</code> to the configuration file of the second server.</p>
<p>In a traditional setup, you would configure a domain name both on the master and the slave server. Additionally, you would specify record data for the domain name on the master server. The slave would then query the master server and download the record data. Whenever you change the record data on the master server, it would notify the slave server and the slave server would refresh the record data by downloading the new record data from the master server. In fact, you can do this with <cite>PowerDNS</cite> and it will work just fine. But <cite>PowerDNS</cite> can do more: If you tell your slave(s), that your master is a so-called <cite>supermaster</cite>, you do not need to setup new domain names on the slave. All you need to do is to setup the new domain name and its record data on the master server. If the domain has a <code>SOA</code> record and your slave is listed as one of the authoritative name servers for the domain, the master will notify your slave of the new domain name. Your slave recognizes, that your master is a <cite>supermaster</cite> server and adds the domain name to its configuration automatically. It works like magic. </p>
<p>To tell your slave, that your master server is a <cite>supermaster</cite> server, execute the following <abbr title="Structured Query Language">SQL</abbr> statement on your slave&#8217;s <cite>MySQL</cite> server.</p>
<ol class="code">
<li><code>INSERT INTO pdns.supermasters (`ip`, `nameserver`, `account`) VALUES ('192.168.0.1', 'dns2.example.net', 'test');</code></li>
</ol>
<p>This tells your slave, that your <cite>PowerDNS</cite> server with the <abbr title="Internet Protocol">IP</abbr> address <code>192.168.0.1</code> is a <cite>supermaster</cite> server. As you will see later, <cite>PowerDNS</cite> supports the concept of accounts. These do not have any influence on the operation of <cite>PowerDNS</cite>. You can specify account information for each domain name, which might be useful, if you want to find all domain names of a certain customer. If <cite>PowerDNS</cite> sets up a new domain name of a <cite>supermaster</cite>, it uses account information specified in the <code>supermasters</code> table for that <cite>supermaster</cite> server. In our case, all domains of the <cite>supermaster</cite> server <code>dns.example.net</code> will be added with the account information <code>test</code>. Note, that the <code>nameserver</code> column of the <code>supermasters</code> table is not the host name of the <cite>supermaster</cite> server. It is the host name of the slave server. Before the slave adds a new domain name from our <cite>supermaster</cite> server, it checks that the host name you specify in the the <code>nameserver</code> column is listed as one of the authoritative <abbr title="Domain Name System">DNS</abbr> servers for that domain name. Thus, we need to add the name of our slave there.</p>
<h3>Enable <abbr title="Asynchronous Full Transfer Zone">AXFR</abbr></h3>
<p>To exchange domain name and record data, your <cite>PowerDNS</cite> servers will use a method that is called <a href="http://en.wikipedia.org/wiki/DNS_zone_transfer"><abbr title="Asynchronous Full Transfer Zone">AXFR</abbr></a>. For security reasons, <abbr title="Asynchronous Full Transfer Zone">AXFR</abbr> is disabled by default. Edit the configuration files of your <cite>PowerDNS</cite> master server:</p>
<ol class="code">
<li><code>allow-axfr-ips=192.168.2.1</code></li>
<li><code>disable-axfr=no</code></li>
</ol>
<p>This will enable <abbr title="Asynchronous Full Transfer Zone">AXFR</abbr> for the <abbr title="Internet Protocol">IP</abbr> address of your slave server. Do not allow <abbr title="Asynchronous Full Transfer Zone">AXFR</abbr> for any server. This would pose a security risk. If you&#8217;ve got multiple slave servers, add all the <abbr title="Internet Protocol">IP</abbr> addresses of the slave servers separated by a comma. <abbr title="Asynchronous Full Transfer Zone">AXFR</abbr> is compatible with other name server software (<abbr title="for example">e.g.</abbr> <cite>Bind</cite>).</p>
<h3>Running <cite>PowerDNS</cite></h3>
<p><cite>PowerDNS</cite> should be in a state now, where it can start and connect to the <cite>MySQL</cite> database with no problems. For now, we will start <cite>PowerDNS</cite> in monitoring mode. That way we can follow everything that happens live on the console. To start up <cite>PowerDNS</cite> in monitoring mode, use the following command.</p>
<ol class="code">
<li><code>/etc/init.d/pdns monitor</code></li>
</ol>
<p>Later, you may want to run <cite>PowerDNS</cite> in the background. To do this just run the following command.</p>
<ol class="code">
<li><code>/etc/init.d/pdns start</code></li>
</ol>
<p>Once you have started up both the master and the slave <cite>PowerDNS</cite> server we can start adding domain names.</p>
<h3>Adding your first domain name</h3>
<p>To add a new domain name, you need to add a new entry to the <code>domains</code> table of your database. To do so, execute the following <abbr title="Structured Query Language">SQL</abbr> query on the master server:</p>
<ol class="code">
<li><code>INSERT INTO `pdns.domains` (`id`, `name`, `type`, `account`) VALUES (1, 'example.com', 'MASTER', 'test');</code></li>
</ol>
<p>This will add the <code>example.com</code> domain name to the database. The type <code>MASTER</code> indicates, that our master server will be the master for this domain. The account name is optional, it is for your information only. It is important to note, that the <code>id</code> of our new domain name is <code>1</code>. We&#8217;ll need this in a second.</p>
<p>Next, we need to add some records, i.e. some zone data, to the database for <cite>PowerDNS</cite> to serve. The records need to be added to the <code>records</code> table of the database. <cite>PowerDNS</cite> supports a number of different records. Depending on the type of the record, you need to provide different values for the <code>type</code>, <code>content</code> and <code>prio</code> columns. Check the <a href="http://doc.powerdns.com/types.html"><cite>PowerDNS</cite> documentation on supported record types and their storage</a> to get an idea of what you need. For your convenience, I&#8217;ll give you a few examples of common record types.</p>
<p>The first thing you want to add is a <code>SOA</code> record. A typical <code>SOA</code> record would look like this:</p>
<ol class="code">
<li><code>INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'example.com','SOA', 'dns.example.net. hostmaster.example.net. 2009042301 10800 3600 604800 3600', 3600);</code></li>
</ol>
<p>Note the <code>domain_id</code>, which is set to the <code>id</code> value of our <code>example.com</code> domain. Then there is the fully qualified domain name, that this record is valid for. You are probably familiar with the values of the <code>type</code>, <code>content</code> and <code>ttl</code> columns. If not, check the documentation. </p>
<p>Next, let&#8217;s add a few name servers. It is important that your master and all your slaves are listed here, of course. </p>
<ol class="code">
<li><code>INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'example.com','NS', 'dns.example.net', 3600);</code></li>
<li><code>INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'example.com','NS', 'dns2.example.net', 3600);</code></li>
</ol>
<p>You probably want some <code>A</code> records:</p>
<ol class="code">
<li><code>INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'example.com','A', '192.168.0.3', 3600);</code></li>
<li><code>INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, 'sales.example.com','A', '192.168.0.4', 3600);</code></li>
<li><code>INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`) VALUES (1, '*.example.com','A', '192.168.0.2', 3600);</code></li>
</ol>
<p>The first of these records is for the <code>example.com</code> domain name. The second is for a subdomain, i.e. <code>sales.example.com</code>. The third <code>A</code> record is special. It is a wildcard record. It matches any subdomain, that is not already specified, i.e. everything except <code>example.com</code> and <code>sales.example.com</code>.</p>
<p>Let&#8217;s finish by adding some <code>MX</code> records:</p>
<ol class="code">
<li><code>INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`) VALUES (1, 'example.com', 'MX','mail.example.net', 3600, 10);</code></li>
<li><code>INSERT INTO `pdns.records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`) VALUES (1, 'example.com', 'MX','mailbackup.example.net', 3600, 20);</code></li>
</ol>
<p>Within a short time you will see the following information showing up in the log file of your slave server. Don&#8217;t be impatient, it takes some time. You should see something within a minute, though.</p>
<ol class="code">
<li><code>Feb 07 21:43:26 Received NOTIFY for example.com from 192.168.0.1 for which we are not authoritative</code></li>
<li><code>Feb 07 21:43:26 Created new slave zone 'example.com' from supermaster 192.168.0.1, queued axfr</code></li>
<li><code>Feb 07 21:43:27 gmysql Connection succesful</code></li>
<li><code>Feb 07 21:43:27 No serial for 'example.com' found - zone is missing?</code></li>
<li><code>Feb 07 21:43:27 AXFR started for 'example.com', transaction started</code></li>
<li><code>Feb 07 21:43:27 AXFR done for 'example.com', zone committed</code></li>
</ol>
<p>And the equivalent on the master server:</p>
<ol class="code">
<li><code>Feb  7 21:43:20 1 domain for which we are master needs notifications</code></li>
<li><code>Feb  7 21:43:20 Queued notification of domain 'example.com' to 192.168.1.2</code></li>
<li><code>Feb  7 21:43:21 AXFR of domain 'example.com' initiated by 192.168.1.2</code></li>
<li><code>Feb  7 21:43:21 Removed from notification list: 'example.com' to 192.168.1.2 (was acknowledged)</code></li>
<li><code>Feb  7 21:43:21 gmysql Connection succesful</code></li>
<li><cdoe>Feb  7 21:43:21 AXFR of domain &#8216;example.com&#8217; to 192.168.1.2 finished</cdoe></li>
<li><code>Feb  7 21:43:23 No master domains need notifications</code></li>
</ol>
<p>This looks like a successful <abbr title="Asynchronous Full Transfer Zone">AXFR</abbr> of the <code>example.com</code> domain name. Let&#8217;s see, if the domain was really added to the <cite>MySQL</cite> database on the slave server:</p>
<ol class="code">
<li><code>mysql> SELECT * FROM pdns.domains WHERE name='example.com';</code></li>
<li><code>+----+--------------+---------------+------------+-------+-----------------+---------+</code><code></code></li>
<li><code>| id | name         | master        | last_check | type  | notified_serial | account |</code><code></code></li>
<li><code>+----+--------------+---------------+------------+-------+-----------------+---------+</code><code></code></li>
<li><code>|  1 | example.com | 192.168.0.2 | 1234039407 | SLAVE |            NULL | test    | </code><code></code></li>
<li><code>+----+--------------+---------------+------------+-------+-----------------+---------+</code></li>
<li><code>1 row in set (0.00 sec)</code></li>
</ol>
<p>Quite cool, isn&#8217;t it? You can also query the <code>records</code> table. All your records will be there. Every time you add a new record and raise the serial number, <cite>PowerDNS</cite> will notify your slave and the record data will be updated automatically. </p>
<h3>Adding slave domains</h3>
<p>Sometimes, you might want to add a slave domain to one of your servers manually. Suppose your master server acts as a slave server for the domain <code>example.org</code>. Say, the master server of the <code>example.org</code> domain is a remote <cite>Bind</cite> server with the <abbr title="Internet Protocol">IP</abbr> address <code>192.168.2.34</code>. First, make sure that <code>AXFR</code> with that server is allowed (see above). Then, execute the following <abbr title="structured query language">SQL</abbr> query on your server.</p>
<ol class="code">
<li><code>INSERT INTO `pdns.domains` (`id`, `name`, `master`, `type`, `account`) VALUES (2, 'example.org', '192.168.2.34',  'SLAVE', 'test');</code></li>
</ol>
<p>Voilà. That&#8217;s it. <cite>PowerDNS</cite> will take care of the rest.</p>
<h3>Limitations of the <cite>supermaster</cite> mode</h3>
<p>Unfortunately, <cite>supermaster</cite> mode is not equivalent to database synchronization. Automatic set up of new domain names and record data works like a charm. What doesn&#8217;t work, though, is the automatic deletion of domain names. If you delete your domain name on the master server, you need to delete it on all slaves manually. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nachtarbeiter.net/2009/04/23/powerdns-on-debian-lenny-sarge-or-woody-2/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PowerDNS on Debian Lenny, Sarge or Woody (1) [Update3]</title>
		<link>http://blog.nachtarbeiter.net/2005/06/04/powerdns-on-debian-woody/</link>
		<comments>http://blog.nachtarbeiter.net/2005/06/04/powerdns-on-debian-woody/#comments</comments>
		<pubDate>Sat, 04 Jun 2005 14:51:36 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[pdns]]></category>
		<category><![CDATA[powerdns]]></category>
		<category><![CDATA[workshop]]></category>

		<guid isPermaLink="false">/?p=243</guid>
		<description><![CDATA[PowerDNS is an extremly powerful DNS server. It supports a number of relational database backends, loadbalancing and failover algorithms. Deploying PowerDNS on all our servers has a few major advantages over our current Bind based setup. PowerDNS has native MySQL database backend support and is therefore easier to integrate with our customer control panel. Also [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.powerdns.com/"><cite>PowerDNS</cite></a> is an extremly powerful <abbr title="Domain Name System">DNS</abbr> server. It supports a number of relational database backends, loadbalancing and failover algorithms.</p>
<p>Deploying <cite>PowerDNS</cite> on all our servers has a few major advantages over our current <a href="http://www.isc.org/index.pl?/sw/bind/">Bind</a> based setup.</p>
<ul>
<li><cite>PowerDNS</cite> has native MySQL database backend support and is therefore easier to integrate with our customer control panel. Also changes to the MySQL database are discovered automatically, eliminating the need for periodical restarts. All changes are applied almost instantly.</li>
<li><cite>PowerDNS</cite> can act as a so-called <cite>supermaster</cite>, synchronizing itsself automatically with slave servers. Zone transfers occur even without adding a domain name to all of the slaves beforehand. It is enough if the domain is added to the database of the master server.</li>
</ul>
<p>I will now describe how to setup <cite>PowerDNS</cite> on a Linux box running Debian Woody or Debian Sarge or Debian Lenny and utilizing the MySQL database backend.</p>
<h3>Initial Setup</h3>
<p>Official Debian packages for <cite>PowerDNS</cite> are availlable since Debian Sarge, but you can download Woody packages from <a href="http://www.powerdns.com/downloads/">http://www.powerdns.com/downloads/</a>, if you use Woody. There is no apt repository availlable, however.</p>
<p>After downloading the most recent package with <code>wget</code>, you can install it on your system with <code>dpkg</code>.</p>
<ol class="code">
<li><code>wget http://downloads.powerdns.com/releases/deb/stable/pdns-static_2.9.17-1_i386.deb</code></li>
<li><code>dpkg -i pdns-static_2.9.17-1*</code></li>
</ol>
<p>If you&#8217;ve got a Sarge or newer installation of Debian just run <code>apt-get</code> as follows and the necessary packages will be installed automatically.</p>
<ol class="code">
<li><code>apt-get install pdns-recursor pdns-backend-mysql</code></li>
</ol>
<p>You&#8217;ll notice that <cite>PowerDNS</cite> will not start up directly after installing the package. That&#8217;s because the standard configuration file does not come preconfigured for a specific backend; we have to configure <cite>PowerDNS</cite> for a backend of our choice first. See below for a sample output of a fresh <cite>PowerDNS</cite> installation.</p>
<ol class="code">
<li><code>/etc/init.d/pdns monitor</code></li>
<li><code>Jun 04 10:13:56 Unable to launch, no backends configured for querying.</code></li>
</ol>
<h3>Gerneal Settings</h3>
<p>Before we will begin to configure the database backend, we&#8217;ll have a look at some basic settings first. If you use Sarge, you can skip this part. You will be asked for the information below during configuration of the package. If you use Lenny or Woody, you need to specify an IP address and a port, to which <cite>PowerDNS</cite> should bind. You should specify an alternate port for non-production use. That allows you to run <cite>PowerDNS</cite> in parallel to an existing nameserver installation during the initial setup period.</p>
<p>On Woddy and Sarge, edit <code>/etc/powerdns/pdns.conf</code> directly. In Lenny, do edit the file <code>/etc/powerdns/pdns.d/pdns.local</code> file instead. This way it will be easier to update the package later.</p>
<ol class="code">
<li><code>vi /etc/powerdns/pdns.d/pdns.local</code></li>
<li><code>local-address=192.168.0.2</code></li>
<li><code>local-port=5300</code></li>
</ol>
<p>If you want to bind <cite>PowerDNS</cite> to multiple IP addresses change the <code>local-address</code> setting as follows.</p>
<ol class="code">
<li><code>local-address=192.168.0.2,192.168.0.3</code></li>
</ol>
<p>If your server has multiple IP addresses configured, you should also set the IP address, which <cite>PowerDNS</cite> will use as the source address when sending out answers to queries from clients or remote servers.</p>
<ol class="code">
<li><code>query-local-address=192.168.0.2</code></li>
</ol>
<h3>MySQL</h3>
<p>Before we start to configure <cite>PowerDNS</cite> to use the MySQL backend, we need to setup the required database and tables.</p>
<ol class="code">
<li><code>CREATE DATABASE pdns;</code></li>
<li><code>USE pdns;</code></li>
<li><code /></li>
<li><code>CREATE TABLE domains (</code></li>
<li><code>  id              INT auto_increment,</code></li>
<li><code>  name	        VARCHAR(255) NOT NULL,</code></li>
<li><code>  master          VARCHAR(20) DEFAULT NULL,</code></li>
<li><code>  last_check      INT DEFAULT NULL,</code></li>
<li><code>  type            VARCHAR(6) NOT NULL,</code></li>
<li><code>  notified_serial INT DEFAULT NULL,</code></li>
<li><code>  account         VARCHAR(40) DEFAULT NULL,</code></li>
<li><code>  primary key (id)</code></li>
<li><code>)type=InnoDB;</code></li>
<li><code /></li>
<li><code>CREATE UNIQUE INDEX name_index ON domains(name);</code></li>
<li><code /></li>
<li><code>CREATE TABLE records (</code></li>
<li><code>  id              INT auto_increment,</code></li>
<li><code>  domain_id       INT DEFAULT NULL,</code></li>
<li><code>  name            VARCHAR(255) DEFAULT NULL,</code></li>
<li><code>  type            VARCHAR(6) DEFAULT NULL,</code></li>
<li><code>  content         VARCHAR(255) DEFAULT NULL,</code></li>
<li><code>  ttl             INT DEFAULT NULL,</code></li>
<li><code>  prio            INT DEFAULT NULL,</code></li>
<li><code>  change_date     INT DEFAULT NULL,</code></li>
<li><code>  primary key(id)</code></li>
<li><code>)type=InnoDB;</code></li>
<li><code /></li>
<li><code>CREATE INDEX rec_name_index ON records(name);</code></li>
<li><code>CREATE INDEX nametype_index ON records(name,type);</code></li>
<li><code>CREATE INDEX domain_id ON records(domain_id);</code></li>
<li><code /></li>
<li><code>CREATE TABLE supermasters (</code></li>
<li><code>  ip              VARCHAR(25) NOT NULL, </code></li>
<li><code>  nameserver      VARCHAR(255) NOT NULL,</code></li>
<li><code>  account         VARCHAR(40) DEFAULT NULL</code></li>
<li><code>);</code></li>
</ol>
<p>We also have to create a new MySQL user account exclusively for <cite>PowerDNS</cite> and need to set the rights accordingly.</p>
<ol class="code">
<li><code>GRANT USAGE ON *.* TO `pdns`@localhost IDENTIFIED BY "********"</code></li>
<li><code>WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0</code></li>
<li><code>MAX_UPDATES_PER_HOUR 0;</code></li>
<li><code /></li>
<li><code>GRANT ALL PRIVILEGES ON `pdns`.`domains` TO `pdns`@localhost;</code></li>
<li><code /></li>
<li><code>GRANT ALL PRIVILEGES ON `pdns`.`records` TO `pdns`@localhost;</code></li>
<li><code /></li>
<li><code>GRANT SELECT ON `pdns`.`supermasters`</code></li>
<li><code>TO `pdns`@localhost;</code></li>
</ol>
<p>The neccessary database is now setup and the empty tables await our data. <del>Because <cite>PowerDNS</cite> is unable to connect using sockets, we have to modify the MySQL configuration and make it bind itsself to <code>localhost</code>.</del></p>
<ol class="code">
<li><del><code>vi /etc/mysql/my.cnf</code></del></li>
<li><del><code>#skip-networking</code></del></li>
<li><del><code>bind-address = 127.0.0.1</code></del></li>
</ol>
<p>All we need to do now is to make another change to the <cite>PowerDNS</cite> configuration.</p>
<ol class="code">
<li><code>vi /etc/powerdns/pdns.d/pdns.local</code></li>
<li><code>launch=gmysql</code></li>
<li><del><code>gmysql-host=127.0.0.1</code></del></li>
<li><code>gmysql-user=pdns</code></li>
<li><code>gmysql-password=********</code></li>
<li><code>gmysql-dbname=pdns</code></li>
</ol>
<p>Let's have a little test of the installation.</p>
<ol class="code">
<li><code>/etc/init.d/pdns monitor</code></li>
<li><code>Jun 04 16:46:34 gmysql Connection successful</code></li>
</ol>
<p>Perfect. <cite>PowerDNS</cite> is setup successfully. The initial setup is completed.  See you later for <a href="http://blog.nachtarbeiter.net/2009/02/07/powerdns-on-debian-lenny-sarge-or-woody-2/">part two of this workshop</a>, in which we will insert some random domain data into our new database and setup a typical superserver/slave framework.</p>
<p>Update1: Recently Debian 3.1 Sarge was released. I changed this tutorial a bit to accommodate some differences between Woody and Sarge.</p>
<p>Update2: Actually, <cite>PowerDNS</cite> is perfectly able to use MySQL sockets, if you omit the <code>gmysql-host</code> option. Lesson learned. Post changed.</p>
<p>Update3: Debian Lenny will be released shortly. I changed this tutorial a bit to accommodate some differences between Woody, Sarge and Lenny.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nachtarbeiter.net/2005/06/04/powerdns-on-debian-woody/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

