Querying SRV records

July 15, 2009 - No comment

I seem to always forget how to query SRV records.. so here it goes :

# host -t SRV _ldap._tcp.example.com
_ldap._tcp.example.com has SRV record 0 100 389 ipaserver.example.com.

Howto : setting up dns2tcp

April 24, 2009 - 4 comments

The following article has been tested on Debian Etch (server) and Debian Lenny and Mac OS X (clients).

I’m not gonna explain what dns2tcp is, just how to get it running in less than 30 minutes.

You need :
- a public server, reachable from anywhere, its UDP/53 port must be available (no DNS service running) and reachable (not filtered)
- a domain name or subdomain dedicated for dns2tcp
- a client computer, your laptop usually
- a “restricted” network (captive portal, firewalled network, paying hotspot)

Considerations :
dns2tcp server public IP : 1.2.3.4
dns2tcp domain : example.org
dns2tcp resources : SSH on TCP/22 at 1.2.3.4 (same machine as dns2tcp), SSH on TCP/22 at 4.3.2.1

DNS :
Create a NS record for the domain example.org pointing to IP 1.2.3.4, obviously you just can’t replace your current NS on your current domain :-)
The NS you specify is NOT a DNS server, it’s the dns2tcp server IP address ! This means that you won’t be able to host a website or anything else at example.org.
As a result and only if your control panel allows it or if you have CLI access to your DNS, I recommend using a subdomain of example.org, for example : dns2tcp.example.org.
This way you don’t reserve a whole domain name for the only dns2tcp application.

Hint : everyDNS allows to create NS records for subdomains. Not all control panels do.

Server :
Install dns2tcp on the machine (apt-get install dns2tcp on Debian)
Edit the file /etc/dns2tcpd.conf like this :

listen = 0.0.0.0
port = 53
user = nobody
chroot = /some/directory/
domain = example.org
ressources = ssh-home:127.0.0.1:22 , ssh-work:4.3.2.1:22

Start dns2tcp server with /etc/init.d/dns2tcp start

Client :
Don’t forget the client must already be installed on your computer when you are on the restricted network :-)
Install it right now : apt-get install dns2tcp on Debian or build it through macports on Mac OS X.

Connect to the restricted network.

Run the command :
dns2tcpc -z example.org 4.2.2.4

If the system is working you should see :
Available connection(s) :
ssh-home
ssh-work

Run the full command now :
dns2tcpc -z example.org -l 8888 -r ssh-home 4.2.2.4

4.2.2.4 is the DNS that will relay the actual DNS requests.
If the network restricts the use of external DNS servers, check your /etc/resolv.conf to get the DNS servers on the local network.

Now dns2tcp will listen on port TCP/8888 and will give you access to the resource “ssh-home” through that port.

Now connect to your SSH server through dns2tcp on port TCP/8888 :
ssh user@localhost -p 8888 -D 1080

You should connect to your home server !

The -D 1080 option will create a SOCKS proxy on your local machine on port TCP/1080.

Now set up your browser or any other program (like Pidgin if you want to chat) to use the SOCKS proxy at address 127.0.0.1 and port 1080.
You can also set the systemwide parameter for SOCKS proxy from the preferences panel of your OS.

You should now be able to browse the internet.

You can store a config file on the client computer if you don’t want to type the command everytime.. this is the config corresponding to the command :

/home/USER/.dns2tcprc :

domain = example.org
ressource = ssh-home
local_port = 8888
server = 4.2.2.4

This way, you just need to run dns2tcpc without argument.
If you store the config file somewhere else, run dns2tcpc -f /where/the/config/resides/dns2tcp.conf

