Commit Diff


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);