Blame
Date:
Sun Dec 27 01:56:09 2020 UTC
Message:
Updated p5-Class-DBI-SQLite-0.11p2
001
2020-10-11
jrmu
#!/usr/bin/perl
002
2020-10-11
jrmu
003
2020-10-11
jrmu
package DNS;
004
2020-10-11
jrmu
005
2020-10-11
jrmu
use strict;
006
2020-10-11
jrmu
use warnings;
007
2020-10-11
jrmu
use OpenBSD::Pledge;
008
2020-10-11
jrmu
use OpenBSD::Unveil;
009
2020-10-23
jrmu
use Data::Dumper;
010
2020-10-11
jrmu
use File::Copy qw(copy);
011
2020-10-11
jrmu
012
2020-11-15
jrmu
my %conf = %main::conf;
013
2020-11-15
jrmu
my $chans = $conf{chans};
014
2020-11-15
jrmu
my $staff = $conf{staff};
015
2020-11-15
jrmu
my $key = $conf{key};
016
2020-11-15
jrmu
my $hash = $conf{hash};
017
2020-11-15
jrmu
my $hostname = $conf{hostname};
018
2020-11-15
jrmu
my $verbose = $conf{verbose};
019
2020-11-15
jrmu
my $ipv4 = $conf{ipv4};
020
2020-11-15
jrmu
my $zonedir = $conf{zonedir};
021
2020-11-15
jrmu
my $ipv6path = $conf{ipv6path};
022
2020-11-15
jrmu
my $hostnameif = $conf{hostnameif};
023
2020-11-15
jrmu
# Validate ipv6s if it exists, otherwise load addresses from /etc/hostname.if
024
2020-10-11
jrmu
my @ipv6s;
025
2020-11-15
jrmu
if (!(-s "$ipv6path")) {
026
2020-11-15
jrmu
print "No IPv6 addresses in $ipv6path, loading from $hostnameif...\n";
027
2020-11-15
jrmu
@ipv6s = readipv6s($hostnameif);
028
2020-11-15
jrmu
} else {
029
2020-11-15
jrmu
@ipv6s = readipv6s($ipv6path);
030
2020-11-15
jrmu
}
031
2020-11-15
jrmu
if (!@ipv6s) { die "No IPv6 addresses in $ipv6path or $hostnameif!"; }
032
2020-11-15
jrmu
if (host($hostname) =~ /(\d+\.){3,}\d+/) {
033
2020-11-15
jrmu
$ipv4 = $&;
034
2020-11-15
jrmu
}
035
2020-11-15
jrmu
main::cbind("msg", "-", "setrdns", \&msetrdns);
036
2020-11-15
jrmu
main::cbind("msg", "-", "delrdns", \&mdelrdns);
037
2020-11-15
jrmu
main::cbind("msg", "-", "setdns", \&msetdns);
038
2020-11-15
jrmu
main::cbind("msg", "-", "deldns", \&mdeldns);
039
2020-11-15
jrmu
main::cbind("msg", "-", "host", \&mhost);
040
2020-11-15
jrmu
main::cbind("msg", "-", "nextdns", \&mnextdns);
041
2020-10-11
jrmu
042
2020-10-11
jrmu
sub init {
043
2020-10-11
jrmu
unveil("$ipv6path", "rwc") or die "Unable to unveil $!";
044
2020-10-11
jrmu
unveil("$zonedir", "rwc") or die "Unable to unveil $!";
045
2020-10-11
jrmu
#dependencies for doas
046
2020-10-11
jrmu
unveil("/usr/bin/doas", "rx") or die "Unable to unveil $!";
047
2020-10-11
jrmu
#dependencies for host
048
2020-10-11
jrmu
unveil("/usr/bin/host", "rx") or die "Unable to unveil $!";
049
2020-10-11
jrmu
}
050
2020-10-11
jrmu
051
2020-10-11
jrmu
sub msetrdns {
052
2020-10-11
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
053
2020-10-11
jrmu
if ($staff !~ /$nick/) { return; }
054
2020-10-11
jrmu
if ($text =~ /^([0-9A-Fa-f:\.]{3,})\s+([-0-9A-Za-z\.]+)/) {
055
2020-10-11
jrmu
my ($ip, $hostname) = ($1, $2);
056
2020-10-11
jrmu
if (setrdns($ip, $hostname)) {
057
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :$hostname set to $ip");
058
2020-10-11
jrmu
} else {
059
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set rDNS");
060
2020-10-11
jrmu
}
061
2020-10-11
jrmu
}
062
2020-10-11
jrmu
}
063
2020-10-11
jrmu
sub mdelrdns {
064
2020-10-11
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
065
2020-10-11
jrmu
if ($staff !~ /$nick/) { return; }
066
2020-10-11
jrmu
if ($text =~ /^([0-9A-Fa-f:\.]{3,})$/) {
067
2020-10-11
jrmu
my $ip = $1;
068
2020-10-11
jrmu
my $hostname = "notset";
069
2020-10-11
jrmu
if (setrdns($ip, $hostname)) {
070
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :$ip rDNS deleted");
071
2020-10-11
jrmu
} else {
072
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set rDNS");
073
2020-10-11
jrmu
}
074
2020-10-11
jrmu
}
075
2020-10-11
jrmu
}
076
2020-10-11
jrmu
sub msetdns {
077
2020-10-11
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
078
2020-10-11
jrmu
if ($staff !~ /$nick/) { return; }
079
2020-10-11
jrmu
if ($text =~ /^([-0-9A-Za-z\.]+)\s+([0-9A-Fa-f:\.]+)/) {
080
2020-10-11
jrmu
my ($hostname, $ip) = ($1, $2);
081
2020-10-11
jrmu
if (setdns($hostname, $ip)) {
082
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :$hostname set to $ip");
083
2020-10-11
jrmu
} else {
084
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set DNS");
085
2020-10-11
jrmu
}
086
2020-10-11
jrmu
}
087
2020-10-11
jrmu
}
088
2020-10-11
jrmu
sub mdeldns {
089
2020-10-11
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
090
2020-10-11
jrmu
if ($staff !~ /$nick/) { return; }
091
2020-10-11
jrmu
if ($text =~ /^([-0-9A-Za-z\.]+)/) {
092
2020-10-11
jrmu
if (setdns($text)) {
093
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :$text deleted");
094
2020-10-11
jrmu
} else {
095
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :ERROR: failed to delete DNS records");
096
2020-10-11
jrmu
}
097
2020-10-11
jrmu
}
098
2020-10-11
jrmu
}
099
2020-10-11
jrmu
sub mhost {
100
2020-10-11
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
101
2020-10-11
jrmu
if ($staff !~ /$nick/) { return; }
102
2020-10-11
jrmu
if ($text =~ /^([-0-9A-Za-z:\.]{3,})/) {
103
2020-10-11
jrmu
my ($hostname, $version) = ($1, $2);
104
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :".host($hostname));
105
2020-10-11
jrmu
}
106
2020-10-11
jrmu
}
107
2020-10-11
jrmu
108
2020-10-11
jrmu
sub mnextdns {
109
2020-10-11
jrmu
my ($bot, $nick, $host, $hand, $text) = @_;
110
2020-10-11
jrmu
if ($staff !~ /$nick/) { return; }
111
2020-10-11
jrmu
if ($text =~ /^([-0-9a-zA-Z]+)/) {
112
2020-10-11
jrmu
main::putserv($bot, "PRIVMSG $nick :$text set to ".nextdns($text));
113
2020-10-11
jrmu
}
114
2020-10-11
jrmu
}
115
2020-10-11
jrmu
116
2020-10-11
jrmu
# Given filename, return a list of ipv6 addresses
117
2020-10-11
jrmu
sub readipv6s {
118
2020-10-11
jrmu
my ($filename) = @_;
119
2020-10-11
jrmu
my @lines = main::readarray($filename);
120
2020-10-11
jrmu
my @ipv6s;
121
2020-10-11
jrmu
foreach my $line (@lines) {
122
2020-10-11
jrmu
if ($line =~ /^\s*inet6 (alias )?([0-9a-f:]{4,}) [0-9]+\s*$/i) {
123
2020-10-11
jrmu
push(@ipv6s, $2);
124
2020-10-11
jrmu
} elsif ($line =~ /^\s*([0-9a-f:]{4,})\s*$/i) {
125
2020-10-11
jrmu
push(@ipv6s, $1);
126
2020-10-11
jrmu
}
127
2020-10-11
jrmu
}
128
2020-10-11
jrmu
return @ipv6s;
129
2020-10-11
jrmu
}
130
2020-10-11
jrmu
131
2020-10-11
jrmu
# returns true upon success, false upon failure
132
2020-10-11
jrmu
sub setrdns {
133
2020-10-11
jrmu
my ($ip, $hostname) = @_;
134
2020-10-11
jrmu
my $stdout = `curl -d \"key=$key&hash=$hash&action=rdns&ip=$ip&rdns=$hostname\" https://manage.buyvm.net/api/client/command.php`;
135
2020-10-11
jrmu
if ($stdout !~ /success/) {
136
2020-10-11
jrmu
return 0;
137
2020-10-11
jrmu
}
138
2020-10-11
jrmu
return 1;
139
2020-10-11
jrmu
}
140
2020-10-11
jrmu
# set $domain to $ip if provided; otherwise, delete $domain
141
2020-10-11
jrmu
# returns true upon success, false upon failure
142
2020-10-11
jrmu
sub setdns {
143
2020-10-11
jrmu
my ($domain, $ip) = @_;
144
2020-10-11
jrmu
my $filename = "$zonedir/$hostname";
145
2020-10-11
jrmu
my $subdomain;
146
2020-10-11
jrmu
if ($domain =~ /^([a-zA-Z][-\.a-zA-Z0-9]+)\.$hostname$/) {
147
2020-10-11
jrmu
$subdomain = $1;
148
2020-10-11
jrmu
} else {
149
2020-10-11
jrmu
return 0;
150
2020-10-11
jrmu
}
151
2020-10-11
jrmu
my @lines = main::readarray($filename);
152
2020-10-11
jrmu
foreach my $line (@lines) {
153
2020-10-11
jrmu
# increment the zone's serial number
154
2020-10-11
jrmu
if ($line =~ /(\d{8})(\d{2})((\s+\d+){4}\s*\))/) {
155
2020-10-11
jrmu
my $date = main::date();
156
2020-10-11
jrmu
my $serial = 0;
157
2020-10-11
jrmu
if ($date <= $1) { $serial = $2+1; }
158
2020-10-11
jrmu
$line = $`.$date.sprintf("%02d",$serial).$3.$';
159
2020-10-11
jrmu
}
160
2020-10-11
jrmu
}
161
2020-10-11
jrmu
if ($ip =~ /^([0-9\.]+)$/) { # if IPv4
162
2020-10-11
jrmu
push(@lines, "$subdomain 3600 IN A $ip");
163
2020-10-11
jrmu
} elsif ($ip =~ /:/) { # if IPv6
164
2020-10-11
jrmu
push(@lines, "$subdomain 3600 IN AAAA $ip");
165
2020-10-11
jrmu
} elsif (!defined($ip)) { # delete records
166
2020-10-11
jrmu
@lines = grep !/\b$subdomain\s*3600\s*IN/, @lines;
167
2020-10-11
jrmu
}
168
2020-10-11
jrmu
# trailing newline necessary
169
2020-10-11
jrmu
main::writefile("$filename.bak", join("\n", @lines)."\n");
170
2020-10-11
jrmu
copy "$filename.bak", $filename;
171
2020-10-11
jrmu
if (system("doas -u _nsd nsd-control reload")) {
172
2020-10-11
jrmu
return 0;
173
2020-10-11
jrmu
} else {
174
2020-10-11
jrmu
return 1;
175
2020-10-11
jrmu
}
176
2020-10-11
jrmu
}
177
2020-10-11
jrmu
178
2020-10-11
jrmu
# given hostname, return IP addresses; or given IP address, return hostname
179
2020-10-11
jrmu
sub host {
180
2020-10-11
jrmu
my ($name) = @_;
181
2020-10-11
jrmu
my @matches;
182
2020-10-11
jrmu
my @lines = split /\n/m, `host $name`;
183
2020-10-11
jrmu
if ($name =~ /^[0-9\.]+$/ or $name =~ /:/) { # IP address
184
2020-10-11
jrmu
foreach my $line (@lines) {
185
2020-10-11
jrmu
if ($line =~ /([\d\.]+).(in-addr|ip6).arpa domain name pointer (.*)/) {
186
2020-10-11
jrmu
push(@matches, $3);
187
2020-10-11
jrmu
}
188
2020-10-11
jrmu
}
189
2020-10-11
jrmu
} else { # hostname
190
2020-10-11
jrmu
foreach my $line (@lines) {
191
2020-10-11
jrmu
if ($line =~ /$name has (IPv6 )?address ([0-9a-fA-F\.:]+)/) {
192
2020-10-11
jrmu
push(@matches, $2);
193
2020-10-11
jrmu
}
194
2020-10-11
jrmu
}
195
2020-10-11
jrmu
}
196
2020-10-11
jrmu
return join(' ', @matches);
197
2020-10-11
jrmu
}
198
2020-10-11
jrmu
199
2020-10-11
jrmu
# create A and AAAA records for subdomain, set the rDNS,
200
2020-10-11
jrmu
# and return the new ipv6 address
201
2020-10-11
jrmu
sub nextdns {
202
2020-10-11
jrmu
my ($subdomain) = @_;
203
2020-10-11
jrmu
my $ipv6 = shift(@ipv6s);
204
2020-10-11
jrmu
my $fqdn = "$subdomain.$hostname";
205
2020-10-20
jrmu
main::writefile($ipv6path, join("\n", @ipv6s));
206
2020-10-11
jrmu
if (setdns($fqdn, $ipv4) && setdns($fqdn, $ipv6) && setrdns($ipv6, $fqdn)) {
207
2020-10-11
jrmu
return "$ipv6";
208
2020-10-11
jrmu
}
209
2020-10-11
jrmu
return "false";
210
2020-10-11
jrmu
}
211
2020-10-11
jrmu
212
2020-10-11
jrmu
1; # MUST BE LAST STATEMENT IN FILE