Please note :
Your traffic is encapsulated inside small DNS packets (some firewalls can drop unusually large DNS packets), is encrypted because of SSH, etc.
This adds overhead, which makes browsing the web a bit slow but still convenient.
I’ve been able to reach 25 KB/s down and 20 KB/s BUT I haven’t been able to transfer large files though, it was taking forever to attach a 3 MB pictures to a mail in Gmail (wifi + UDP + small packets is a terrible mix)
A good idea is to use mobile versions of websites, they load faster.
To give you an idea, it can take up to a minute to display maps on Google Maps.
Since you are going through the SOCKS proxy created by the SSH connection, your traffic is encrypted and wifi users can’t snoop on you.
Obviously you can define anything as a resource in dns2tcp, for example you can point to a public web proxy but your traffic wouldn’t be encrypted !
The owner of the restricted network may notice unusually high DNS traffic while you are surfing (especially if you’re the only person using the wifi network in the hotel).

DHCP and Dynamic DNS with BIND

July 3, 2008 - 16 comments

Tested under Debian Etch

This is the network configuration of our DHCP/DNS server

Hostname : router.static.example.org
WAN interface (eth0) : 192.168.99.254 mask 255.255.255.0
LAN interface (eth1) : 172.30.200.254 mask 255.255.0.0
Default gateway : 192.168.99.1

First, we need to tell the DHCP server to only run on eth1 :

/etc/default/dhcp3-server :

INTERFACES="eth1"

/etc/dhcp3/dhcpd.conf :

This is the DHCP server configuration.

When a computer requests network information from the DHCP server, the DHCP will update the DNS zones
- dyn.example.org : the zone that will map hostnames to IP address
- 201.30.172.in-addr.arpa : the zone in charge of reverse lookups

ddns-domainname is the domain name that the DHCP server will try to update in the zone. For example if my computer is named mycomputer, it will try to upload the dyn.example.org zone with mycomputer.dyn.example.org.

That option is absolutely needed if you have several domains in the “option domain-name” field (the “search” domains that will be in /etc/resolv.conf), or it could try to add the hostname mycomputer.static.example.org to the dyn.example.org zone.

If you only have one domain in the “option domain-name” field, you can go without ddns-domainname as it will upload the zone with the domain specified there.

ddns-update-style interim;
include "/etc/bind/rndc.key";

zone dyn.example.org. {
        primary 127.0.0.1;
        key "rndc-key";
}

ddns-domainname "dyn.example.org";
option domain-name "static.example.org dyn.example.org";
option domain-name-servers 172.30.200.254;
option routers 172.30.200.254;
option broadcast-address 172.30.255.255;
option ntp-servers 172.30.200.254;

default-lease-time 86400;
max-lease-time 86400;

authoritative;

log-facility local7;

subnet 172.30.0.0 netmask 255.255.0.0 {

        range 172.30.201.10 172.30.201.200;

        # DNS zones to update
        zone 201.30.172.in-addr.arpa. {
                primary 172.30.200.254;
                key "rndc-key";
        }

        zone dyn.example.org. {
                primary 172.30.200.254;
                key "rndc-key";
        }
}

/etc/bind9/named.conf :

Make sure the file contains the following :
include "/etc/bind/named.conf.local";

You should not change that file, as you will specify your options in two other files.

/etc/bind9/named.conf.options :

Your options.
The zone files will be stored under /var/cache/bind/
The queries for unauthoritative domains will be forwarded to 192.168.99.1. You can put the DNS provided by your ISP there (or put the DNS from opendns.com)

options {
        directory "/var/cache/bind";

        query-source address * port 53;

        forwarders {
                192.168.99.1;
        };

        recursion yes;

        version "REFUSED";

        allow-recursion {
                127.0.0.1;
                192.168.99.0/24;
                172.30.0.0/16;
        };

        allow-query {
                127.0.0.1;
                192.168.99.0/24;
                172.30.0.0/16;
        };

};

/etc/bind9/named.conf.local :

This will contain your zone declarations

### options #########

include "/etc/bind/rndc.key";
controls {
        inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
};

### "static" zones #########

zone "static.example.org" {
        type master;
        file "db.static.example.org";
};

zone "200.30.172.in-addr.arpa" {
        type master;
        notify no;
        file "db.172.30.200";
};

