<?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>ipsidixit.net &#187; DNS</title>
	<atom:link href="http://www.ipsidixit.net/tag/dns/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ipsidixit.net</link>
	<description>A far off place</description>
	<lastBuildDate>Thu, 08 Dec 2011 06:30:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Content filtering in a home network</title>
		<link>http://www.ipsidixit.net/2011/02/07/content-filtering-in-a-home-network/</link>
		<comments>http://www.ipsidixit.net/2011/02/07/content-filtering-in-a-home-network/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 11:04:23 +0000</pubDate>
		<dc:creator>sgroarke</dc:creator>
				<category><![CDATA[FPage]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[ethernet]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[IPv6]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[nslookup]]></category>
		<category><![CDATA[opendns]]></category>
		<category><![CDATA[shorewall]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.ipsidixit.net/?p=425</guid>
		<description><![CDATA[<p>With two young children starting to make increasing use of the Internet, my attention has turned in recent times to the thorny subject of Content Filtering. This posting is actually going to look at a technical approach I settled upon, however one cannot help mentioning, at least in passing, some of the wider issues [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ipsidixit.net/wp-content/2011/02/footer_logo.gif"><img class="size-full wp-image-447 alignleft" style="margin-left: 50px; margin-right: 50px; margin-top: 30px; margin-bottom: 30px;" title="opendns_logo" src="http://www.ipsidixit.net/wp-content/2011/02/footer_logo.gif" alt="" width="100" height="40" /></a>With two young children starting to make increasing use of the Internet, my attention has turned in recent times to the thorny subject of Content Filtering. This posting is actually going to look at a technical approach I settled upon, however one cannot help mentioning, at least in passing, some of the wider issues involved.</p>
<p>As a parent I do not believe in raising children in some sort of bubble, totally devoid of anything that could possibly &#8220;harm&#8221; them. That applies to the Internet too &#8211; my hope is to raise children who are able to understand and deal with things, rather than require protection from them. To that end, Internet access for my children involves their parents first and foremost! They use a laptop, after asking permission, in the kitchen, in view of everyone else. I&#8217;m interested in what they are doing on it (genuinely so, not as some excuse to snoop!) and they want me to help and guide them. Email? Sure, make full use of it. But all emails sent to your address also get forwarded to me too guys&#8230; Why? So I can see what you&#8217;re receiving! Very open. Very honest. Nothing underhand. Those are the rules in this house.</p>
<p>And that approach actually covers probably 90% of what is required. However there&#8217;s still a small part that needs attention. As most adults know, there&#8217;s some weird stuff in some corners of the Internet. <em>Really</em> weird. <em>Disturbingly</em> weird. Stuff which I do not want my young children to see, even if accidentally. Being a very liberal sort, and totally anti-censorship with regard to what consenting adults view, I do not support any move to remove such stuff from the Internet. Weird, sick, depraved, whatever&#8230; Some of it may not be at all nice, but it&#8217;s there and it can be found. I just don&#8217;t want young children to accidentally find it. So what is a network engineer father to do&#8230;?</p>
<h1>Content filtering &#8211; 4 approaches</h1>
<p>Broadly speaking there are four way of approaching content filtering in the home environment:</p>
<ul>
<li>Workstation filtering</li>
<li>Network filtering</li>
<li>ISP filtering</li>
<li>DNS blocking</li>
</ul>
<p><span id="more-425"></span>The first three are all variations on the same theme. They vary in terms of the &#8220;Where do you do it?&#8221;</p>
<h2>Workstation</h2>
<p>There are many software packages out there which will filter content locally on the PC being used to browse the web. In a similar manner to that used by the more familiar virus detection software, one can purchase and run content filtering software which aims to identify and block various categories of content. The difficulty faced with this approach is that it&#8217;s not at all easy to identify what to block! Just to take the most obvious candidate category for blocking: pornography. The software can, and will, have lists of the names of the popular, known web-sites with porn. And with some enormous proportion of the Internet being porn, that will already be a long long list! Then we have the challenge of the fact that every day goodness knows how many hundreds of new porn sites will appear, and old ones disappear. The list of sites cannot be fully up to date. So the software will also need to include elements of heuristic detection: identifying porn indirectly and blocking it. So we&#8217;re now into looking and scanning all the traffic to and fro for words or patterns which might identify it as porn.  And so on. It&#8217;s a computationally intensive exercise, and requires frequent updating with new lists of patterns, URLs, IP addresses and so on.</p>
<p>The task is very similar to virus detection, with the frequent updates required, slowing down of communication to an extent, higher CPU usage, and so on.</p>
<p>The software out there is worth consideration for some &#8211; I&#8217;m not saying it&#8217;s a bad approach. But it has unavoidable limitations. Two obvious ones which apply to me are:</p>
<ul>
<li>Locked to a particular PC &#8211; If I install the software on one PC, then I cannot let the kids use another PC as it will be unprotected, unless I pay for and install the software there too.</li>
<li>Linux. A big issue for me is that we only have a single Windows PC in the house (hooray!) All the others (too many&#8230; way too many&#8230;) including that used by the children, run Linux. And such packages are few and far between for Linux&#8230;</li>
</ul>
<h2>Home network</h2>
<p>An approach I used for a while, with success, was to filter on the gateway device on my network. A quick summary here: at home my Internet connection terminates on a gateway firewall/router system. This system performs all manner of network-related functions. The key one is to run my Linux-based firewall. A host of other jobs get handled by this box too: VPN termination, media serving, DHCP, IPv6 routing, the list is long. Given that all of our Internet traffic traverses this system it is ideally suited to perform a filtering function.</p>
<p>To that end, for a while I ran <a href="http://www.dansguardian.org/" target="_blank">Dans Guardian</a> on my firewall. This is a sophisticated bit of software, and not entirely trivial to set up and get working. Apart from quite a lot of configuration itself, it also requires a web-proxy to be running on the firewall. I ran <a href="http://www.squid-cache.org/">squid</a> to fulfil that requirement. And then there&#8217;s the requirement to &#8220;hook&#8221; users into it. That involves either configuring the workstation to use a designated web proxy (and possible authentication required there &#8211; depends upon what exactly you want to achieve) or using IPTables on the firewall to intercept traffic from a given workstation and force it via the proxy. Various approaches, all quite interesting, but only if you find networks interesting&#8230; Many would find it simply &#8220;complicated&#8221;.</p>
<p>Once up and running, however, there are then further challenges to be faced. Firstly there&#8217;s the question of overhead. That is, how much load does it place on the gateway device, and hence how much delay or slowness does it introduce to the web browsing. My kids may not need the snappiest, lightening fast response times possible, but nor do they want to wait tens of seconds to see a page, or have some You Tube video constantly stop and start. Let me be clear here (and make sure I&#8217;m fair to Dans Guardian): if the device running it is powerful (in terms of CPU, memory, disk and so on) then it&#8217;s great. Really good. Trouble is, however, that a lot of boxes used as gateway routers/firewalls are not, by their nature, so highly specified. And that applied to me. My installation was, frankly, not fast enough. Much of the time it would work OK-ish, but often there would be very long delays indeed.</p>
<p>If you have a powerful box you can dedicate to such filtering, then do go ahead and consider it.</p>
<p>On other issue I also had to tackle was that of updates: as described for the Workstation solution, filtering software, wherever it is located, needs to be kept up to date. Dans Guardian does not come with an update mechanism, nor source of updates. There are sources of such updates out there if you search, but again, it&#8217;s an extra piece of work to do this and get it all set up correctly, auto updating silently every day.  As before, not a criticism of the software that has been made freely available &#8211; but something that does need to be taken in to account.</p>
<h2>ISP</h2>
<p>Many ISPs offer a filtering service to their customers. This is of course attractive, as it entirely removes the need to perform the filtering and blocking locally to the home network. The work is offloaded to the ISP. While there may be a charge associated with this, it may be worth considering. The main, and maybe for many significant, disadvantage to it is the all-or-nothing approach. If you have many PCs (and hence different users) within the home network, you may only want to block certain stuff from certain PCs. I may not want my kids viewing<em> DominatrixFrenchMaids.com, </em>but (purely for research purposes, of course) their father may need to. (God knows, such a site probably exists, but I dare not look&#8230;) More realistically, there are other sites which are more genuinely OK for adults, but not for young children. If one has an interest in 20th Century history, a sad reflection on humankind is that there are some horrible things which can be seen&#8230; For older children and adults, that&#8217;s fine and indeed educational. But not below a certain age. I&#8217;d like to maintain the illusion of a nice world for at least a little while longer.</p>
<p>So ISP filtering is attractive in terms of removing the work from the home. But it does come, in general, with a certain amount of inflexibility.</p>
<h2>DNS blocking</h2>
<p>This last technique is somewhat different from the others. Most people have at least some awareness that the names we use on the Internet (www.ipsidixit.net) actually map on to so-called IP addresses. For example www.ipsidixit.net is mapped via a DNS (Domain Name Service) to the IP address 217.70.191.54 (And to IPv6 2001:4b98:dc0:41:216:3eff:feaa:964a &#8211; I&#8217;m soooo hip and trendy&#8230;)</p>
<p>Yet no one in their right mind (nor even a network engineer) bothers with the numerical version. You just bang in the name and have your computer us DNS to resolve it to an IP address.</p>
<p>Most PCs will use one or more DNS devices specified and operated by their ISP. Used &#8220;normally, for example, my ISP (free.fr) provides two DNS systems for workstations to use.</p>
<p>However one does not need to use their suggestions. One can, in general, use other DNSs operated by third-parties.</p>
<p>The point is, then, that if one used a DNS service which had a constantly updated blacklist of sites which are &#8220;undesirable&#8221;, one could block access to them by simply declining to resolve them to their correct address. This then offers the benefits of ISP Blocking in so far as the load of shifted outside of the home network, but with the added flexibility that only workstations that require protection need use the &#8220;filtering&#8221; DNS. Other workstations can use the normal DNS.</p>
<p>I found that <a href="http://www.opendns.com/">OpenDNS</a> provide such a service, and have stated to make use of it. It&#8217;s free (they have some paid options too &#8211; but the free one seems fine for me) I have no association with OpenDNS, and am only &#8220;promoting&#8221; them as what they offer seems neat and useful. If others have knowledge of other similar services, please do post them in a comment &#8211; I&#8217;m not trying to make this exclusive to OpenDNS! In fact I&#8217;d like to compare OpenDNS to some others.</p>
<p>The service they offer is to provide DNS addresses which can have a selectable level of filtering applied. The spectrum is covered, from porn, violence, drug use, etc. through to shopping sites, social networking sites, etc. You get to choose which categories to block and which to allow.</p>
<p>And it does seem to work really rather well indeed. Below I am going to detail how I set it up within my network, integrating it within the DNS caching system already used.</p>
<p>The main weakness of the system is that with some knowledge and effort it can be circumvented (as, of course, can most systems) One could take the trouble to manually find the Name &lt;&#8211;&gt; IP mapping for a domain and enter that directly into a browser, thereby bypassing the DNS. However such a bypass would be very cumbersome to use, since even if you use an IP to land on a page, probably any link off that page will in turn require DNS, and would then need to be manually decoded, etc. Workable, but hard work. By the time my kids are knowledgeable enough to work all that out, they will probably be old enough to look after themselves!</p>
<h1>Integrating OpenDNS into a Linux firewall, already running DNSMasq</h1>
<p>My home network has <a href="http://www.thekelleys.org.uk/dnsmasq/doc.html">DNSMasq</a> running on a central gateway/server/firewall box. DNSMasq is responsible for DHCP (i.e. allocating IP addresses on my home network) and also DNS caching. To that end, it announces, via DHCP, that it  is the DHCP server to be used by devices. Then it, in turn, resolves addresses via the ISP-supplied DNSs. It caches then DNS lookups locally.</p>
<p>In the DHCP configuration it has a pool of addresses available for any device to use, but most of the devices on the network have pre-allocated addressees reserved for them within the DNSMasq configuration. These are allocated based upon the Ethernet MAC address of a device. This is a very common technique to use with DHCP.</p>
<p>Given that, where now a device will be handed an IP address and the address of a DNS server to use (where that DNS server will actually be the same as the DNSMasq device itself) we want to change the config so that for certain devices (the childrens&#8217; PC) when an IP address is handed out it will instead be given with the DNS addresses of the OpenDNS filtering systems. Then all DNS requests from that PC will no longer be locally forwarded to the gateway device, but will instead be routed out externally to OpenDNS, where they can be answered or blocked as appropriate.</p>
<p>The DNSMasq config to achieve this is slightly fiddly, so I am providing it here more or less in its entirety (a few names omitted and some light obfuscation of MACs etc.), but only highlighting the parts that particularly pertain to the OpenDNS filtering setup.</p>
<pre style="padding-left: 30px;"># Configuration file for dnsmasq.
domain-needed
resolv-file=/etc/resolv.conf
no-resolv
no-poll

# Add other name servers here, with domain specs if they are for
# non-public domains.
server=/localnet/192.168.0.22</pre>
<pre style="padding-left: 30px;"><strong><em><span style="color: #ff6600;">This part is not related to OpenDNS in any way: I don't use my ISP's DNS for normal use - I instead use Google's Public DNS.
</span></em># Google Public DNS servers
server=8.8.8.8
server=8.8.4.4</strong>

# Add local-only domains here, queries in these domains are answered
# from /etc/hosts or DHCP only.
local=/localnet/

interface=eth1
expand-hosts
domain=localnet

# For general purpose use, use this range.
dhcp-range=192.168.0.128,192.168.0.160,12h</pre>
<pre style="padding-left: 30px;"><strong><span style="color: #ff6600;">This is for OpenDNS. We use the dhcp-mac config to tag these special devices for filtering:
</span># MAC list for openDNS filtering
dhcp-mac=opendns,00:c0:9f:12:34:56	# Laptop on-board
dhcp-mac=opendns,00:90:4b:12:34:56	# Laptop wifi</strong></pre>
<pre style="padding-left: 30px;"><strong><span style="color: #ff6600;">Here we're back for normal dhcp-host preallocation for known unfiltered devices:
</span></strong># Most ip addresses are pre-allocated here
dhcp-host=00:50:ba:12:34:56,aname,192.168.0.2,720m
dhcp-host=00:18:8B:12:34:56,anothername,192.168.0.3,5m
dhcp-host=00:90:4b:12:34:56,laptop_wifi,192.168.0.4,720m
dhcp-host=00:26:37:12:34:56,galaxy,192.168.0.5,60m
dhcp-host=00:18:41:12:34:56,magic,192.168.0.6,60m
dhcp-host=00:26:82:12:34:56,eva9150,192.168.0.7,720m
dhcp-host=00:c0:9f:12:34:56,laptop_eth,192.168.0.8,720m
dhcp-host=00:14:29:12:34:56,camera,192.168.0.10,120m
dhcp-host=00:21:5A:12:34:56,printer,192.168.0.11,720m
dhcp-host=00:40:63:12:34:56,aservername,192.168.0.22,infinitem</pre>
<pre style="padding-left: 30px;"><strong><span style="color: #ff6600;">The devices tagged "opendns" above here get special DHCP options pointing them to the OpenDNS filtering-servers.
</span># OpenDNS content filtering servers
# Specify the two OpenDNS first, then ourselves third for local stuff
dhcp-option=opendns,6,208.67.222.222,208.67.220.220,192.168.0.22</strong></pre>
<pre style="padding-left: 30px;"><strong><span style="color: #ff6600;">Note also the "192.169.0.22" on the end - this is optional, if you still want the filtered devices to be able to resolve local names.
</span></strong>
dhcp-authoritative
cache-size=150
clear-on-reload</pre>
<p>Anyone who has an existing DNSMasq configuration should find the above more than enough to change it to point arbitrary devices at the OpenDNS systems.</p>
<h1>Summary</h1>
<p>Nothing, but nothing, replaces a conscientious adult supervising, guiding and helping get to grips with the Internet. However even with that it&#8217;s still all too easy for some stuff to pop up which is better left hidden! This article highlight some of the general technical approaches one can take, and in particular that of DNS filtering with a service such as OpenDNS, optionally using a Linux device to semi-automatically allocate filtering to some device but not others.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ipsidixit.net/2011/02/07/content-filtering-in-a-home-network/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IPv6 and DNS</title>
		<link>http://www.ipsidixit.net/2010/04/02/243/</link>
		<comments>http://www.ipsidixit.net/2010/04/02/243/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 08:33:37 +0000</pubDate>
		<dc:creator>sgroarke</dc:creator>
				<category><![CDATA[FPage]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[icmp6]]></category>
		<category><![CDATA[IPv6]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ndisc6]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[nslookup]]></category>
		<category><![CDATA[ping6]]></category>
		<category><![CDATA[rdisc6]]></category>
		<category><![CDATA[rdnss]]></category>
		<category><![CDATA[rdnssd]]></category>
		<category><![CDATA[tcpdump]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.ipsidixit.net/2010/04/02/243/</guid>
		<description><![CDATA[<p>IPv6 DNS &#8211; It works for me&#8230;.. but it shouldn&#8217;t.</p> <p>When in my IPv6 environment I perform a test ping to, say, Google, it seems to work great:</p> ping6 ipv6.google.com PING ipv6.google.com(2a00:1450:8006::6a) 56 data bytes 64 bytes from 2a00:1450:8006::6a: icmp_seq=1 ttl=55 time=49.3 ms 64 bytes from 2a00:1450:8006::6a: icmp_seq=2 ttl=55 time=44.6 ms . . . [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-227" style="margin-top: 10px; margin-bottom: 10px; margin-left: 15px; margin-right: 15px;" title="IPv6 Logo" src="http://www.ipsidixit.net/wp-content/2010/02/IPv6-logo.png" alt="" width="100" height="60" />IPv6 DNS &#8211; It works for me&#8230;.. but it shouldn&#8217;t.</p>
<p>When in my IPv6 environment I perform a test ping to, say, Google, it seems to work great:</p>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">ping6 ipv6.google.com</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">PING ipv6.google.com(2a00:1450:8006::6a) 56 data bytes</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">64 bytes from 2a00:1450:8006::6a: icmp_seq=1 ttl=55 time=49.3 ms</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">64 bytes from 2a00:1450:8006::6a: icmp_seq=2 ttl=55 time=44.6 ms</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">.</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">.</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">.</span></div>
<p>Which is lovely. But I then ask myself how the ping6 command actually gets to know that name ipv6.google.com lives at IPv6 global address 2a00:1450:8006::6a. How is the domain name being resolved? And I find that I actually don&#8217;t know. I&#8217;m perfectly familiar with IPv4 DNS. So what&#8217;s going on here?</p>
<h2>I&#8217;m cheating</h2>
<p>I discover, upon investigation, that in fact I&#8217;m &#8220;cheating&#8221;. By that I mean that my attempt to set up a &#8220;pure&#8221; IPv6 environment (albeit in parallel with IPv4) that does not rely upon or touch IPv4 in any way has not been achieved &#8211; It turns out that my DNS is currently entirely dependent upon the existing IPv4 infrastructure! And before going ahead and trying to rectify that, it&#8217;s actually rather educational to understand how it is actually working at all.</p>
<p><span id="more-243"></span>So I run tcpdump on the IPv6 interface and take a look at what&#8217;s going on when I kick off the <em>ping6</em>:</p>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">13:28:36.671682 IP (tos 0&#215;0, ttl 64, id 45341, offset 0, flags [DF], proto UDP (17), length 61)</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"> 11.11.11.11.48231 &gt; 212.XXX.XXX.XXX: [udp sum ok] 8831+ AAAA? ipv6.google.com. (33)</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">13:28:36.765503 IP (tos 0&#215;0, ttl 60, id 0, offset 0, flags [DF], proto UDP (17), length 250)</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"> 212.XXX.XXX.XXX &gt; 11.11.11.11.48231: 8831 q: AAAA? ipv6.google.com. 7/0/0 ipv6.google.com. [1h49m54s] CNAME[|domain]</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">13:28:36.767123 IP (tos 0&#215;0, ttl 64, id 45365, offset 0, flags [DF], proto UDP (17), length 118)</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"> 11.11.11.11.56346 &gt; 212.XXX.XXX.XXX: 37833+[|domain]</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">13:28:37.042646 IP (tos 0&#215;0, ttl 60, id 0, offset 0, flags [DF], proto UDP (17), length 178)</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"> 212.XXX.XXX.XXX &gt; 11.11.11.11.56346: 37833 NXDomain q:[|domain]</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">.</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">.</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">.</span></div>
<div>So what&#8217;s all that about then?</div>
<div>We appear to have a perfectly standard IPv4 exchange taking place, but with a few odd bits mixed in! Taking it a step at a time&#8230;..</div>
<ul>
<li>A DNS query (UDP &#8211; port 53 &#8211; IPv4 &#8211; standard stuff) goes out for <em>ipv6.google.com</em>. The odd looking bit is the DNS query type: &#8220;AAAA&#8221;. What&#8217;s that? That actually signifies that this is an IPv6 query. Special.</li>
<li>And sure enough we get a response from the IPv4 DNS. It does not decode it here, but in the CNAME response data is the full IPv6 address required.</li>
<li>In fact it returns, as DNS queries often do, more than one address. It returns a selection of 6 of them, of which one gets selected for use.</li>
<li>And we then get a rather odd repeating pattern of subsequent PTR resolution attempts, which is a bit confusing. We&#8217;ll ignore that bit for now.</li>
</ul>
<p>So: in fact our IPv6 DNS is running (with great success!) but&#8230;&#8230;&#8230;&#8230;. over an entirely IPv4 infrastructure.</p>
<p>It&#8217;s fabulous that it all works so easily and seamlessly. <img src='http://www.ipsidixit.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  However, for the purposes of my voyage in to IPv6, I&#8217;d actually rather not use the IPv4 side of things at all. What if IPv4 wasn&#8217;t available to me? So what to do?</p>
<h2>Pure IPv6 Name Resolution &#8211; IPv6 DNS</h2>
<p>So we want to shift the DNS function off IPv4 and to make use of the IPv6 infrastructure. Where to being? Well, since setting up all the IPv6 I had noticed some new bit &#8216;n bobs appearing in my logs, as you do with new things. And I&#8217;d mostly ignored them for now. Again, as you do. But this one was appearing rather regularly, and now seemed rather interesting&#8230;</p>
<pre style="padding-left: 30px;">Mar 30 09:45:30 xxxxx radvd[2351]: RDNSS address 2a01:e00::1 received on eth0 from fe80::207:cbff:fea5:XXX is not advertised by us</pre>
<p>What&#8217;s that all about? Looking at the elements:</p>
<p style="padding-left: 30px;">
<ul>
<li style="padding-left: 30px;"><em>eth0</em> is my external (Internet-facing) interface</li>
<li style="padding-left: 30px;">the <em>fe80:</em> address is the IPv6 <em>link</em> address of my adjacent router (i.e. the ISP&#8217;s IPv6 router)</li>
<li style="padding-left: 30px;"><em>2a01:e00::1</em> is a normalish looking IPv6 global address. And sometimes I see the same log with <em>2a01:e00::2</em> in it instead.</li>
<li style="padding-left: 30px;">The RDNSS rather gives it away! &#8220;DNS.&#8221; Is this to do with DNS perhaps&#8230;?</li>
<li style="padding-left: 30px;">&#8220;&#8230;is not advertised by us&#8221; &#8211; What&#8217;s that all about?</li>
</ul>
<p>&nbsp;</p>
<p>Grabbing the incoming packet that seems to generate these logs I see more when fully decoded. The packet concerned is an expected <em>Router Advertisement</em> (RA) but it has some options on it:</p>
<p style="padding-left: 30px;">
<ul>
<li style="padding-left: 30px;">Prefix Information: this we expect. It tells me the 64-bit prefix that is &#8220;mine&#8221; to use for global IPv6 addresses.</li>
<li style="padding-left: 30px;">Recursive DNS Server: woah! That acronymises as RDNSS. And it hands me two &#8220;Recursive DNS Servers&#8221;: <em>2a01:e00::1</em> and <em>::2</em>. So that&#8217;s where they come from.</li>
<li style="padding-left: 30px;">MTU: an MTU of 1480 is specified in there too. I see that in fact my interface MTU is 1500. Should I worry? perhaps yes. But I&#8217;ll leave that for now and come back to it.</li>
<li style="padding-left: 30px;">Source link-layer address: we can ignore that. <img src='http://www.ipsidixit.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
<p>&nbsp;</p>
<h2>Manual test of IPv6 DNS</h2>
<p>Before jumping in to new software subsystems, let&#8217;s try a manual test and see what happens. Just as one can use nslookup on the command line to check name resolution for IPv4, so one can use it for IPv6 too. Specify the name to be resolved and the server to us (or else we will default as per /etc/resolv.conf) and see what happens, checking with tcpdump:</p>
<pre style="padding-left: 30px;"><span style="font-family: 'Courier New';"> </span><span style="font-size: medium;">nslookup ipv6.google.com 2a01:e00::1</span></pre>
<p>And I see the following packet sequence result:</p>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">10:23:43.522926 IP6 (hlim 64, next-header UDP (17) payload length: 41) 2a01:XXX:8b25:7ea0:240:63ff:fef5:f93c.52838 &gt; dns2.proxad.net.domain: [udp sum ok] 9362+ A? ipv6.google.com. (33)</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"><br />
</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">10:23:43.577684 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::207:cbff:fea5:XXX &gt; ff02::1:fff5:XXX: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has 2a01:XXX:8b25:7ea0:240:63ff:fef5:f93c</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"> source link-address option (1), length 8 (1): 00:07:cb:a5:1a:68</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"> 0&#215;0000:  0007 cba5 1a68</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"><br />
</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">10:23:43.577937 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) 2a01:XXX:8b25:7ea0:240:63ff:fef5:f93c &gt; fe80::207:cbff:fea5:XXX: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is 2a01:XXX:8b25:7ea0:240:63ff:fef5:f93c, Flags [router, solicited, override]</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"> destination link-address option (2), length 8 (1): 00:40:63:f5:f9:3c</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"> 0&#215;0000:  0040 63f5 f93c</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';"><br />
</span></div>
<div style="padding-left: 30px;"><span style="font-family: 'Courier New';">10:23:43.578294 IP6 (hlim 60, next-header UDP (17) payload length: 112) dns2.proxad.net.domain &gt; 2a01:XXX:8b25:7ea0:240:63ff:fef5:f93c.52838: [udp sum ok] 9362 q: A? ipv6.google.com. 1/1/0 ipv6.google.com. [2h44m2s] CNAME ipv6.l.google.com. ns: l.google.com. [10m] SOA ns4.google.com. dns-admin.google.com. 1411041 900 900 1800 60 (104)</span></div>
<p>Key here are the first and fourth packets: DNS request out, and DNS response back. All in IPv6. No IPv4 there at all. That&#8217;s good. We can see our IPv6 DNS server and, in principle, they work.</p>
<h2>A secret &#8211; ndisc6</h2>
<p>Time to let you in on a little secret to make life much easier&#8230; While tcpdumps and so on are instructive up to a point, and force one to think a little about what is being seen, they are also pretty tedious. A lot of what we need to achieve here can be done using much more accessible tools! Do yourself a big favour and install the ndisc6 package on your linux system. The <a id="p49f" title="creator's web page" href="http://www.remlab.net/ndisc6/"><span style="color: #000000;">creator&#8217;s web page</span></a> gives you a little more information, but just as an example, look at this command + output:</p>
<div><span style="font-size: medium;"><strong>rdisc6  eth0</strong></span></div>
<div><span style="font-family: 'Courier New';">Soliciting ff02::2 (ff02::2) on eth0&#8230;</span></div>
<div><span style="font-family: 'Courier New';">Hop limit                 :           64 (      0&#215;40)</span></div>
<div><span style="font-family: 'Courier New';">Stateful address conf.    :           No</span></div>
<div><span style="font-family: 'Courier New';">Stateful other conf.      :           No</span></div>
<div><span style="font-family: 'Courier New';">Router preference         :       medium</span></div>
<div><span style="font-family: 'Courier New';">Router lifetime           :         1800 (0&#215;00000708) seconds</span></div>
<div><span style="font-family: 'Courier New';">Reachable time            :  unspecified (0&#215;00000000)</span></div>
<div><span style="font-family: 'Courier New';">Retransmit time           :  unspecified (0&#215;00000000)</span></div>
<div><span style="font-family: 'Courier New';"> Source link-layer address: 00:40:63:F5:F9:3C</span></div>
<div><span style="font-family: 'Courier New';"> from fe80::240:63ff:fef5:f93c</span></div>
<div><span style="font-family: 'Courier New';">Hop limit                 :           64 (      0&#215;40)</span></div>
<div><span style="font-family: 'Courier New';">Stateful address conf.    :           No</span></div>
<div><span style="font-family: 'Courier New';">Stateful other conf.      :           No</span></div>
<div><span style="font-family: 'Courier New';">Router preference         :       medium</span></div>
<div><span style="font-family: 'Courier New';">Router lifetime           :         1800 (0&#215;00000708) seconds</span></div>
<div><span style="font-family: 'Courier New';">Reachable time            :  unspecified (0&#215;00000000)</span></div>
<div><span style="font-family: 'Courier New';">Retransmit time           :  unspecified (0&#215;00000000)</span></div>
<div><span style="font-family: 'Courier New';"> Prefix                   : 2a01:XXX:8b25:7ea0::/64</span></div>
<div><span style="font-family: 'Courier New';"> Valid time              :        86400 (0&#215;00015180) seconds</span></div>
<div><span style="font-family: 'Courier New';"> Pref. time              :        86400 (0&#215;00015180) seconds</span></div>
<div><span style="font-family: 'Courier New';"> Recursive DNS server     : 2a01:e00::2</span></div>
<div><span style="font-family: 'Courier New';"> Recursive DNS server     : 2a01:e00::1</span></div>
<div><span style="font-family: 'Courier New';"> DNS servers lifetime    :          600 (0&#215;00000258) seconds</span></div>
<div><span style="font-family: 'Courier New';"> MTU                      :         1480 bytes (valid)</span></div>
<div><span style="font-family: 'Courier New';"> Source link-layer address: 00:07:CB:A5:1A:68</span></div>
<div><span style="font-family: 'Courier New';"> from fe80::207:cbff:fea5:1a68</span></div>
<p>Wow. Look at all that! Useful.</p>
<p>Now to move on to integrating this into the system so all IPv6 names get resolved this was.</p>
<h2>rdnssd &#8211; Recursive DNS Server daemon</h2>
<p>I think I should start out with a warning here: this next step is the entirely logical and sensible thing to do. But in fact read through to the end: it&#8217;s not going to work &#8211; the Linux IPv6 userspace tools are simply not quite here they should be yet&#8230; But it&#8217;s instructive to look at this, if only for the learning it provides.</p>
<p>Let&#8217;s set up the required sub-system to handle IPv6 DNS requests from this system and the users who will later traverse it. The first step is simply to install the required package:</p>
<p style="padding-left: 30px;"><span style="font-family: 'Courier New';">apt-get install rdnssd</span></p>
<p>This package may have other dependencies, which should get automatically fulfilled, e.g. <em>resolvconf</em>)</p>
<div>Just what is rdnssd? The best summary of it I can see is the first paragraph of the associated <em>man</em> page:</div>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'Courier New';">rdnssd is a daemon program providing client-side support for DNS configuration using the Recursive</span></div>
<div><span style="font-family: 'Courier New';">DNS Server (RDNSS) option, as described in RFC 5006. Its purpose is to supply IPv6 DNS resolvers</span></div>
<div><span style="font-family: 'Courier New';">through stateless autoconfiguration, carried by Router Advertisements.</span></div>
<div><span style="font-family: 'Courier New';"><br />
</span></div>
</blockquote>
<p>That pretty much sums it up. It&#8217;s just what we need here!</p>
<div>The second paragraph is also quite illuminating:</div>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'Courier New';">rdnssd parses RDNSS options and keeps track of resolvers to write nameservers entries to a</span></div>
<div><span style="font-family: 'Courier New';">resolv.conf(5) configuration file. By default, it writes its own separate file, and may call an</span></div>
<div><span style="font-family: 'Courier New';">external hook to merge it with the main /etc/resolv.conf. This is aimed at easing coexistence with</span></div>
<div><span style="font-family: 'Courier New';">concurrent daemons, especially IPv4 ones, updating /etc/resolv.conf too.</span></div>
</blockquote>
<p>So, we&#8217;ve installed it. What&#8217;s it doing? Straight after installing the package a ps -ef shows me that the process is running. I rerun my ping6 and nslookup (without specifying th IPv6 DNS this time) and tcpdump shows me no change: the DNS is still taking place over IPv4.</p>
<p>As mentioned at the start of thus sub-section, we have a problem here. A big, fat problem. We want this daemon to pick up our DNS server from the RA and use them. Which is fine. But check out the last para of the rdnssd man page:</p>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'Courier New';">When rdnssd uses a raw socket instead of the netlink kernel interface, it does not validate received</span></div>
<div><span style="font-family: 'Courier New';">Neighbor Discovery traffic in any way. For example, it will always consider Router Advertisement</span></div>
<div><span style="font-family: 'Courier New';">packets, whereas it should not if the host is configured as a router. When the netlink interface is</span></div>
<div><span style="font-family: 'Courier New';">used, such validation is done by the kernel.</span></div>
</blockquote>
<p>What that boils down to is that if we&#8217;re running as a <em>router</em> (and we are, since in <em>/etc/sysctl.conf</em> we have <em>net.ipv6.conf.all.forwarding=1</em>) the kernel will simply not pass the RA up to user-space at all. So rdnssd never gets the chance to see it, and thus never acts upon it. Which is a bummer.</p>
<p>Just to experiment, you can dynamically drop down to <em>/proc/sys/net/ipv6/conf/all/forwarding</em> and set it to &#8217;0&#8242;. (radvd will bitch and moan, but ignore that.) Force a RA refresh if required, using rdisc eth0, and you will see rdnssd do its stuff and change the <em>/etc/resolv.conf</em> to point at the IPv6 servers. But we can&#8217;t leave it that way, alas. We&#8217;ve hit a bit of a blocker here &#8211; picking up the IPv6 DNS servers automatically from the ISP seems to not be achievable at the moment using rdnssd &#8211; the kernel&#8217;s policies for what is allowed and when prevent it.</p>
<h2>So what do we do?</h2>
<p>We now understand what we&#8217;re trying to do. We also understand how it should be doable. But currently there&#8217;s a blocker. What to do?</p>
<p>As always in such matters, there&#8217;s an easy, pragmatic way forward and a tricky, hacky way forward! The sensible path to take is very simple indeed. We know the IPv6 addresses of our DNS servers (and if we forget we can just do a rdisc eth0 to find them out again) The obvious thing to do it to statically configure them in to the existing <em>/etc/resolv.conf</em> and then, when we later use IPv6 from a device on the internal network, configure them there too.</p>
<p>That&#8217;s what I would recommend. That&#8217;s what you should do. You can specify a mixture of IPv6 and IPv4 name-server in the <em>/etc/resolv.conf file</em>. If you specify the IPv6 servers first, then all DNS on the system will (if available) use the IPv6 name servers. I suppose this does slightly violate still our desire to keep IPv4 and IPv6 separate (since IPv4 name resolution will now also use IPv6) but since it tilts the bias in favour if IPv6, with a seamless fallback to IPv4, I think I can live with that.</p>
<h2>OK &#8211; but what about more wacky solutions?</h2>
<div><strong><em>[Remember, stop here unless you're wanting to have some fun</em></strong><em><strong> and</strong></em><strong><em> you are comfortable with building your own software.]</em></strong></div>
<p>One approach that would give us a partial solution would be to admit we were wrong originally, and instead of using radvd to propagate simple prefix information into our internal networks we should instead use a fully-fledged IPv6 DHCP server that can propagate addressing and DNS information. This would solve the problem of devices inside the network needing to have the IPv6 DNSs statically configured on them. However even this would not solve the root issue here: our inability to automatically pick up the IPv6 DNS information from received RAs when we&#8217;re configured to operate as a router.</p>
<p>The problem there is not, directly, rdnssd itself. The problem is the kernel. An architectural decision has been taken to stop the kernel sending RA DNS data up to userspace if the system is functioning as a router. Good or bad decision? Bad in my view. I can understand why it is sensible default behaviour, yes. But I do not understand why it&#8217;s been made unchangeable. But that&#8217;s how it is, for now anyway.</p>
<p>The solution I&#8217;m going to go for is to actually bypass the policing mechanism itself. The kernel only manages to stop the DNS being sent to userspace when userspace uses the Netlink mechanism to talk down. So why not just bypass that and get the raw data we want? This should bre easy enough to do, as rdnssd itself used to work this way, before the kernel started using Netlink to talk to userspace. So we might be able to build rdnssd to behave as it used to and get the data, right?</p>
<h3>Hack and build rdnssd</h3>
<p>The existing rndssd code makes provision for kernels <em>with </em> the netlink capability which causes us problems and for older kernels <em>without</em> that capability. So all the code we need is already in place. All we really need to do is change the default behaviour of <em>rdnssd</em> to the old way and we&#8217;ll be all set. One could of course do this properly and completely using command line options. Here&#8217;s what you might do in terms of changes to the <em>rdnssd</em> code-base:</p>
<h3>Edit rdnssd.c</h3>
<p>In <em>usage()</em>, ad a line such as:</p>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'Courier New';">&#8221;  -n  &#8211;no-netlink  use old method to pick up kernel notificationsn&#8221;</span></div>
</blockquote>
<p>In <em>main() </em>drop in appropriate parameter parsing:</p>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'Courier New';">static const struct option opts[] =</span></div>
<div><span style="font-family: 'Courier New';"> {</span></div>
<div><span style="font-family: 'Courier New';"> { &#8220;foreground&#8221;,         no_argument,            NULL, &#8216;f&#8217; },</span></div>
<div><span style="font-family: 'Courier New';"> { &#8220;no-netlink&#8221;,         no_argument,            NULL, &#8216;n&#8217;},</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
</blockquote>
<p>and an appropriate global:</p>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'courier new';">bool nonetlink = false;</span></div>
</blockquote>
<p>and then in the main parsing switch add:</p>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'Courier New';">case &#8216;n&#8217;:</span></div>
<div><span style="font-family: 'Courier New';"> nonetlink = true;</span></div>
<div><span style="font-family: 'Courier New';"> break;</span></div>
</blockquote>
<p>Then finally up in worker() we act upon it.</p>
<p>Before we had:</p>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'Courier New';">static int worker (int pipe, const char *resolvpath, const char *username)</span></div>
<div><span style="font-family: 'Courier New';">{</span></div>
<div><span style="font-family: 'Courier New';"> sigset_t emptyset;</span></div>
<div><span style="font-family: 'Courier New';"> int rval = 0, sock = -1;</span></div>
<div><span style="font-family: 'Courier New';"> const rdnss_src_t *src;</span></div>
<div><span style="font-family: 'Courier New';">#ifdef __linux__</span></div>
<div><span style="font-family: 'Courier New';"> src = &amp;rdnss_netlink;</span></div>
<div><span style="font-family: 'Courier New';"> sock = src-&gt;setup ();</span></div>
<div><span style="font-family: 'Courier New';">#endif</span></div>
<div><span style="font-family: 'Courier New';"> if (sock == -1)</span></div>
<div><span style="font-family: 'Courier New';"> {</span></div>
<div><span style="font-family: 'Courier New';"> src = &amp;rdnss_icmp;</span></div>
<div><span style="font-family: 'Courier New';"> sock = src-&gt;setup ();</span></div>
<div><span style="font-family: 'Courier New';"> }</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
</blockquote>
<p>Change it to something like:</p>
<blockquote style="border: none; margin: 0 0 0 40px;">
<div><span style="font-family: 'Courier New';">static int worker (int pipe, const char *resolvpath, const char *username)</span></div>
<div><span style="font-family: 'Courier New';">{</span></div>
<div><span style="font-family: 'Courier New';"> sigset_t emptyset;</span></div>
<div><span style="font-family: 'Courier New';"> int rval = 0, sock = -1;</span></div>
<div><span style="font-family: 'Courier New';"> const rdnss_src_t *src;</span></div>
<div><span style="font-family: 'Courier New';">#ifdef __linux__</span></div>
<div><span style="font-family: 'Courier New';"> if (!nonetlink) {</span></div>
<div><span style="font-family: 'Courier New';"> src = &amp;rdnss_netlink;</span></div>
<div><span style="font-family: 'Courier New';"> sock = src-&gt;setup ();</span></div>
<div><span style="font-family: 'Courier New';"> }</span></div>
<div><span style="font-family: 'Courier New';">#endif</span></div>
<div><span style="font-family: 'Courier New';"> if (sock == -1)</span></div>
<div><span style="font-family: 'Courier New';"> {</span></div>
<div><span style="font-family: 'Courier New';"> src = &amp;rdnss_icmp;</span></div>
<div><span style="font-family: 'Courier New';"> sock = src-&gt;setup ();</span></div>
<div><span style="font-family: 'Courier New';"> }</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
<div><span style="font-family: 'Courier New';">.</span></div>
</blockquote>
<p>and we&#8217;re good. Build, install and use as before, but using the new cli parameter &#8220;-n&#8221; as required to force the old behaviour.</p>
<p><a title="rdnssd.c - proof of concept" href="http://www.ipsidixit.net/wp-content/2010/04/rdnssd.c" target="_blank">Attached is a version of rdnssd.c </a>based off version 0.9.9 for reference.</p>
<p>For finishing touches, set up an rdnssd hook-file which puts the IPv6 nameservers first in /etc/resolv.conf, and then have the original IPv4 servers appended after them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ipsidixit.net/2010/04/02/243/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

