[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