commit 1c2d62de0973a10a30d4bae5405037b32a47af5c from: jrmu date: Tue Dec 21 06:15:21 2021 UTC Import sources commit - /dev/null commit + 1c2d62de0973a10a30d4bae5405037b32a47af5c blob - /dev/null blob + 48265248e99b9921d429b4721ec3eef9a0c0749e (mode 644) --- /dev/null +++ install.pl @@ -0,0 +1,160 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use OpenBSD::Pledge; +use OpenBSD::Unveil; +use Data::Dumper; +use File::Copy qw(copy); + +my $vmconf = "/etc/vm.conf"; +my $zonedir = "/var/nsd/zones/master/"; +my $hostname = "host.oddprotocol.org"; +my $ipv4path = "/home/error/ipv4s"; +my @ipv4s; +if (!(-s "$ipv4path")) { + print "No IPv4 addresses in $ipv4path!\n"; + die; +} else { + @ipv4s = readarray($ipv4path); +} + +`doas chmod -R g+w $zonedir`; + +# Read from filename and return array of lines without trailing newlines +sub readarray { + my ($filename) = @_; + open(my $fh, '<', $filename) or die "Could not read file '$filename' $!"; + chomp(my @lines = <$fh>); + close $fh; + return @lines; +} + +# Read from filename and return as string +sub readstr { + my ($filename) = @_; + open my $fh, '<', $filename or die "Could not read file '$filename' $!"; + my $str = do { local $/; <$fh> }; + close $fh; + return $str; +} + +# Write str to filename +sub writefile { + my ($filename, $str) = @_; + open(my $fh, '>', "$filename") or die "Could not write to $filename"; + print $fh $str; + close $fh; +} + +# Append str to filename +sub appendfile { + my ($filename, $str) = @_; + open(my $fh, '>>', "$filename") or die "Could not append to $filename"; + print $fh $str; + close $fh; +} + +sub date { + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); + my $localtime = sprintf("%04d%02d%02d", $year+1900, $mon+1, $mday); + return $localtime; +} + +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 @lines = readarray($filename); + foreach my $line (@lines) { + # increment the zone's serial number + if ($line =~ /(\d{8})(\d{2})((\s+\d+){4}\s*\))/) { + my $date = date(); + my $serial = 0; + if ($date <= $1) { $serial = $2+1; } + $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; + } + # trailing newline necessary + writefile("$filename.bak", join("\n", @lines)."\n"); + copy "$filename.bak", $filename; + if (system("doas -u _nsd nsd-control reload")) { + return 0; + } else { + return 1; + } +} + +# create A and AAAA records for subdomain, set the rDNS, +# and return the new ipv6 address +sub nextdns { + my ($subdomain) = @_; + my $ipv4 = shift(@ipv4s); + my $ipv6; + my $fqdn = "$subdomain.$hostname"; + if ($ipv4 =~ /^[0-9]+\.[0-9]+\.[0-9]+\.([0-9]+)$/) { + $ipv6 = "2602:fccf:1:1".sprintf("%03d",$1)."::"; + } + writefile($ipv4path, join("\n", @ipv4s)); + my $success = setdns($fqdn, $ipv4) && setdns($fqdn, $ipv6) && setdns("ns1.$fqdn", $ipv4) && setdns("ns2.$fqdn", $ipv4); + return $success; +} + +sub createshell { + my ($username, $password) = @_; + print "Username: $username\n"; + print "Password: $password\n"; + system "doas groupadd $username"; + system "doas adduser -batch $username $username $username `encrypt $password`"; + system "doas usermod -G vmdusers $username"; + system "doas chmod -R o-rwx /home/$username"; + system "doas su -l $username -c \"vmctl create -s 20G $username.qcow2\""; + print "VM created for $username!\n"; + my @vmconf = readarray($vmconf); + my $lladdr; + foreach my $line (@vmconf) { + if ($line =~ /lladdr (.*)/) { + $lladdr = $1; + } + } + if (defined($lladdr) && $lladdr =~ /([0-9a-fA-F]{2})$/) { + $lladdr = $`.($1+1); + } + my $block = <<"EOF"; +vm "$username" { + owner $username + memory 1024M + cdrom "/home/iso/install70.iso" + disk /home/$username/$username.qcow2 + interface { + locked lladdr $lladdr + switch "switch0" + } +} +EOF + appendfile($vmconf, $block); + `doas vmctl reload`; +} + +my $nargs = $#ARGV + 1; +if ($nargs != 1) { + print "\nUsage: install.pl username\n"; + exit; +} +my $username = $ARGV[0]; +my $password = join'', map +(0..9,'a'..'z','A'..'Z')[rand(10+26*2)], 1..12; + +createshell($username, $password); +nextdns($username);