Changelog¶
All notable changes to Hornet are documented here.
[0.3.0]: Unreleased: rendering what bindy emits¶
0.3.0 closes the four gaps that kept the bindy operator from rendering its BIND9
configuration through hornet's writer
(ADR-0004).
Every grammar decision was checked with named-checkconf on BIND 9.18 and 9.20.
Breaking changes¶
LogChannel::print_timeisOption<PrintTime>, notOption<bool>. ReplaceSome(true)withSome(PrintTime::Yes)andSome(false)withSome(PrintTime::No).Statementhas a new variant,DnssecPolicy. An exhaustivematchonStatementneeds an arm for it. Adnssec-policyblock that 0.2 returned asStatement::Unknown { keyword: "dnssec-policy", .. }is now typed.OptionsBlockhas three new fields (allow_new_zones,key_directory,dnssec_policy). Struct literals without..Default::default()must add them, and code that looked for these options inOptionsBlock::extramust read the fields instead.- Library builds no longer enable
miette/fancy. It is enabled only by theclifeature. A program that renders hornet errors with miette's graphical handler must enablefancyon its ownmiettedependency. The CLI's output is unchanged.
Added¶
print-time local | iso8601 | iso8601-utc(BIND 9.16 and later); aloggingblock using them is now typed instead of falling back toStatement::Unknown.Statement::DnssecPolicy(DnssecPolicyStmt)withDnssecPolicyKey,DnssecKeyRole,DnssecKeyStorage,DnssecKeyLifetimeandNsec3Param, covering the BIND 9.18 and 9.20 grammar; unmodelled clauses go to the policy's ownextraraw carrier.named_conf::is_duration(the BIND duration grammar) andnamed_conf::BUILTIN_DNSSEC_POLICIES.- Typed
allow-new-zones,key-directoryanddnssec-policyinoptions. - Validator checks for
dnssec-policy: duplicate and reserved names, unknown key roles, unrecognised or deprecated algorithms, KSK / ZSK coverage per algorithm, invalid durations,nsec3param iterationsother than 0, and zones whose effective policy is undefined. - The writer quotes policy names,
key-storenames and digest types, and writes durations and algorithms bare only when they match their grammar. - e2e: fixtures for every new construct, and a
min-bindmarker for fixtures that need BIND 9.20.
[0.2.0]: Hardening release¶
0.2.0 fixes every finding from hornet's first threat-model pass (see the threat model, section 6, and ADR-0003), reaches 100% test coverage, and checks every change against real BIND9 9.18 and 9.20.
Security¶
- Writer injection fixed (F2, F3). No AST string can break out of its
syntactic position any more. named.conf strings are quoted and escaped by
position; zone files use RFC 1035 escaping (
\",\\,\DDD) for every character-string, name and token. A TXT value ending in a backslash can no longer inject records. Raw carriers (extra,Statement::Unknown,RData::Unknown) stay verbatim and are documented as trusted input only. - Parse divergence fixed (F4, F5, F7). Quoted strings honour
\"; unmodelled statements are captured quote- and comment-aware; keywords andany/none/localhost/localnetsmatch whole words only, so an ACL namedanyoneis a reference. - Quadratic parsing fixed (F1). Parse time is linear in the input size.
- CLI no longer deletes comments silently (F6).
fmtandconvert --in-placerefuse to rewrite a file with comments unless given--force; stdout modes warn.
Added¶
parse_named_conf_source(source_name, input)andparse_zone_file_source(source_name, input): parse text you already hold, with diagnostics naming its source.writer::zone_file::{escape_char_string, escape_name, escape_token}andast::zone_file::MODELLED_RTYPES.- Typed parsing of LOC, RRSIG, NSEC3 and NSEC3PARAM records;
\DDD/\Xdecoding in zone files; names with/(RFC 2317) and escapes. - named.conf:
controls { unix ... },in-view,type delegation-only, quoted ACL references, classesCH/CHAOS,HS/HESIOD,ANY, and the options, zone and server fields the writer now emits (update-policy,forwarders,rate-limit,response-policy,notify-source,transfer-source,query-source,send-cookie,edns-version, and more). check-zonewarns when a record's data was kept verbatim because it does not match its type.- CLI:
--no-modernonparseandfmt;--forceonfmtandconvert.
Changed¶
- License changed from MIT to Apache-2.0. The
LICENSEfile, SPDX headers,Cargo.tomland docs now say Apache-2.0, and aNOTICEfile is included. parse_zone_filecan return an error. A line that is not a record or a known directive (an unknown$directive, a bad$TTL, a line with no record type) is an error naming its line number; 0.1 skipped such lines silently. Record data that does not match its type is kept verbatim asRData::Unknowninstead of being dropped.- Zone files: only
;starts a comment;#and//are data. - Writer:
WriteOptions::explicit_classnow applies (IN at the top level, the view's class inside a view); empty address-match lists are written{ }; every modelled field is written. - CLI:
parseandfmtaccept--no-modernto emit legacy keywords (master,slave,masters);--modernremains the default and the last flag given wins. Previously--moderncould not be turned off. - Zone parser:
$TTLvalues that overflow 32 bits are rejected instead of wrapping.$TTLalso accepts compound values such as1h30m.
Fixed¶
- Writer:
controlskey lists now end with;(BIND rejected the output), andread-onlyis written. - Writer: with legacy keywords, a zone's
primariesoption is written asmasters. - Writer:
in-viewanddelegation-onlyzones are written in the syntax BIND accepts. - named.conf parser:
syslog authpriv;and uppercase size suffixes (256M) parse. - Zone parser: no record is silently dropped any more. The record following a
single-line SOA, TXT, LOC, HTTPS, NSEC, unknown-type or
$GENERATEline, and a DNSKEY continuation starting with//, are kept. - Zone parser: blank-owner lines inherit the previous owner; any record may
span lines in parentheses;
;inside a quoted TXT string is data;$GENERATEwith$in the left-hand side is parsed.
[0.1.0] — Initial release¶
Added¶
- Parse
named.conffrom a string or file path (parse_named_conf,parse_named_conf_file) - Parse DNS zone files from a string or file path (
parse_zone_file,parse_zone_file_from_path) - Write ASTs back to valid BIND9 text (
write_named_conf,write_zone_file) WriteOptionswith configurable indent, keyword style, class emission, and statement spacing- Semantic validation for
named.conf(validate_named_conf) covering:- Undefined ACL references
- Duplicate zone declarations
- Primary zones without
filedirectives - Secondary zones without
primariesdirectives - Forward zones without
forwarders - DNSSEC/recursion conflicts
- Unrecognised key algorithms
- Invalid CIDR prefixes
- Empty key secrets
- Undefined logging channels
- Zone name length violations
- Semantic validation for zone files (
validate_zone_file) covering:- Missing or duplicate SOA records
- Missing NS records
- TXT chunk/total size limits
- Null MX detection
- Non-standard CAA tags
- Support for 9
named.confstatement types:options,zone,view,acl,logging,controls,key,primaries/masters,server,include, unknown blocks - Support for 24+ DNS record types: A, AAAA, NS, MX, SOA, CNAME, PTR, HINFO, TXT, SRV, CAA, SSHFP, TLSA, NAPTR, LOC, DS, DNSKEY, RRSIG, NSEC, NSEC3, NSEC3PARAM, HTTPS, SVCB, ANAME/ALIAS, TYPE fallback
$ORIGIN,$TTL,$INCLUDE,$GENERATEzone file directives- Optional
serdefeature flag (addsSerialize/Deserializeto all AST types) hornet-clibinary withparse,zone,check,check-zone,fmt,convertsubcommands- Rich parse error reporting via miette with source spans
- Legacy keyword normalisation (
master→primary,slave→secondary)
Versioning¶
Hornet follows Semantic Versioning:
- Patch (
0.1.x) — Bug fixes and documentation; no breaking changes - Minor (
0.x.0) — New record types, statement fields, or validation rules; no breaking changes - Major (
x.0.0) — Breaking changes to the public API or AST shape