### dynamic zones (updated by DDNS) #########

zone "dyn.example.org" {
        type master;
        file "db.dyn.example.org";
        allow-update { key "rndc-key"; };
};

zone "201.30.172.in-addr.arpa" {
        type master;
        notify no;
        file "db.172.30.201";
        allow-update { key "rndc-key"; };
};

Now let’s focus on DNS zones.

In this example we have several zones :

- static.example.org : static zone (like servers with static IP’s)
- dyn.example.org : dynamic zone, updated by DHCP when a computer gets an IP from it
- 172.30.200 : static zone (servers, etc.), which is not updated by DDNS
- 172.30.201 : dynamic zone, will contain information about machines using DHCP

I advise to split the static zones from the dynamic zones, DDNS has a tendency to mess up the zone files, which make them barely readable and manageable.

/var/cache/bind/db.172.30.200 :

$ORIGIN .
$TTL 86400	; 1 day
200.30.172.in-addr.arpa	IN SOA	static.example.org. postmaster.example.org. (
				200806299  ; serial
				28800      ; refresh (8 hours)
				7200       ; retry (2 hours)
				2419200    ; expire (4 weeks)
				86400      ; minimum (1 day)
				)
			NS	ns.static.example.org.
$ORIGIN 200.30.172.in-addr.arpa.
253			IN PTR	server.static.example.org.
254			IN PTR	router.static.example.org.

/var/cache/bind/db.172.30.201 :

$ORIGIN .
$TTL 86400	; 1 day
201.30.172.in-addr.arpa	IN SOA	static.example.org. postmaster.example.org. (
				200806327  ; serial
				28800      ; refresh (8 hours)
				7200       ; retry (2 hours)
				2419200    ; expire (4 weeks)
				86400      ; minimum (1 day)
				)
			NS	ns.static.example.org.
$ORIGIN 201.30.172.in-addr.arpa.

/var/cache/bind/db.static.example.org :

$ORIGIN .
$TTL 86400	; 1 day
static.example.org	IN SOA	ns.static.example.org. postmaster.example.org. (
				200806327  ; serial
				28800      ; refresh (8 hours)
				7200       ; retry (2 hours)
				2419200    ; expire (4 weeks)
				86400      ; minimum (1 day)
				)
			NS	ns.static.example.org.
			A	172.30.200.254
$ORIGIN static.example.org.
server			A	172.30.200.253
router			A	172.30.200.254
ns			A	172.30.200.254

ntp			CNAME	router.static.example.org.
smtp			CNAME	router.static.example.org.

/var/cache/bind/db.dyn.example.org

$ORIGIN .
$TTL 86400	; 1 day
dyn.example.org		IN SOA	ns.static.example.org. admin.example.org. (
				200806341  ; serial
				28800      ; refresh (8 hours)
				7200       ; retry (2 hours)
				2419200    ; expire (4 weeks)
				86400      ; minimum (1 day)
				)
			NS	ns.dyn.example.org.
			A	172.30.200.254
$ORIGIN dyn.example.org.

Now, make sure the zones will be writable by the user “bind” and restart the services :

# chown bind. /var/cache/bind/*
# /etc/init.d/bind restart
# /etc/init.d/dhcp3-server restart

On a computer on the network :

As root :

Edit /etc/dhcp3/dhclient.conf and set :
send host-name "mycomputer";

Now request an IP :
# dhclient eth0

Let’s imagine the computer has received the IP 172.30.201.200

You should see on the server’s syslog that the DNS zones have been updated.

- mycomputer.dyn.example.org is now bound to 172.30.201.200
- 172.30.201.200 will return mycomputer.dyn.example.org

From your computer, you should be able to verify the zones have been updated properly :

$ nslookup mycomputer
Server:		172.30.200.254
Address:	172.30.200.254#53

Name:	mycomputer.dyn.example.org
Address: 172.30.201.200
$ nslookup 172.30.201.200
Server:		172.30.200.254
Address:	172.30.200.254#53

