I l@ve RuBoard Previous Section Next Section

3.20 Setting Up a Slave Name Server for a Zone in Multiple Views

3.20.1 Problem

You want to configure a BIND 9 name server as a slave for a zone that exists in multiple views on the master name server.

3.20.2 Solution

Configure the slave name server to initiate the transfers of the zone from different source IP addresses, one for each of the views of the zone. Then configure the master name server to make a different view of the zone visible to each of the slave's source addresses.

For example, say the master name server loads two views of the zone foo.example:

options {
    directory "/var/named";
};

acl internal { 192.168/16; };

view internal {

    match-clients { internal; };

    zone "foo.example" {
        type master;
        file "internal/db.foo.example";
    };

};

view external {

    match-clients { any; };    // match all other IP addresses

    zone "foo.example" {
        type master;
        file "external/db.foo.example";
    };

};

If the slave name server has the IP address 192.168.1.1, it would normally only see -- and only be able to transfer -- the internal version of foo.example.

If you add an IP address alias (say, 192.168.1.2) to the slave's network interface, though, you can reconfigure the master to place that one IP address in the external view. Here's how the configuration of the slave might look:

options {
    directory "/var/named";
};

acl internal { 192.168/16; };

view internal {

    match-clients { internal; };

    zone "foo.example" {
        type slave;
        masters { 192.168.0.1; };
        file "internal/bak.foo.example";
        transfer-source 192.168.1.1;
    };

};

view external {

    match-clients { any; };

    zone "foo.example" {
        type slave;
        masters { 192.168.0.1; };
        file "external/bak.foo.example";
        transfer-source 192.168.1.2;
    };

};

Here's how the primary master's named.conf file might look, after changing the configuration to place the slave's new address in the external view:

options {
    directory "/var/named";
};

acl internal { ! 192.168.1.2; 192.168/16; };

view internal {

    match-clients { internal; };

    zone "foo.example" {
        type master;
        file "internal/db.foo.example";
    };

};

view external {

    match-clients { any; };    // match all other IP addresses

    zone "foo.example" {
        type master;
        file "external/db.foo.example";
    };

};

There are still minor problems with this configuration as written -- NOTIFY doesn't work. When the primary master name server sends NOTIFY messages to the slave, the slave interprets those NOTIFY messages according to the view the source address of the message is in. Since the primary master's address is in the slave's internal view, the slave assumes all NOTIFY messages refer to the internal copy of foo.example. Also, the primary will look up the addresses of the slave to send it NOTIFY messages. If the primary's address is in its own internal view, it'll only find the slave's internal address.

To solve this, the master needs two addresses, too: one from which it can look up the slave's internal address and send NOTIFY messages about the internal view, and one from which it can look up the slave's external address and send NOTIFY messages about the external view. And, of course, both the primary master and the slave need to consider the primary's extra address part of its external view. So the primary master's configuration ends up looking like this:

// Primary master; has IP addresses 192.168.0.1 and 192.168.0.2

options {
    directory "/var/named";
};

acl internal { !192.168.0.2; ! 192.168.1.2; 192.168/16; };

view internal {

    match-clients { internal; };

    query-source address 192.168.0.1;    // so it sees slave's internal addr

    zone "foo.example" {
        type master;
        file "internal/db.foo.example";
        notify-source 192.168.0.1;       // so the NOTIFY falls into the 
                                         // slave's internal view
    };

};

view external {

    match-clients { any; };             // match all other IP addresses

    query-source address 192.168.0.2;   // so it sees slave's external addr

    zone "foo.example" {
        type master;
        file "external/db.foo.example";
        notify-source 192.168.0.2;      // so the NOTIFY falls into the
                                        // slave's external view
    };

};

And the slave's configuration looks like this:

// Slave; has IP addresses 192.168.1.1 and 192.168.1.2

options {
    directory "/var/named";
};

acl internal { !192.168.0.2; !192.168.1.2; 192.168/16; };

view internal {

    match-clients { internal; };

    query-source address 192.168.1.1;    // so it sees internal addrs

    zone "foo.example" {
        type slave;
        masters { 192.168.0.1; };
        file "internal/bak.foo.example";
        transfer-source 192.168.1.1;     // so it gets the internal view
    };

};

view external {

    match-clients { any; };

    query-source address 192.168.1.2;    // so it sees external addrs

    zone "foo.example" {
        type slave;
        masters { 192.168.0.1; };
        file "external/bak.foo.example";
        transfer-source 192.168.1.2;     // so it gets the external view
    };

};

3.20.3 Discussion

Notice that the negation of the new IP address of the slave name server in the definition of the internal access control list causes queries from that address -- including zone transfer requests -- to fall through to the external view.

3.20.4 See Also

Section 3.18 for setting up multiple views on a primary master name server.

    I l@ve RuBoard Previous Section Next Section