[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
botnow patch
[Thread Prev] | [Thread Next]
- Subject: botnow patch
- From: jrmu <jrmu@xxxxxxxxxx>
- Date: Tue, 20 Jul 2021 21:11:42 +0800
- To: codeforce@xxxxxxxxxx
This patch fixes DNS/network handling:
1) relies on nsd for both forward and reverse DNS instead of buyvm's API
2) adds IPv6 addresses dynamically
3) fixes some bugs
diff -ur botnow-old/DNS.pm botnow/DNS.pm
--- botnow-old/DNS.pm Tue Jul 20 04:46:02 2021
+++ botnow/DNS.pm Tue Jul 20 04:26:01 2021
@@ -16,21 +16,13 @@
my $hash = $conf{hash};
my $hostname = $conf{hostname};
my $verbose = $conf{verbose};
-my $ipv4 = $conf{ipv4};
+my $ip4 = $conf{ip4};
+my $ip6 = $conf{ip6};
+my $ip6subnet = $conf{ip6subnet};
my $zonedir = $conf{zonedir};
-my $ipv6path = $conf{ipv6path};
my $hostnameif = $conf{hostnameif};
-# Validate ipv6s if it exists, otherwise load addresses from /etc/hostname.if
-my @ipv6s;
-if (!(-s "$ipv6path")) {
- print "No IPv6 addresses in $ipv6path, loading from $hostnameif...\n";
- @ipv6s = readipv6s($hostnameif);
-} else {
- @ipv6s = readipv6s($ipv6path);
-}
-if (!@ipv6s) { die "No IPv6 addresses in $ipv6path or $hostnameif!"; }
if (host($hostname) =~ /(\d+\.){3,}\d+/) {
- $ipv4 = $&;
+ $ip4 = $&;
}
main::cbind("msg", "-", "setrdns", \&msetrdns);
main::cbind("msg", "-", "delrdns", \&mdelrdns);
@@ -38,73 +30,83 @@
main::cbind("msg", "-", "deldns", \&mdeldns);
main::cbind("msg", "-", "host", \&mhost);
main::cbind("msg", "-", "nextdns", \&mnextdns);
+main::cbind("msg", "-", "readip6s", \&mreadip6s);
sub init {
- unveil("$ipv6path", "rwc") or die "Unable to unveil $!";
unveil("$zonedir", "rwc") or die "Unable to unveil $!";
- #dependencies for doas
unveil("/usr/bin/doas", "rx") or die "Unable to unveil $!";
- #dependencies for host
unveil("/usr/bin/host", "rx") or die "Unable to unveil $!";
+ unveil("$hostnameif", "rwc") or die "Unable to unveil $!";
}
+# !setrdns 2001:bd8:: username.example.com
sub msetrdns {
my ($bot, $nick, $host, $hand, $text) = @_;
if (! (main::isstaff($bot, $nick))) { return; }
- if ($text =~ /^([0-9A-Fa-f:\.]{3,})\s+([-0-9A-Za-z\.]+)/) {
+ if ($text =~ /^([0-9A-Fa-f:\.]{3,})\s+([-0-9A-Za-z\.]+)$/) {
my ($ip, $hostname) = ($1, $2);
- if (setrdns($ip, $hostname)) {
+ if (setrdns($ip, $ip6subnet, $hostname)) {
main::putserv($bot, "PRIVMSG $nick :$hostname set to $ip");
} else {
main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set rDNS");
}
}
}
+
+# !delrdns 2001:bd8::
sub mdelrdns {
my ($bot, $nick, $host, $hand, $text) = @_;
if (! (main::isstaff($bot, $nick))) { return; }
if ($text =~ /^([0-9A-Fa-f:\.]{3,})$/) {
- my $ip = $1;
- my $hostname = "notset";
- if (setrdns($ip, $hostname)) {
+ my ($ip) = ($1);
+ if (delrdns($ip, $ip6subnet)) {
main::putserv($bot, "PRIVMSG $nick :$ip rDNS deleted");
} else {
main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set rDNS");
}
}
}
+# !setdns username 1.2.3.4
sub msetdns {
my ($bot, $nick, $host, $hand, $text) = @_;
if (! (main::isstaff($bot, $nick))) { return; }
if ($text =~ /^([-0-9A-Za-z\.]+)\s+([0-9A-Fa-f:\.]+)/) {
- my ($hostname, $ip) = ($1, $2);
- if (setdns($hostname, $ip)) {
- main::putserv($bot, "PRIVMSG $nick :$hostname set to $ip");
+ my ($name, $value) = ($1, $2);
+ if ($value =~ /:/ and setdns($name, $hostname, "AAAA", $value)) {
+ main::putserv($bot, "PRIVMSG $nick :$name.$hostname AAAA set to $value");
+ } elsif (setdns($name, $hostname, "A", $value)) {
+ main::putserv($bot, "PRIVMSG $nick :$name.$hostname A set to $value");
} else {
main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set DNS");
}
}
}
+
+# !deldns username
sub mdeldns {
my ($bot, $nick, $host, $hand, $text) = @_;
if (! (main::isstaff($bot, $nick))) { return; }
- if ($text =~ /^([-0-9A-Za-z\.]+)/) {
- if (setdns($text)) {
+ if ($text =~ /^([-0-9A-Za-z\.]+)$/) {
+ my ($name) = ($1);
+ if (setdns($name, $hostname)) {
main::putserv($bot, "PRIVMSG $nick :$text deleted");
} else {
main::putserv($bot, "PRIVMSG $nick :ERROR: failed to delete DNS records");
}
}
}
+
+# !host username
sub mhost {
my ($bot, $nick, $host, $hand, $text) = @_;
if (! (main::isstaff($bot, $nick))) { return; }
if ($text =~ /^([-0-9A-Za-z:\.]{3,})/) {
- my ($hostname, $version) = ($1, $2);
+ my ($hostname) = ($1);
main::putserv($bot, "PRIVMSG $nick :".host($hostname));
}
}
+# !nextdns username
sub mnextdns {
my ($bot, $nick, $host, $hand, $text) = @_;
if (! (main::isstaff($bot, $nick))) { return; }
@@ -113,13 +115,22 @@
}
}
-# Given filename, return a list of ipv6 addresses
-sub readipv6s {
+# !readip6s
+sub mreadip6s {
+ my ($bot, $nick, $host, $hand, $text) = @_;
+ if (! (main::isstaff($bot, $nick))) { return; }
+ foreach my $line (readip6s($hostnameif)) {
+ print "$line\n"
+ }
+}
+
+# Return list of ipv6 addresses from filename
+sub readip6s {
my ($filename) = @_;
my @lines = main::readarray($filename);
my @ipv6s;
foreach my $line (@lines) {
- if ($line =~ /^\s*inet6 (alias )?([0-9a-f:]{4,}) [0-9]+\s*$/i) {
+ if ($line =~ /^\s*inet6\s+(alias\s+)?([0-9a-f:]{4,})\s+[0-9]+\s*$/i) {
push(@ipv6s, $2);
} elsif ($line =~ /^\s*([0-9a-f:]{4,})\s*$/i) {
push(@ipv6s, $1);
@@ -128,27 +139,33 @@
return @ipv6s;
}
-# TODO: fix rdns request with buyvm's api, the ips must not skip 0s
-# returns true upon success, false upon failure
+# set rdns of $ip6 to $hostname given $subnet
+# return true on success; false on failure
sub setrdns {
- my ($ip, $hostname) = @_;
- my $stdout = `curl -d \"key=$key&hash=$hash&action=rdns&ip=$ip&rdns=$hostname\" https://manage.buyvm.net/api/client/command.php`;
- if ($stdout !~ /success/) {
- return 0;
- }
- return 1;
+ my ($ip6, $subnet, $hostname) = @_;
+ my $digits = ip6full($ip6);
+ $digits =~ tr/://d;
+ my $reversed = reverse($digits);
+ my $origin = substr($reversed, 32-$subnet/4);
+ $origin = join('.', split(//, $origin)).".ip6.arpa";
+ my $name = substr($reversed, 0, 32-$subnet/4);
+ $name = join('.', split(//, $name));
+ # delete old PTR records, then set new one
+ return setdns($name, $origin) && setdns($name, $origin, "PTR", $hostname);
}
-# set $domain to $ip if provided; otherwise, delete $domain
+# delete rdns of $ip6 given $subnet
+# return true on success; false on failure
+sub delrdns {
+ my ($ip6, $subnet) = @_;
+ return setrdns($ip6, $subnet);
+}
+
+# given $origin. create $name RR of $type and set to $value if provided;
+# if $value is missing, delete $domain
# returns true upon success, false upon failure
sub setdns {
- my ($domain, $ip) = @_;
- my $filename = "$zonedir/$hostname";
- my $subdomain;
- if ($domain =~ /^([a-zA-Z][-\.a-zA-Z0-9]+)\.$hostname$/) {
- $subdomain = $1;
- } else {
- return 0;
- }
+ my ($name, $origin, $type, $value) = @_;
+ my $filename = "$zonedir/$origin";
my @lines = main::readarray($filename);
foreach my $line (@lines) {
# increment the zone's serial number
@@ -159,12 +176,10 @@
$line = $`.$date.sprintf("%02d",$serial).$3.$';
}
}
- if ($ip =~ /^([0-9\.]+)$/) { # if IPv4
- push(@lines, "$subdomain 3600 IN A $ip");
- } elsif ($ip =~ /:/) { # if IPv6
- push(@lines, "$subdomain 3600 IN AAAA $ip");
- } elsif (!defined($ip)) { # delete records
- @lines = grep !/\b$subdomain\s*3600\s*IN/, @lines;
+ if (!defined($value)) { # delete records
+ @lines = grep !/\b$name\s*3600\s*IN/, @lines;
+ } else {
+ push(@lines, "$name 3600 IN $type $value");
}
# trailing newline necessary
main::writefile("$filename.bak", join("\n", @lines)."\n");
@@ -197,15 +212,56 @@
return join(' ', @matches);
}
+# Return an ipv6 address with all zeroes filled in
+sub ip6full {
+ my ($ip6) = @_;
+ my $left = substr($ip6, 0, index($ip6, "::"));
+ my $leftcolons = ($left =~ tr/://);
+ $ip6 =~ s{::}{:};
+ my @quartets = split(':', $ip6);
+ my $length = scalar(@quartets);
+ for (my $n = 1; $n <= 8 - $length; $n++) {
+ splice(@quartets, $leftcolons+1, 0, "0000");
+ }
+ my @newquartets = map(sprintf('%04s', $_), @quartets);
+ my $full = join(':',@newquartets);
+ return $full;
+}
+# Returns the network part of the first IPv6 address (indicated by subnet)
+# with the host part of the second IPv6 address
+sub ip6mask {
+ my ($ip6net, $subnet, $ip6host) = @_;
+ my $netdigits = ip6full($ip6net);
+ $netdigits =~ tr/://d;
+ my $hostdigits = ip6full($ip6host);
+ $hostdigits =~ tr/://d;
+ my $digits = substr($netdigits,0,($subnet/4)).substr($hostdigits,($subnet/4));
+ my $ip6;
+ for (my $n = 0; $n < 32; $n++) {
+ if ($n > 0 && $n % 4 == 0) {
+ $ip6 .= ":";
+ }
+ $ip6 .= substr($digits,$n,1);
+ }
+ return $ip6;
+}
+sub randip6 {
+ return join ':', map { sprintf '%04x', rand 0x10000 } (1 .. 8);
+}
+
# create A and AAAA records for subdomain, set the rDNS,
# and return the new ipv6 address
sub nextdns {
my ($subdomain) = @_;
- my $ipv6 = shift(@ipv6s);
- my $fqdn = "$subdomain.$hostname";
- main::writefile($ipv6path, join("\n", @ipv6s));
- if (setdns($fqdn, $ipv4) && setdns($fqdn, $ipv6) && setrdns($ipv6, $fqdn)) {
- return "$ipv6";
+ my $newip6 = $ip6;
+ my @allip6s = readip6s($hostnameif);
+ while (grep(/$newip6/, @allip6s)) {
+ $newip6 = ip6mask($ip6, $ip6subnet,randip6());
+ }
+ main::appendfile($hostnameif, "inet6 alias $newip6 48\n");
+ `doas ifconfig vio0 inet6 $newip6/48`;
+ if (setdns($subdomain, $hostname, "A", $ip4) && setdns($subdomain, $hostname, "AAAA", $newip6) && setrdns($newip6, $ip6subnet, "$subdomain.$hostname")) {
+ return "$newip6";
}
return "false";
}
diff -ur botnow-old/README botnow/README
--- botnow-old/README Tue Jul 20 04:46:04 2021
+++ botnow/README Mon Jul 19 05:06:19 2021
@@ -1,18 +1,18 @@
botnow: the versatile IRC bot
-botnow has only been tested on openbsd 6.7
+botnow has only been tested on openbsd 6.9
### System requirements ###
In order to install botnow, you will need to have the following installed and
configured:
-1) sendmail (https://wiki.ircnow.org/index.php?n=Openbsd.Opensmtpd)
-2) nsd (https://wiki.ircnow.org/index.php?n=Openbsd.Nsd)
-3) openhttpd (https://wiki.ircnow.org/index.php?n=Openbsd.Openhttpd)
+1) sendmail (https://wiki.ircnow.org/index.php?n=Opensmtpd.Configure)
+2) nsd (https://wiki.ircnow.org/index.php?n=Nsd.Configure)
+3) openhttpd (https://wiki.ircnow.org/index.php?n=Openhttpd.Configure)
4) php (https://wiki.ircnow.org/index.php?n=Openbsd.Php)
-5) znc (https://wiki.ircnow.org/index.php?n=Openbsd.Znc)
-6) IPv6 (https://wiki.ircnow.org/index.php?n=Openbsd.Staticnet)
+5) znc (https://wiki.ircnow.org/index.php?n=Znc.Chroot)
+6) IPv6 (https://wiki.ircnow.org/index.php?n=Hostnameif.Static)
### Install instructions ###
diff -ur botnow-old/botnow.conf.example botnow/botnow.conf.example
--- botnow-old/botnow.conf.example Tue Jul 20 04:46:06 2021
+++ botnow/botnow.conf.example Mon Jul 19 05:10:28 2021
@@ -8,8 +8,11 @@
#Bouncer hostname
hostname = example.ircnow.org
-#External IPv4 address, plaintext and ssl port
+#External IP addresses, plaintext and ssl port
ip4 = 192.168.0.1
+ip6 = 2001:db8::
+ip6subnet = 64
+ip6prefix = 48
#plainport = 1337
#sslport = 31337
@@ -35,7 +38,7 @@
hash = ABCDEFGHIJKLMNOPQRST
#Modules to load
-modules = BNC DNS Mail Shell SQLite WWW Hash Help
+modules = BNC DNS Mail Shell SQLite Hash Help
#Comment out the line below
die = You did not configure botnow.conf!
diff -ur botnow-old/botnow.pl botnow/botnow.pl
--- botnow-old/botnow.pl Tue Jul 20 04:46:07 2021
+++ botnow/botnow.pl Mon Jul 19 05:07:10 2021
@@ -32,6 +32,8 @@
# External IPv4 address, plaintext and ssl port
$conf{ip4} = $conf{ip4} or die "ERROR: botnow.conf: ip4";
+$conf{ip6} = $conf{ip6} or die "ERROR: botnow.conf: ip6";
+$conf{ip6subnet} = $conf{ip6subnet} or die "ERROR: botnow.conf: ip6subnet";
$conf{plainport} = $conf{plainport} || 1337;
$conf{sslport} = $conf{sslport} || 31337;
diff -ur botnow-old/makefile botnow/makefile
--- botnow-old/makefile Tue Jul 20 04:46:08 2021
+++ botnow/makefile Mon Jul 19 05:06:37 2021
@@ -48,7 +48,7 @@
pkg_add p5-DBI
pkg_add p5-DBD-SQLite
pkg_add sqlite3
- pkg_add p5-Class-DBI-SQLite-0.11p1
+ pkg_add p5-Class-DBI-SQLite
blowfish:
cc -o blowfish.o blowfish.c
diff -ur botnow-old/networks botnow/networks
--- botnow-old/networks Tue Jul 20 04:46:08 2021
+++ botnow/networks Mon Jul 19 05:06:46 2021
@@ -152,7 +152,7 @@
hackint irc.hackint.org +6697
hackthissite irc.hackthissite.org +7000
hazinem irc.hazinem.net 6667
-hybridirc irc.hybridirc.com ~6697
+hybridirc ipv6.hybridirc.com ~6697
icqchat irc.icq-chat.com +6697
insomnia irc.insomnia247.nl 6667
irc4fun irc.irc4fun.net ~6697
@@ -179,6 +179,7 @@
kalbim irc.kalbim.net 6667
kampungchat etnies6.ircd.link 6667
librairc irc.librairc.net ~6697
+linuxconsole linuxconsole.net ~6697
luatic irc.luatic.net 6667
magnet irc.shadowcat.co.uk 6667
malikania malikania.fr ~6697
Attachment:
20210720botnow.tgz
Description: application/tar-gz
Attachment:
signature.asc
Description: PGP signature