Preliminary server chroot installation
Configures a chroot with Perl and bin/pgen-server to run a shell. ssh to 'pgen@localhost' successful shows pgen-server test message then logs out. 'add_key' and 'remove_server' functions also work. Recursive path builder function 'dig_dirs' also works well within the latter.
This commit is contained in:
parent
aedd59b759
commit
e3bdcdb5ae
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
print("Testing server\n");
|
|
@ -0,0 +1,218 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
our $server_dir = '/var/pgen';
|
||||||
|
use File::Which;
|
||||||
|
|
||||||
|
if (scalar(@ARGV) != 1) {
|
||||||
|
usage("Requires exactly 1 argument:");
|
||||||
|
} elsif ($ARGV[0] eq '-h' || $ARGV[0] eq '--help') {
|
||||||
|
usage("Usage: $0 <option>");
|
||||||
|
} elsif ($ARGV[0] eq 'server') {
|
||||||
|
if (-d $server_dir) {
|
||||||
|
print("Installation appears to already exist. Would you like it to be removed and
|
||||||
|
replaced? All existing password information will be lost. ");
|
||||||
|
my $selection;
|
||||||
|
do {
|
||||||
|
print("[y/N]? ");
|
||||||
|
$selection = <STDIN>;
|
||||||
|
chomp($selection);
|
||||||
|
} while (!defined($selection) || $selection !~ m/^[yYnN]?$/);
|
||||||
|
unless ($selection eq 'y' || $selection eq 'Y') {
|
||||||
|
die("Abandoning installation\n");
|
||||||
|
}
|
||||||
|
remove_server();
|
||||||
|
}
|
||||||
|
install_server();
|
||||||
|
} elsif ($ARGV[0] eq 'client') {
|
||||||
|
install_client();
|
||||||
|
} elsif ($ARGV[0] eq 'remove') {
|
||||||
|
my %removed = (
|
||||||
|
'server' => undef,
|
||||||
|
'client' => undef
|
||||||
|
);
|
||||||
|
if (detect_server()) {
|
||||||
|
$removed{'server'} = remove_server();
|
||||||
|
}
|
||||||
|
if (detect_client()) {
|
||||||
|
$removed{'client'} = remove_client();
|
||||||
|
}
|
||||||
|
foreach (keys(%removed)) {
|
||||||
|
if (defined($removed{$_})) {
|
||||||
|
if ($removed{$_}) {
|
||||||
|
print("Received error '$removed{$_}' while removing $_\n");
|
||||||
|
} else {
|
||||||
|
print("Successfully removed $_\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elsif ($ARGV[0] eq 'add') {
|
||||||
|
add_key();
|
||||||
|
} else {
|
||||||
|
usage("Invalid argument '$ARGV[0]'. Requires one of:");
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
sub detect_server
|
||||||
|
{
|
||||||
|
my $dir = (getpwnam('pgen'))[7] || return undef;
|
||||||
|
if (-d $dir) {
|
||||||
|
return($dir);
|
||||||
|
}
|
||||||
|
return(undef);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub detect_client
|
||||||
|
{
|
||||||
|
return(which('pgen'));
|
||||||
|
}
|
||||||
|
|
||||||
|
sub install_server
|
||||||
|
{
|
||||||
|
my $perl = which('perl') || die "Missing dependency: perl\n";
|
||||||
|
chomp($perl);
|
||||||
|
my ($perl_dir) = $perl =~ m/^((?:\/[^\/]*)*)\/perl$/;
|
||||||
|
my @perl_path = ( $server_dir );
|
||||||
|
foreach (split('/',$perl_dir)) {
|
||||||
|
unless($_ eq '') {
|
||||||
|
if (scalar(@perl_path)) {
|
||||||
|
$_ = $perl_path[scalar(@perl_path)-1].'/'.$_;
|
||||||
|
}
|
||||||
|
push(@perl_path,$_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (@perl_path, $server_dir."/.ssh", $server_dir."/bin", $server_dir."/lib", $server_dir."/lib64") {
|
||||||
|
print "Creating directory '$_'\n";
|
||||||
|
mkdir($_) || die "Failed to mkdir '$_': $!\n";
|
||||||
|
}
|
||||||
|
use File::Copy;
|
||||||
|
print("Installing Perl...\n");
|
||||||
|
copy($perl,"${server_dir}${perl}");
|
||||||
|
chmod(0755, "${server_dir}${perl}");
|
||||||
|
my $libs = `ldd ${server_dir}${perl}`;
|
||||||
|
foreach (split("\n",$libs)) {
|
||||||
|
if ($_ =~ m#^\s+([^\ ]+)\ =>\ (\/[^\/]+)((?:\/[^\/]*)*)\/([^\/]+) \(.*#) {
|
||||||
|
print "Copying ${2}${3}/${4} to ${server_dir}${2}/${4}\n";
|
||||||
|
copy("${2}${3}/${4}","${server_dir}${2}/${4}");
|
||||||
|
} elsif ($_ =~ m#^\s+(\/[^\/]+)((?:\/[^\/]*)*)\/([^\/]+) \(.*#) {
|
||||||
|
print "Copying ${1}${2}/${3} to ${server_dir}${1}/${3}\n";
|
||||||
|
copy("${1}${2}/${3}","${server_dir}${1}/${3}");
|
||||||
|
} else {
|
||||||
|
print "skipping $_\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my $src = $0;
|
||||||
|
$src =~ s/(.*)\/([^\/]*)/$1\/bin\/pgen-server/;
|
||||||
|
print("Installing $src to ${server_dir}/bin/pgen\n");
|
||||||
|
copy($src,"${server_dir}/bin/pgen") || die("Failed to install: $!\n");
|
||||||
|
chmod(0755, "${server_dir}/bin/pgen");
|
||||||
|
print("Configuring user 'pgen'\n");
|
||||||
|
system("useradd -d $server_dir pgen");
|
||||||
|
system("usermod -s $server_dir/bin/pgen pgen");
|
||||||
|
add_key();
|
||||||
|
print("Server installation complete\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub install_client
|
||||||
|
{
|
||||||
|
if (detect_client()) {
|
||||||
|
die("Client is already installed. If necessary, uninstall it with 'remove'\n");
|
||||||
|
}
|
||||||
|
print("TODO: Here I would install the client\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub remove_server
|
||||||
|
{
|
||||||
|
if (detect_server()) {
|
||||||
|
system("userdel pgen");
|
||||||
|
}
|
||||||
|
my @paths;
|
||||||
|
my $paths_ref = \@paths;
|
||||||
|
dig_dirs($paths_ref, $server_dir);
|
||||||
|
unless (scalar(@paths)) {
|
||||||
|
die("No chroot installation present at $server_dir\n");
|
||||||
|
}
|
||||||
|
while (scalar(@paths)) {
|
||||||
|
my $target = pop(@paths);
|
||||||
|
print "Removing $target...\n";
|
||||||
|
if (-d $target) {
|
||||||
|
rmdir($target) || die("Failed to remove directory '$target': $!\n");
|
||||||
|
} else {
|
||||||
|
unlink($target) || die("Failed to delete '$target': $!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub dig_dirs
|
||||||
|
{
|
||||||
|
my $paths_ref = shift;
|
||||||
|
my $path = shift;
|
||||||
|
unless (-e $path) {
|
||||||
|
return(undef);
|
||||||
|
}
|
||||||
|
if ($path =~ m/\/\.\.?$/) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
push(@$paths_ref, $path);
|
||||||
|
foreach (glob("$path/*"), glob("$path/.*")) {
|
||||||
|
if ($path =~ m/\/\.\.?$/) {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
if (-d $_) {
|
||||||
|
dig_dirs($paths_ref,$_);
|
||||||
|
} else {
|
||||||
|
push(@$paths_ref, $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub remove_client
|
||||||
|
{
|
||||||
|
unless (detect_client()) {
|
||||||
|
return "Client is not installed.\n";
|
||||||
|
}
|
||||||
|
print("TODO: Here I would remove the client\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub add_key
|
||||||
|
{
|
||||||
|
unless (detect_server()) {
|
||||||
|
die("This must be run on a host with the server installed");
|
||||||
|
}
|
||||||
|
my $file = "$server_dir/.ssh/authorized_keys";
|
||||||
|
my $msg = "Paste the SSH public key of the user. 'Q' to";
|
||||||
|
if (-e $file) {
|
||||||
|
print("Adding new user. $msg abort ");
|
||||||
|
} else {
|
||||||
|
print("Initializing with first user. $msg skip ");
|
||||||
|
}
|
||||||
|
my $key;
|
||||||
|
do {
|
||||||
|
print("[<key>/Q]: ");
|
||||||
|
$key = <STDIN>;
|
||||||
|
chomp($key);
|
||||||
|
} while (!defined($key) || ($key ne 'Q' && $key ne 'q' && $key !~ m/^ssh\-(dsa|ecdsa|ecdsa\sk|ed25519|ed25519-sk|rsa)\ [a-zA-Z0-9\+\/]{50,}/));
|
||||||
|
open(my $fh, '>>', $file) || die("Failed to open '$file': $!\n");
|
||||||
|
unless ($key eq 'Q' && $key ne 'q') {
|
||||||
|
print $fh $key."\n";
|
||||||
|
}
|
||||||
|
close($fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub usage
|
||||||
|
{
|
||||||
|
my $error = shift;
|
||||||
|
if (!defined($error)) {
|
||||||
|
$error = "Unknown failure. Try running with one of these options:";
|
||||||
|
}
|
||||||
|
die($error . "
|
||||||
|
server - install server application
|
||||||
|
client - install client application
|
||||||
|
remove - uninstall client and server (as necessary)
|
||||||
|
add - add a user key (SSH public key)\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
Loading…
Reference in New Issue