Setup NSD
Create new zone file
vi /var/nsd/etc/nsd.conf
zone:
name: "example.com"
# under /var/nsd/zones/
zonefile: "master/example.com.zone"
craete zone file(example)
/var/nsd/zones/master/example.com.zone
$ORIGIN example.com. ; default zone domain
$TTL 86400 ; default time to live
@ IN SOA example.com. admin.example.com. (
1663917795;serial
28800 ; Refresh
7200 ; Retry
864000 ; Expire
86400 ; Min TTL
)
NS ns1.example.com.
MX 10 smtp.example.com.
@ CAA 128 issue "letsencrypt.org"
@ 300 IN A 1.1.1.1;dynamic
;@ 300 IN AAAA 2002:0114:a244:1:5a9c:fcff:fe0f:fb16;dynamic6
home 300 IN A 1.1.1.1;dynamic
smtp 300 IN A 1.1.1.1;dynamic
dns CNAME nsd.example.com.
Enable NSD
rcctl enable nsd
rcctl start nsd
Script detect IP
vi /root/update-dns
#!/usr/bin/perl
my $dns_host = "example.com";
my $dns_url = "/dns/update";
my $file = '/var/nsd/zones/master/example.com.zone';
my $ipv6_host = '2002:%02x%02x:%02x%02x:1:5a9c:fcff:fe0f:fb16';
my $serial = 'serial';
my $record = 'dynamic';
my $record6 = 'dynamic6';
sub update {
my $ip = shift;
my $ip6 = shift;
open( $fh, "<$file" ) or die "File not found";
my @lines = <$fh>;
close($fh);
my $change = 1;
foreach (@lines) {
if (/\d+;$serial/) {
my $t = time;
$_ =~ s/\d+;\Q$serial\E/$t;$serial/;
}
elsif ( $ip && /(\d+\.\d+\.\d+\.\d+);\Q$record\E/ ) {
next if ( $ip eq $1 );
$_ =~ s/\d+\.\d+\.\d+\.\d+;\Q$record\E/$ip;$record/;
$change = 1;
}
elsif ( $ip6 && /(\S+);\Q$record6\E/ ) {
next if ( $ip6 eq $1 );
my $ip6 = sprintf( $ipv6_host, split( /\./, $ip ) );
$_ =~ s/\S+;\Q$record6\E/$ip6;$record6/;
$change = 1;
}
}
if ($change) {
open( $fh, ">$file" ) or die "File not found";
print $fh @lines;
close($fh);
}
return $change;
}
while (<STDIN>) {
if (/\Q$dns_host\E (\d+\.\d+\.\d+\.\d+) .*GET \Q$dns_url\E/) {
qx(rcctl reload nsd) if update( $1, 0 );
}
if (/\Q$dns_host\E ([\:0-9a-fA-F]) .*GET \Q$dns_url\E/) {
qx(rcctl reload nsd) if update( 0, $1 );
}
}
Detect via syslog
Dummy file
mkdir -p /var/www/htdocs/update-dns/dns/
echo "OK" > /var/www/htdocs/update-dns/dns/update
Config syslog
vi /etc/syslog.conf
daemon.info | /usr/bin/doas /usr/bin/perl /root/update-dns
rcctl reload syslogd
Config httpd
vi /etc/httpd.conf
server "dns.example.com" {
listen on * tls port 443
tls {
certificate "/root/.acme.sh/*.example.com/fullchain.cer"
key "/root/.acme.sh/*.example.com/*.example.com.key"
}
default type text/plain
root "/htdocs/update-dns"
log syslog
}
rcctl enable httpd
rcctl start httpd