BIND 9 In-Line Signing Internals

  • In-Line Signing feature automatically creates and maintains a new dns_zone for signed data. Link between signed and unsigned zone is stored in struct dns_zone:

    struct dns_zone {
        dns_zone_t  *raw;    /* unsigned zone (original) */
        dns_zone_t  *secure; /* signed zone */
    };
    
  • DNS zone is unsigned if zone->raw == NULL

  • view->zonetable contains secure zone

  • DNS updates are done in raw zone:

    • ns_update_start() finds secure zone in zonetable and redirects the update to raw zone.
    • send_update_event() works on raw zone.

Creating secure & raw zone tandem

  • bin/named/server.c: configure_zone() creates to-be-secure zone (variable zone):

    CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone));
    CHECK(dns_zone_setorigin(zone, origin));
    dns_zone_setview(zone, view);
    if (view->acache != NULL)
        dns_zone_setacache(zone, view->acache);
    CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
    dns_zone_setstats(zone, ns_g_server->zonestats);
    
  • bin/named/server.c: configure_zone() creates raw zone later:

    signing = NULL;
    if ((strcasecmp(ztypestr, "master") == 0 ||
         strcasecmp(ztypestr, "slave") == 0) &&
        cfg_map_get(zoptions, "inline-signing", &signing) == ISC_R_SUCCESS &&
        cfg_obj_asboolean(signing))
    {
        dns_zone_getraw(zone, &raw);
        if (raw == NULL) {
            CHECK(dns_zone_create(&raw, mctx));
            CHECK(dns_zone_setorigin(raw, origin));
            dns_zone_setview(raw, view);
            if (view->acache != NULL)
                dns_zone_setacache(raw, view->acache);
            dns_zone_setstats(raw, ns_g_server->zonestats);
    
    /* Following line interconnects secure and raw zone.
       Secure zone has to be managed by zonemgr already. */
            CHECK(dns_zone_link(zone, raw));
        }
    }
    

Configuring in-line zones

BIND implements zone configuration in bin/named/zoneconf.c: ns_zone_configure().

  • Secure zone always has type dns_zone_master
Parameter Zone Function Notes
Name checks raw dns_zone_setoption DNS_ZONEOPT_CHECKNAMES
Update ACL raw configure_zone_ssutable  
Notify raw dns_zone_setnotifytype dns_notifytype_no
Notify secure dns_zone_setnotifytype dns_zone_setisself()
Journal file raw + secure dns_zone_setjournal  
Query ACL secure configure_zone_acl  
Transfer ACL secure configure_zone_acl  
DNSSEC options secure   key-directory; auto-dnssec
Statistics secure dns_zone_setstatlevel  
Name checks secure dns_zone_setoption disabled

Signing parameters have to be configured explicitly on a secure zone:

/* Magic constants are taken from zoneconf.c */
dns_zone_setsigvalidityinterval(secure, 2592000); /* sig-validity-interval */
dns_zone_setsigresigninginterval(secure, 648000); /* re-sign */
dns_zone_setsignatures(secure, 10); /* sig-signing-signatures */
dns_zone_setnodes(secure, 10); /* sig-signing-nodes */
dns_zone_setprivatetype(secure, 65534); /* sig-signing-type */
dns_zone_setoption(secure, DNS_ZONEOPT_UPDATECHECKKSK, ISC_TRUE); /* update-check-ksk */
dns_zone_setrefreshkeyinterval(secure, 60); /* dnssec-loadkeys-interval */
/* auto-dnssec = maintain */
dns_zone_setkeyopt(secure, DNS_ZONEKEY_ALLOW, ISC_TRUE);
dns_zone_setkeyopt(secure, DNS_ZONEKEY_MAINTAIN, ISC_TRUE);

Zone loading

dns_zone_load() has to be called only on secure zone. It will load raw zone internally (and fail mysteriously if raw zone was loaded manually).