Month: August 2011

  • IPv6 Part 9: Configuring A Domain For IPv6 With BIND

    Welcome to part nine of my multipart series on IPv6. In this post I’ll cover how to configure the ISC BIND daemon to serve an authoritative DNS domain over IPv6. The host is running FreeBSD 8.2, but this should apply equally well to any system running the ISC named daemon.

    Just having connectivity over IPv6 isn’t enough; you also have to tell the rest of the world that it can reach you over IPv6. In this post I’ll cover the basics of configuring your domain for IPv6, on the assumption that your name servers and your web servers have IPv6 connectivity. If your name servers do not, Hurricane Electric will host your DNS on IPv6 enabled systems for free.

    The first step is actually administrative in nature. You need to figure out if you can get your IPv6 addresses into the whois record for your domain at your registrar. In my case my registrar did not have support for adding IPv6 glue records in their admin interface, but they were happy to do it manually through a support ticket. They also said they were in the process of adding IPv6 support to their admin interface, so I hopefully I won’t have to bother the support department next time I need to update a record with them. Here’s an example of my whois record:

    $ whois mmacleod.ca
    Domain name: mmacleod.ca
    Domain status: registered
    Creation date: 2009/04/06
    Expiry date: 2012/04/06
    Updated date: 2011/06/17
    
    Registrar:
    Name: DomainsAtCost Corp.
    Number: 45
    
    Name servers:
    ns1.nullpointer.ca 199.48.133.238 2607:fc50:1000:8b00::2
    ns2.nullpointer.ca 208.86.255.157 2001:0470:001d:0619::2

    As you can see, I have glue records for both IPv4 and IPv6 for my name servers. With that out the way, it’s time to make sure that those nameservers actually serve the zones properly.

    I’m using FreeBSD, but this should apply equally well to any system running BIND, just change the paths to the various configuration files to suit your environment. First, we need to edit /etc/namedb/named.conf:

    $ cat named.conf
    options {
    directory "/etc/namedb/working";
    pid-file "/var/run/named/pid";
    dump-file "/var/dump/named_dump.db";
    statistics-file "/var/stats/named.stats";
    
    recursion no;
    allow-query { any; };
    version "0";
    
    listen-on { 203.0.113.238; };
    listen-on-v6 { 2001:0DB8:1000:8b00::2; };
    };
    
    include "/etc/namedb/dnsadmin.key";
    
    controls {
    inet 127.0.0.1 allow { 127.0.0.1; } keys { "dnsadmin";};
    inet ::1 allow { ::1; } keys { "dnsadmin"; };
    
    };
    
    zone "example.com" {
    type master;
    file "../master/example.com";
    };

    This is a very basic named.conf to highlight the few options necessary to get BIND to listen to requests over IPv6 (which is really just the listen-on-v6 option). You are encouraged to read up on BIND administration, as BIND has been associated with a number of attacks over the years, and proper administration of it is very important.

    Next is the configuration of the zone itself. Our example domain will use Google for Domains for email, and host a few of services. Open up /etc/namedb/master/example.com:

    $ cat example.com
    $TTL 1200
    example.com. IN SOA ns1.example.com. [email protected]. (
    2011062702 ; Serial
    1200 ; Refresh
    1200 ; Retry
    2419200 ; Expire
    3600 ) ; Negative Cache TTL
    ;
    
    IN AAAA 2001:0DB8:1000:8b00:0000:0000:0000:0002
    IN A 203.0.113.238
    IN NS ns1.example.com.
    IN NS ns2.example.com.
    IN MX 10 ASPMX.L.GOOGLE.COM.
    IN MX 20 ALT1.ASPMX.L.GOOGLE.COM.
    IN MX 20 ALT2.ASPMX.L.GOOGLE.COM.
    IN MX 30 ASPMX2.GOOGLEMAIL.COM.
    IN MX 30 ASPMX3.GOOGLEMAIL.COM.
    IN MX 30 ASPMX4.GOOGLEMAIL.COM.
    IN MX 30 ASPMX5.GOOGLEMAIL.COM.
    
    $ORIGIN example.com.
    ; A Records
    ns1 IN A 203.0.113.238
    ns2 IN A 203.0.113.157
    www IN A 203.0.113.238
    appsrv-02 IN A 203.0.113.157
    appsrv-03 IN A 203.0.113.158
    
    ; AAAA Records
    ns1 IN AAAA 2001:0DB8:1000:8b00:0000:0000:0000:0002
    ns2 IN AAAA 2001:0DB8:001d:0619:0000:0000:0000:0002
    www IN AAAA 2001:0DB8:1000:8b00:0000:0000:0000:0002
    appsrv-02 IN AAAA 2001:0DB8:001d:0619:0000:0000:0000:0002
    appsrv-03 IN AAAA 2001:0DB8:001d:0619:0000:0000:0000:0003
    
    ; SRV Records
    _sip._tcp IN SRV 1 0 5060 appsrv-03
    _sip._udp IN SRV 1 0 5060 appsrv-03
    
    ; CNAME Records
    sip IN CNAME appsrv-03.example.com.
    mail IN CNAME ghs.google.com.
    calendar IN CNAME ghs.google.com.
    docs IN CNAME ghs.google.com.
    sites IN CNAME ghs.google.com.

    As you can see, the only real difference between this and an IPv4-only domain is the addition of some AAAA records. It’s worth noting that the SRV and CNAME records are IPv4/IPv6 agnostic, since they just point to another hostname. It’s then up to your operating system whether it wants to find an A or AAAA record for that hostname.

    That’s all there really is to configuring an authoritative domain for IPv6.

  • IPv6 Part 8: Configuring DNS And DHCPv6 On An IPv6 Network

    Welcome to part eight of my multipart series on IPv6. In this post I’ll cover how to configure the ISC BIND and DHCP daemons to support dynamic DNS updates from DHCP in DNS on your LAN. The router is running FreeBSD 8.2, but this should apply equally well to any system running the ISC named and dhcpd daemons.

    For all the talk about DNS being the foundation of the Internet, most geeks and system administrators probably know the IP addresses of all the important hosts and services on their network. If you have setup your network for IPv6 and you don’t happen to be an android, then you’ve likely come to the conclusion that navigating to your hosts by IPv6 address is a sucker’s game. It’s time to look at configuring your DHCPv6 and DNS, and making sure they’re talking to each other. For this post I’m going to use the ISC BIND and DHCP daemons; I set them up on FreeBSD, but the choice of OS really shouldn’t matter.

    This post will assume we’re using a single domain for both our IPv4 and our IPv6 addresses. This can be a little tricky, as we will have two DHCP daemons trying to update the DNS configuration and they don’t really like to do that by default. It’s also quite reasonable to setup your main domain as a regular domain, and use two subdomains, one for IPv4 and one for IPv6. If you decide to go that route, you’ll need to configure your two subdomains in BIND, and configure the two instances of dhcpd to use the different domains. Everything else is largely the same though.

    First, configure the BIND daemon. On FreeBSD edit /etc/namedb/named.conf:

    $ cat /etc/namedb/named.conf
    options {
    directory "/etc/namedb/working";
    pid-file "/var/run/named/pid";
    dump-file "/var/dump/named_dump.db";
    statistics-file "/var/stats/named.stats";
    
    listen-on { 127.0.0.1; 192.168.1.1; };
    listen-on-v6 { ::1; 2001:0DB8:f00e:eb00::1; };
    
    forwarders {
    2001:470:20::2;
    };
    };
    
    include "/etc/namedb/rndc.key";
    
    controls {
    inet 127.0.0.1 allow { 127.0.0.1; } keys { "rndc-key";};
    inet 192.168.1.1 allow { 192.168.1.1; } keys { "rndc-key";};
    inet ::1 allow { ::1; } keys { "rndc-key"; };
    inet 2001:0DB8:f00e:eb00::1 allow { 2001:0DB8:f00e:eb00::1; } keys { "rndc-key"; };
    };
    
    zone "." { type hint; file "/etc/namedb/named.root"; };
    
    zone "example.com" {
    type master;
    file "../dynamic/example.com";
    allow-update { key rndc-key; };
    };
    
    zone "1.168.192.in-addr.arpa" {
    type master;
    file "../dynamic/1.168.192.in-addr.arpa";
    allow-update { key rndc-key; };
    };
    
    zone "0.0.b.e.e.0.0.f.8.B.D.0.1.0.0.2.ip6.arpa" {
    type master;
    file "../dynamic/2001:0DB8:f00e:eb00::64.ip6.arpa";
    allow-update { key rndc-key; };
    };

    The above is an edited example. By default the FreeBSD named.conf file also includes a number of intentionally empty and zeroed out zones, such as for reserved address space, example.com, and so forth. I would recommend keeping those, and in general reading up on BIND configuration. BIND has been associated with a number of vulnerabilities and attacks in the past, and proper configuration of BIND can be important for mitigating these risks.

    The important entries in the above configuration include listen-on-v6, which defines which IPv6 addresses your BIND configuration should listen on. You may which to include the link-local addresses associated with your LAN interface. In the control section there are four entries, which are both loopback and the LAN interface in both IPv4 and IPv6. It’s possible to use only the loopback interfaces, though this requires a change to your DHCP configuration.

    I use a forwarder in my configuration. Typically the use of forwarders should be avoided, but in this case the forwarder in question is the Hurricane Electric public DNS server. Hurricane Electric is on Google’s IPv6 whitelist, which means that all of their services will resolve to IPv6 address (AAAA records, specifically). Basically it just means you’ll be able to use Google and YouTube over IPv6.

    Also, there is the rndc key file, which is generated thusly:

    $ rndc-confgen -a -c /etc/namedb/rndc.key
    $ cat /etc/namedb/rndc.key
    key "rndc-key" {
    algorithm hmac-md5;
    secret "";
    };

    That will generate a basic key file, which is included in the named.conf as well as the rndc.conf files. We’ll also use a slightly edited version of it with our DHCP configuration (for some bizarre reason despite both coming from the ISC, the syntax for the two files is just slightly different for each daemon).

    Next up is the example.com forward zone configuration. Because it’s a dynamic zone BIND will handle updating the zone, but it’s up to you to supply the initial zone information. If you need to add entries manually, you can use the nsupdate command. Here’s an example:

    $ cat /etc/namedb/master/example.com
    $TTL 1200 ; 20 minutes
    example.com. IN SOA ns1.example.com. admin.example.com. (
    2011071301 ; serial
    1200 ; refresh (20 minutes)
    1200 ; retry (20 minutes)
    2419200 ; expire (4 weeks)
    3600 ; minimum (1 hour)
    )
    NS ns1.example.com.
    A 192.168.1.1
    AAAA 2001:0DB8:f00e:eb00::1
    
    $ORIGIN example.com.
    ;;;;;;;;;;;;;;;;;;
    ;; IPv4 Records ;;
    ;;;;;;;;;;;;;;;;;;
    ; A Records
    ns1 IN A 192.168.1.1
    gateway IN A 192.168.1.1
    
    ;;;;;;;;;;;;;;;;;;
    ;; IPv6 Records ;;
    ;;;;;;;;;;;;;;;;;;
    ; AAAA Records
    ns1 IN AAAA 2001:0DB8:f00e:eb00::1
    gateway IN AAAA 2001:0DB8:f00e:eb00::1

    This example should get you started. There’s almost no hosts defined, because we want them to all be entered via updates from DHCP. Here are the reverse zones as well:

    $ cat /etc/namedb/dynamic/1.168.192.in-addr.arpa
    $ORIGIN .
    $TTL 1200 ; 20 minutes
    1.168.192.in-addr.arpa IN SOA ns1.example.com. admin.example.com. (
    2011062928 ; serial
    1200 ; refresh (20 minutes)
    1200 ; retry (20 minutes)
    2419200 ; expire (4 weeks)
    3600 ; minimum (1 hour)
    )
    NS ns1.example.com.
    1 PTR gateway.example.com.
    
    $ cat /etc/namedb/dynamic/2001\:0DB8\:f00e\:eb00\:\:64.ip6.arpa
    $ORIGIN .
    $TTL 1200 ; 20 minutes
    0.0.b.e.e.0.0.f.8.B.D.0.1.0.0.2.ip6.arpa IN SOA ns1.example.com. admin.example.com. (
    2011062902 ; serial
    1200 ; refresh (20 minutes)
    1200 ; retry (20 minutes)
    2419200 ; expire (4 weeks)
    3600 ; minimum (1 hour)
    )
    NS ns1.example.com.
    1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 PTR gateway.example.com.

    Just like with the forward zone, they’re pretty basic since we expect BIND and DHCP to handle adding all the hosts. That should cover everything necessary to get BIND off the ground. I haven’t covered configuring rndc, but that’s simple and left as an exercise for the reader.

    Next up is configuring the DHCP daemon. At present, the ISC DHCP daemon can’t run in both IPv4 and IPv6 modes simultaneously. On recent versions of FreeBSD, the isc-dhcpd-server package installs two rc scripts, which are used to run the two instances of the daemon we’ll have to run.

    First up, configure the IPv4 instance of the DHCP server. On FreeBSD, this means editing /usr/local/etc/dhcpd.conf:

    $ cat /usr/local/etc/dhcpd.conf
    #
    # dhcpd.conf
    #
    
    include "/usr/local/etc/dhcpd/common.conf";
    include "/usr/local/etc/dhcpd/secret.key";
    
    option domain-name-servers 192.168.1.1;
    option ntp-servers 192.168.1.10;
    
    zone example.com. {
    key rndc-key;
    }
    
    zone 1.168.192.in-addr.arpa. {
    key rndc-key;
    }
    
    subnet 192.168.1.0 netmask 255.255.255.0 {
    authoritative;
    range 192.168.1.100 192.168.1.200;
    option routers 192.168.1.1;
    }

    The IPv4 and IPv6 instances will share a number of configuration options, which are kept in the /usr/local/etc/dhcpd/common.conf file. This isn’t necessary I just find it easier. Also, if you’ve elected to only allow control connections over the loopback interface, you’ll need to add the option primary localhost; to any zone entry. By default dhcpd uses the SOA record from the zone file, which is the LAN interface address in the above zone files.

    To configure the IPv6 instance, edit /usr/local/etc/dhcpd6.conf:

    $ cat /usr/local/etc/dhcpd6.conf
    #
    # dhcpd.conf
    #
    
    include "/usr/local/etc/dhcpd/common.conf";
    include "/usr/local/etc/dhcpd/secret.key";
    
    option dhcp6.name-servers 2001:0DB8:f00e:eb00::1;
    
    zone example.com. {
    key rndc-key;
    }
    
    zone 0.0.b.e.e.0.0.f.8.B.D.0.1.0.0.2.ip6.arpa. {
    key rndc-key;
    }
    
    subnet6 2001:0DB8:f00e:eb00::/64 {
    range6 2001:0DB8:f00e:eb00::1000 2001:0DB8:f00e:eb00::2000;
    authoritative;
    }

    This file also references both common.conf and secret.key. The secret.key file is almost identical to the rndc.key file we used for BIND, but with some slight syntactical differences. Any by slight, I mean it doesn’t use quotes:

    $ cat /usr/local/etc/dhcpd/secret.key
    key rndc-key {
    algorithm hmac-md5;
    secret ;
    };
    
    $ cat /usr/local/etc/dhcpd/common.conf
    #
    # common.conf
    #
    
    default-lease-time 86400;
    max-lease-time 604800;
    ddns-update-style interim;
    ddns-ttl 1200;
    update-conflict-detection false;
    get-lease-hostnames true;
    use-host-decl-names on;
    option domain-name "example.com";
    option domain-search "example.com";
    update-static-leases on;

    The secret.key is used by dhcpd to authenticate with named to update the DNS zones as required. The common.conf contains the entire shared configuration between the IPv4 and IPv6 instances of the ISC DHCP daemon. Here’s a rundown on the two important entries:

    ddns-update-style interim: This is what tells dhcpd to actually update the DNS.
    update-conflict-detection false: This tells the two instances of dhcpd to be less strict about updating the zones, so that they don’t end up fighting with each other.

    The rest are all standard fare for a dhcpd configuration. That should be everything that is required to get your configuration off the ground. If you watch your syslog (wherever you have it sending dhcpd logging) you should see entries about adding forward and reverse mappings.

    I would recommend testing with Windows Vista or Windows 7 workstations, as they honestly have the best IPv6 network stack out of the box at this time. Mac OS X Lion might have decent DHCPv6 support – I haven’t had a chance to test it yet – but anything earlier won’t really. Linux is a bit of a mixed bag, depending on which distro and configuration you’re using. Hopefully this will be worked on in the near future, and we can come to expect all the main operating systems to be well behaved DHCPv6 clients.

  • IPv6 Part 7: Securing And Optimizing An IPv6 Home Network Using FreeBSD

    Welcome to part seven of my multipart series on IPv6. In this post I’ll cover how to use packet filter (pf) on BSD to run a small network. The router is running FreeBSD 8.2, but this should apply equally well to either OpenBSD or FreeBSD with pf.
    (more…)

  • IPv6 Part 6: Configuring An IPv6 Network Assigned Over PPPoE Using FreeBSD

    Welcome to part six of my multipart series on IPv6. In this post I’ll cover how to configure a dual-stacked PPPoE tunnel on FreeBSD using mpd. The host is a FreeBSD 8.2 box using mpd5 from ports.
    (more…)

  • IPv6 Part 5: Configuring An IPv6 Network Using Linux And A Tunnel Broker

    Welcome to part five of my multipart series on IPv6. In this post I’ll cover how to configure an IPv6 tunnel on (Ubuntu/Debian) linux. An IPv6 tunnel is necessary if you’re trying to get IPv6 support to a host or network that does not have native IPv6 connectivity.
    (more…)