Saturday, August 25, 2012

Using views in bind 9

If you need a DNS server resolving different addresses for the same name depending on the IP address of the client that makes the request, then this article may be of your interest.

What you need is to configure views, which allow one single zone to have different information to be served.

This is very useful in the following cases:
  • A DNS server connected to two or more networks with different needs.
  • A DNS server connected to Internet and an Intranet, where the IP addresses are local and you might have more services for private use.
  • A DNS server connected to a single network but receiving requests from other networks for which you may need to resolve differently.
Let's see how views work. For my example, I'll assume you already read the article  Basic DNS configuration, for this is an evolution of the previous configuration.

The steps should be:
  1. Go to /etc/bind and backup the file named.conf.local (just in case, you never know):
    cp named.conf.local named.conf.local.20120825
  2. For every view you can decide which clients will match it with the directive match-clients, where you can specify the addresses directly or use an ACL, as in my example.
  3. The file named.conf.local could be similar to this one:
    //
    // Do any local configuration here
    //

    acl "company-net" { 192.168.56.0/24; 192.168.100.0/24; };

    view "private" {

        match-clients { "company-net"; };

        zone "yourcompany.com" {
            type master;
            file "/etc/bind/db.yourcompany.com-private";
        };

    };

    view "public" {

        match-clients { any; };

        zone "yourcompany.com" {
            type master;
            file "/etc/bind/db.yourcompany.com-public";
        };

    };

    // Consider adding the 1918 zones here, if they are not used in your
    // organization
    //include "/etc/bind/zones.rfc1918";
  4. In this case, request from clients on the networks 192.168.56.0/24 and 192.168.100.0/24 will get the information of the file db.yourcompany.com-private and the rest from the file db.yourcompany.com-public.
  5. Now copy the original file to db.yourcompany.com-private (just in case) and to db.yourcompany.com-public (this is the one we'll modify in a minute).
    sergio@zeus:/etc/bind$ sudo cp db.yourcompany.com db.yourcompany.com-private
    sergio@zeus:/etc/bind$ sudo cp db.yourcompany.com db.yourcompany.com-public
  6. We'll keep unmodified the private zone file and modify the public zone file to have less records and different IP addresses for the services. The result is:
    ; BIND direct file for yourcompany.com zone
    ;
    $TTL    86400
    @       IN    SOA    zeus.yourcompany.com. hostmaster.yourcompany.com. (
                      1        ; Serial
                  43200        ; Refresh (12h)
                   3600        ; Retry (1h)
                2419200        ; Expire (2 weeks)
                  86400 )      ; Negative Cache TTL
    ;
    @       IN    NS    zeus.yourcompany.com.
    zeus    IN    A     213.176.100.20
    atila   IN    A     213.176.100.21
    www     IN    CNAME atila
  7. Compare the two files to see the differences. Go to Basic DNS configuration to see the original.
  8. At this point, if you restart bind, you'll have trouble because ALL the zones MUST be in VIEWS.
  9. This means that all the includes in the file named.conf must lead to zones in views. Therefore, you should modify the file named.conf.default-zones accordingly to what has been explained (you could include all the default zones in a general view allowing the access to any client, for instance).
  10. Backup the file:
    sudo cp named.conf.default-zones named.conf.default-zones.20120825
  11. Modify it just adding the first 2 lines at the top and don't forget the closing }; at the bottom:
    view "general" {

    match-clients { any; };

    // prime the server with knowledge of the root servers
    zone "." {
        type hint;
        file "/etc/bind/db.root";
    };

    // be authoritative for the localhost forward and reverse zones, and for
    // broadcast zones as per RFC 1912

    zone "localhost" {
        type master;
        file "/etc/bind/db.local";
    };

    zone "127.in-addr.arpa" {
        type master;
        file "/etc/bind/db.127";
    };

    zone "0.in-addr.arpa" {
        type master;
        file "/etc/bind/db.0";
    };

    zone "255.in-addr.arpa" {
        type master;
        file "/etc/bind/db.255";
    };

    };
  12. Now restart the DNS server:
    sudo service bind9 restart
  13. And make some queries to check it. From the private network (using a client with IP address 192.168.56.2) we can resolve www and ramses, getting their address in this network:
    sergio@odin:~$ sudo ifconfig vboxnet0
    vboxnet0  Link encap:Ethernet  direcciónHW 0a:00:27:00:00:00 
              Direc. inet:192.168.56.2  Difus.:192.168.56.255  Másc:255.255.255.0
              Dirección inet6: fe80::800:27ff:fe00:0/64 Alcance:Enlace
              ACTIVO DIFUSIÓN FUNCIONANDO MULTICAST  MTU:1500  Métrica:1
              Paquetes RX:0 errores:0 perdidos:0 overruns:0 frame:0
              Paquetes TX:73 errores:0 perdidos:0 overruns:0 carrier:0
              colisiones:0 long.colaTX:1000
              Bytes RX:0 (0.0 B)  TX bytes:13181 (13.1 KB)
    sergio@odin:~$ nslookup
    > server zeus
    Default server: zeus
    Address: 192.168.56.101#53
    > www.yourcompany.com
    Server:        zeus
    Address:    192.168.56.101#53

    www.yourcompany.com    canonical name = atila.yourcompany.com.
    Name:    atila.yourcompany.com
    Address: 192.168.56.102
    > ramses.yourcompany.com
    Server:        zeus
    Address:    192.168.56.101#53

    Name:    ramses.yourcompany.com
    Address: 192.168.56.103
    > exit
  14. However, from outside the private network we get the public IP address of www but not ramses, which wasn't in the public zone data file:
    coord@mudel:~$ sudo ifconfig eth0
    eth0      Link encap:Ethernet  HWaddr 08:00:27:d3:f8:c1 
              inet addr:192.168.1.145  Bcast:192.168.1.255  Mask:255.255.255.0
              inet6 addr: fe80::a00:27ff:fed3:f8c1/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:1077 errors:0 dropped:0 overruns:0 frame:0
              TX packets:598 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:1269977 (1.2 MiB)  TX bytes:52897 (51.6 KiB)

    coord@mudel:~$ nslookup
    > server zeus
    Default server: zeus
    Address: 192.168.1.143#53
    > www.yourcompany.com
    Server:        zeus
    Address:    192.168.1.143#53

    www.yourcompany.com    canonical name = atila.yourcompany.com.
    Name:    atila.yourcompany.com
    Address: 213.176.100.21
    > ramses.yourcompany.com
    Server:        zeus
    Address:    192.168.1.143#53

    ** server can't find ramses.yourcompany.com: NXDOMAIN
    > exit

Sunday, August 19, 2012

Basic DNS configuration

Let's suppose your company acquired a new domain (mycompany.com) to address its Internet services and it's asking you to configure a DNS server to resolve the names of this services, which probably are www, mail, smtp, pop3, etc.

The steps you should follow are:
  1. Install the bind DNS server in your Linux box (a Debian 6.0.5 squeeze in my case). With
    sudo apt-get install bind9
    you will install the latest bind 9 release (9.7.3 in my case).
  2. Don't configure bind from empty files, for there are a lot of mistakes you will make even if you don't realize you made them. Avoid headaches. Instead, use the example file /etc/bind9/db.empty which already contains the SOA and NS records.
  3. From this file create both files, direct and reverse resolution:
    sergio@zeus:/etc/bind$ sudo cp db.empty db.yourcompany.com
    sergio@zeus:/etc/bind$ sudo cp db.empty db.56.168.192
    Note that in my case the LAN is 192.168.56.0/24.
  4. Edit the direct resolution file (db.yourcompany.com). Modify the SOA record and add the other records you may need. Then, it should be similar to this one:
    ; BIND direct file for yourcompany.com zone
    ;
    $TTL    86400
    @       IN      SOA     zeus.yourcompany.com. hostmaster.yourcompany.com. (
                                  1         ; Serial
                              43200         ; Refresh (12h)
                               3600         ; Retry (1h)
                            2419200         ; Expire (2 weeks)
                              86400 )       ; Negative Cache TTL
    ;
    @       IN      NS      zeus.yourcompany.com.
    @       IN      MX      10 mail.yourcompany.com.
    zeus    IN      A       192.168.56.101
    atila   IN      A       192.168.56.102
    ramses  IN      A       192.168.56.103
    www     IN      CNAME   atila
    mail    IN      CNAME   ramses
    smtp    IN      CNAME   ramses
    pop3    IN      CNAME   ramses
    I have changed some of the parameters of the SOA record, although it's unnecessary if you don't have a secondary or slave server.
  5. Now edit the reverse resolution file (db.56.168.192). Modify the SOA record and add the PTR records. The result should be something similar to:
    ; BIND reverse file for 56.168.192.in-addr.arpa IPv4 zone
    ;
    ;
    $TTL    86400
    @       IN      SOA     zeus.yourcompany.com. hostmaster.yourcompany.com. (
                                  1         ; Serial
                              43200         ; Refresh (12h)
                               3600         ; Retry (1h)
                            2419200         ; Expire (2 weeks)
                              86400 )       ; Negative Cache TTL
    ;
    @       IN      NS      zeus.yourcompany.com.
    101     IN      PTR     zeus.yourcompamy.com.
    102     IN      PTR     atila.yourcompamy.com.
    103     IN      PTR     ramses.yourcompamy.com.
    Be aware of ending the FQDN with a dot if you don't want the name of the zone to be append.
  6. Edit the file named.conf.local, where you'll configure bind to access the files already created.
    //
    // Do any local configuration here
    //

    zone "yourcompany.com" {
            type master;
            file "/etc/bind/db.yourcompany.com";
    };

    zone "56.168.192.in-addr.arpa" {
            type master;
            file "/etc/bind/db.56.168.192";
    };

    // Consider adding the 1918 zones here, if they are not used in your
    // organization
    //include "/etc/bind/zones.rfc1918";
  7. Now you might want to modify the loopback resolution files (db.local for direct and db.127 for reverse) and the broadcast reverse resolution files (db.0 and db.255) the same way you did with your zones files. Don't forget to add them up to the file named.conf.local.
  8. Restart the service with the command
    sudo service bind9 restart
    where sudo is necessary if you're not root (which I would recommend).
  9. And try to ask the server about your configuration using nslookup:
    sergio@zeus:/etc/bind$ nslookup
    > server 127.0.0.1
    Default server: 127.0.0.1
    Address: 127.0.0.1#53
    > www.yourcompany.com
    Server:        127.0.0.1
    Address:    127.0.0.1#53

    www.yourcompany.com    canonical name = atila.yourcompany.com.
    Name:    atila.yourcompany.com
    Address: 192.168.56.102
    > ramses.yourcompany.com
    Server:        127.0.0.1
    Address:    127.0.0.1#53

    Name:    ramses.yourcompany.com
    Address: 192.168.56.103
    > 192.168.56.102
    Server:        127.0.0.1
    Address:    127.0.0.1#53

    102.56.168.192.in-addr.arpa    name = atila.yourcompamy.com.
    > pop3.yourcompany.com
    Server:        127.0.0.1
    Address:    127.0.0.1#53

    pop3.yourcompany.com    canonical name = ramses.yourcompany.com.
    Name:    ramses.yourcompany.com
    Address: 192.168.56.103
    > set q=MX
    > yourcompany.com
    Server:        127.0.0.1
    Address:    127.0.0.1#53

    yourcompany.com    mail exchanger = 10 mail.yourcompany.com.
    > exit
  10. If you want your DNS server to query itself, just configure the /etc/resolv.conf file to look like this:
    domain yourcompany.com
    search yourcompany.com
    nameserver 127.0.0.1

Wednesday, August 15, 2012

How to configure a SSH connection with no password

This is needed to:
  • Move from a system's user to another system's user without typing the password.
  • Allow automatic scripts to execute remote commands or copy / move data from one system to another.
Be aware of:
  • If the user account you use to connect to remote systems is hacked, all your systems might be compromised.
  • Do not allow root user to remotely connect without password unless necessary, for the risk is higher.
  • The configuration is not bidirectional. You must do all the steps to configure the connection back from the remote to the local system.
In my case, I will show you how to configure a SSH connection from the user sergio of the local system odin (Ubuntu 12.04 with kernel 3.2.0-29) to the user coord of the remote system mudel (Debian 6.0 with kernel 2.6.32-5).

The steps are:
  1. Create a pair of keys (public and private) in the user's home of the system you will use to connect to the remote system. The command to use is ssh-keygen.
    You can change the filenames where your keys will be stored.
    When asked about the passphrase, keep it empty, otherwise it will be required when establishing a connection to the remote system.
    sergio@odin:~$ ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/sergio/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/sergio/.ssh/id_rsa.
    Your public key has been saved in /home/sergio/.ssh/id_rsa.pub.
    The key fingerprint is:
    ce:bb:e5:75:e4:8f:23:67:09:12:c8:9c:39:ad:3e:bd sergio@odin
    The key's randomart image is:
    +--[ RSA 2048]----+
    |                 |
    |                 |
    |       o =       |
    |        B o      |
    |        So .  .  |
    |       o. . .o   |
    |       .o.....o. |
    |        o+....=o |
    |        ooE. +...|
    +-----------------+
  2. A directory .ssh will be created, containing the two files. Be aware of keeping the permissions of the private key file (id_rsa) readable only by the owner.
    sergio@odin:~$ ls -l .ssh
    total 8
    -rw------- 1 sergio sergio 1679 ago 15 11:46 id_rsa
    -rw-r--r-- 1 sergio sergio  393 ago 15 11:46 id_rsa.pub
  3. Append the content of the public key file (id_rsa.pub) to the file ~/.ssh/authorized_keys of the remote system. To do so, you might send it by e-mail, copy and paste, remote copy to a temporary file or use the ssh-copy-id tool, which will do all the work.
    sergio@odin:~$ ssh-copy-id coord@mudel
    The authenticity of host 'mudel (192.168.56.1)' can't be established.
    RSA key fingerprint is 0c:48:50:6c:67:df:1f:8c:ac:22:c2:ee:0b:a8:98:55.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'mudel,192.168.56.1' (RSA) to the list of known hosts.
    coord@mudel's password:
    Now try logging into the machine, with "ssh 'coord@mudel'", and check in:

      ~/.ssh/authorized_keys

    to make sure we haven't added extra keys that you weren't expecting.
  4. The first time you establish a SSH connection, the fingerprint of the origin system will be shown and you will be asked if it should be append to the ~/.ssh/known_hosts file of the remote system. Answer yes.
  5. Now try to connect.
    sergio@odin:~$ ssh coord@mudel
    Linux mudel 2.6.32-5-686 #1 SMP Tue Mar 8 21:36:00 UTC 2011 i686

    The programs included with the Debian GNU/Linux system are free software;
    the exact distribution terms for each program are described in the
    individual files in /usr/share/doc/*/copyright.

    Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
    permitted by applicable law.
    Last login: Wed Aug 15 12:07:26 2012
    coord@mudel:~$