200.201.30.172.in-addr.arpa	name = mycomputer.dyn.example.org.

You don’t need to type the whole mycomputer.dyn.example.org thing since it will lookup for either :
- mycomputer.dyn.example.org
- mycomputer.static.example.org if the previous wasn’t found
- mycomputer if the previous two were not found

This actually means that if you lookup www.google.be, it would try to resolve www.google.be.dyn.example.org first, then www.google.be.static.example.org, and finally www.google.be

You can avoid those unnecessary lookups by adding a dot to the end of the hostname you are trying to resolve :

# nslookup www.google.be.

This is the purpose of the search domains in /etc/resolv.conf

Pay attention to the syntax in /etc/resolv.conf.
You should be able to specify up to 6 domains to look up automatically.
Each domains should be on one line, separated by spaces.
I made a mistake and had domains separated by commas.
It was working perfectly fine with up to 2 domains on the search line.
With 3 domains or more, the computer would just not try to resolve on the domains at all.

BIND : the $GENERATE Directive

January 10, 2008 - No comment

From : http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2566761

BIND Master File Extension: the $GENERATE Directive

Syntax: $GENERATE range lhs [ttl] [class] type rhs [ comment ]

$GENERATE is used to create a series of resource records that only differ from each other by an iterator. $GENERATE can be used to easily generate the sets of records required to support sub /24 reverse delegations described in RFC 2317: Classless IN-ADDR.ARPA delegation.

$ORIGIN 0.0.192.IN-ADDR.ARPA.
$GENERATE 1-2 0 NS SERVER$.EXAMPLE.
$GENERATE 1-127 $ CNAME $.0

is equivalent to

0.0.0.192.IN-ADDR.ARPA NS SERVER1.EXAMPLE.
0.0.0.192.IN-ADDR.ARPA. NS SERVER2.EXAMPLE.
1.0.0.192.IN-ADDR.ARPA. CNAME 1.0.0.0.192.IN-ADDR.ARPA.
2.0.0.192.IN-ADDR.ARPA. CNAME 2.0.0.0.192.IN-ADDR.ARPA.
...
127.0.0.192.IN-ADDR.ARPA. CNAME 127.0.0.0.192.IN-ADDR.ARPA.

More about the options on the site mentionned above

CentOS 5 : chroot DNS with bind

December 13, 2007 - 90 comments

Howto for CentOS 4 here : http://www.wains.be/index.php/2007/02/04/centos-chroot-dns-with-bind/

1. Install packages :

yum install bind bind-chroot bind-libs bind-utils caching-nameserver

2. Configure RNDC :

cd /var/named/chroot/etc
rndc-confgen > rndc.key
chown root:named rndc.key

Edit rndc.key so it looks like this :

key "rndckey" {
algorithm hmac-md5;
secret "SGsvd1dF+mv+yU4ywCCkkg==";
};

You DON’T NEED anything else in the file (you must remove some option lines !)

A symlink in /etc exists and points to the rndc.key file we’ve just created, named expects that file there in order to be able to authenticate against rndc.

3. Configure /var/named/chroot/etc/named.conf

// we include the rndckey (copy-paste from rndc.key created earlier)
key "rndckey" {
      algorithm hmac-md5;
      secret "SGsvd1dF+mv+yU4ywCCkkg==";
};

// we assume our server has the IP 192.168.254.207 serving the 192.168.254.0/24 subnet
controls {
        inet 127.0.0.1 allow { 127.0.0.1; } keys { "rndckey"; };
        inet 192.168.254.207 allow { 192.168.254.0/24; } keys { "rndckey"; };
};

