diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 02f6fd1..6310c3f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ jobs: whoami env | sort echo == depend == - sudo pkg_add libunbound + sudo pkg_add libunbound ldns-utils sudo useradd -m _pfresolved echo == build == make all diff --git a/regress/Makefile b/regress/Makefile index 4db97e4..58aa934 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -57,6 +57,23 @@ server.crt: ca.crt ${@:R}.req ${REGRESS_TARGETS:M*tls*}: server.crt ${REGRESS_TARGETS:M*badca*}: badca.crt +# create zone and key signing keys for DNSSEC + +CLEANFILES += *.key *.private *.ds .key .private .ds + +zsk.key: + ldns-keygen -a ED25519 -sf regress + mv .key zsk.key + mv .private zsk.private + +ksk.key: + ldns-keygen -a ED25519 -k -sf regress + mv .key ksk.key + mv .private ksk.private + mv .ds ksk.ds + +${REGRESS_TARGETS:M*dnssec*}: zsk.key ksk.key + # make perl syntax check for all args files .PHONY: syntax diff --git a/regress/Nsd.pm b/regress/Nsd.pm index aeb8c34..3b6dcd0 100644 --- a/regress/Nsd.pm +++ b/regress/Nsd.pm @@ -65,7 +65,11 @@ sub new { print $fh "zone:\n"; # libunbound does not process invalid domain print $fh " name: regress.\n"; - print $fh " zonefile: nsd.zone\n"; + if ($self->{dnssec}) { + print $fh " zonefile: nsd.zone.signed\n"; + } else { + print $fh " zonefile: nsd.zone\n"; + } $self->zone(); @@ -75,7 +79,7 @@ sub new { sub zone { my $self = shift; my %args = @_; - $args{serial} ||= time(); + $args{serial} ||= $self->{serial} || time(); $self->{record_list} = $args{record_list} if $args{record_list}; my $test = basename($self->{testfile} || ""); @@ -95,6 +99,12 @@ sub zone { print $fz "$r\n"; } + if ($self->{dnssec}) { + my @cmd = qw(/usr/local/bin/ldns-signzone -b nsd.zone zsk ksk); + system(@cmd) and die ref($self), + "sign zone command '@cmd' failed: $?"; + } + kill('HUP', $self->{pid}) or die ref($self), " kill HUP child '$self->{pid}' failed: $!" if $args{sighup}; diff --git a/regress/Pfresolved.pm b/regress/Pfresolved.pm index 0b14f72..da35472 100644 --- a/regress/Pfresolved.pm +++ b/regress/Pfresolved.pm @@ -78,6 +78,10 @@ sub child { "-f", $self->{conffile}); push @cmd, "-r", $resolver if $resolver; push @cmd, "-m", $self->{min_ttl} if $self->{min_ttl}; + if ($self->{dnssec_level}) { + push @cmd, "-A", "ksk.ds"; + push @cmd, "-S", $self->{dnssec_level}; + } if ($self->{tls}) { my $ca = $self->{ca} || "ca.crt"; push @cmd, "-C", $ca if $self->{tls}; diff --git a/regress/args-dnssec.pl b/regress/args-dnssec.pl new file mode 100644 index 0000000..7ed56cf --- /dev/null +++ b/regress/args-dnssec.pl @@ -0,0 +1,44 @@ +# Create signed zone file with A and AAAA records in zone regress. +# Start nsd with signed zone file listening on 127.0.0.1. +# Write hosts of regress zone into pfresolved config. +# Start pfresolved with nsd as resolver and dnssec level 3. +# Wait until pfresolved creates table regress-pfresolved. +# Read IP addresses from pf table with pfctl. +# Check that pfresolved added IPv4 and IPv6 addresses. +# Check that pfresolved logged secure when receiving dns. + +use strict; +use warnings; + +our %args = ( + nsd => { + dnssec => 1, + record_list => [ + "foo IN A 192.0.2.1", + "bar IN AAAA 2001:DB8::1", + "foobar IN A 192.0.2.2", + "foobar IN AAAA 2001:DB8::2", + ], + }, + pfresolved => { + dnssec_level => 3, + address_list => [ map { "$_.regress." } qw(foo bar foobar) ], + loggrep => { + qr/-S 3/ => 1, + qr/result for .* secure: 1,/ => 6, + qr{added: 192.0.2.1/32,} => 1, + qr{added: 2001:db8::1/128,} => 1, + qr{added: 192.0.2.2/32,} => 1, + qr{added: 2001:db8::2/128,} => 1, + }, + }, + pfctl => { + updated => [4, 1], + loggrep => { + qr/^ 192.0.2.[12]$/ => 2, + qr/^ 2001:db8::[12]$/ => 2, + }, + }, +); + +1;