options {
        directory "/var/named";
        pid-file "/var/run/named/named.pid";

        recursion yes;

        allow-recursion {
                127.0.0.1;
                192.168.254.0/24;
                };

        // these are the opendns servers (optional)
        forwarders {
                208.67.222.222;
                208.67.220.220;
        };

        listen-on {
                127.0.0.1;
                192.168.254.207;
                };

        /*
         * If there is a firewall between you and nameservers you want
         * to talk to, you might need to uncomment the query-source
         * directive below.  Previous versions of BIND always asked
         * questions using port 53, but BIND 8.1 uses an unprivileged
         * port by default.
         */
        query-source address * port 53;

        // so people can't try to guess what version you're running
        version "REFUSED";

        allow-query {
                127.0.0.1;
                192.168.254.0/24;
                };
        };

server 192.168.254.207 {
        keys { rndckey; };
        };

zone "." IN {
        type hint;
        file "named.ca";
        };

// forward zone
zone "test.be" IN {
        type master;
        file "data/test.be.zone";
        allow-update { none; };
        // we assume we have a slave dns server with the IP 192.168.254.101
        allow-transfer { 192.168.254.101; };
        };

// reverse zone
zone "250.168.192.in-addr.arpa" IN {
	type master;
	file "data/192.168.250.zone";
	allow-update { none; };
        allow-transfer { 192.168.254.101; };
	};

4. Our first zone

Let’s say I own the domain test.be

We create our first zone under /var/named/chroot/var/named/data/test.be.zone

Here’s an example :

$ttl 38400
test.be.       IN      SOA     ns.test.be. admin.test.be. (
                       2007020400   ; Serial
                       10800           ; Refresh after 3 hours
                       3600            ; Retry after 1 hour
                       604800          ; Expire after 1 week
                       86400 )         ; Minimum TTL of 1 day
test.be.       IN      NS      ns.test.be.

test.be.               IN      MX      1       mx.test.be.
test.be.               IN      MX      5       mx2.test.be.

www.test.be.           IN      A       192.168.100.5
ns.test.be.           IN      A       192.168.100.10
mx.test.be.          IN      A       192.168.100.20
mx2.test.be.         IN      A       192.168.100.21
mail.test.be.          IN      CNAME   mx.test.be.

Here’s the corresponding reverse zone under /var/named/chroot/var/named/data/192.168.100.zone :

$TTL 86400
100.168.192.in-addr.arpa.	IN	SOA	ns.test.be. admin.test.be. (
			2007032000
			10800
			900
			604800
			3600 )

100.168.192.in-addr.arpa.	IN	NS	ns.test.be.

20.100.168.192.in-addr.arpa. IN PTR mx.test.be.
5.100.168.192.in-addr.arpa. IN PTR www.test.be.

5. Start the service and make sure it’ll start at boot

service named start
chkconfig named on

Make sure it’s running :
# rndc status
number of zones: 1
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is OFF
recursive clients: 0/1000
tcp clients: 0/100
server is up and running

6. Query

# nslookup mx.test.be. 127.0.0.1
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   mx.test.be
Address: 192.168.100.20

# nslookup www.google.com. 127.0.0.1
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
www.google.com  canonical name = www.l.google.com.
Name:   www.l.google.com
Address: 216.239.59.99
Name:   www.l.google.com
Address: 216.239.59.103
Name:   www.l.google.com
Address: 216.239.59.104
Name:   www.l.google.com
Address: 216.239.59.147

7. /etc/resolv.conf

If the query made on the previous point is working, you can set up /etc/resolv.conf on the server.

It should look like this :
search test.be
nameserver 127.0.0.1

CentOS 4 : chroot DNS with BIND

February 4, 2007 - 22 comments

I won’t go into the details of what is DNS, or the difference between an A record and a CNAME record.. just a quick howto to set up a chrooted DNS server using Bind under CentOS in a mere 5 minutes..

Howto available for CentOS 5 : http://www.wains.be/index.php/2007/12/13/centos-5-chroot-dns-with-bind/

BIND : undefined symbol: dns_resolver_setudpsize

October 22, 2006 - 1 comment

If you get this error message under RHEL/CentOS when trying to start Named

“undefined symbol: dns_resolver_setudpsize”

“yum install bind-libs” should fix the problem