mirror of
https://github.com/ovh/the-bastion.git
synced 2025-01-10 09:23:52 +08:00
115 lines
4.2 KiB
Perl
115 lines
4.2 KiB
Perl
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
|
package OVH::Bastion;
|
|
|
|
use common::sense;
|
|
|
|
use constant {MINIJAIL_PATH => "/bin/minijail0",};
|
|
|
|
sub jailify {
|
|
my %params = @_;
|
|
|
|
my $required = delete $params{'required'};
|
|
my $use_sudo = delete $params{'use_sudo'};
|
|
my $user = delete $params{'user'};
|
|
my $group = delete $params{'group'};
|
|
my $no_new_privs = delete $params{'no_new_privs'};
|
|
my $set_env = delete $params{'set_env'};
|
|
my $pid_ns = delete $params{'pid_ns'};
|
|
my $mount_mode = delete $params{'mount_mode'};
|
|
my $mount_ns = delete $params{'mount_ns'};
|
|
my $pivot_root = delete $params{'pivot_root'};
|
|
my $bind_mounts = delete $params{'bind_mounts'};
|
|
my $mounts = delete $params{'mounts'};
|
|
my $seccomp = delete $params{'seccomp'};
|
|
my $uts = delete $params{'uts'};
|
|
my $ld_preload = delete $params{'ld_preload'};
|
|
my $dev = delete $params{'dev'};
|
|
my $cmd = delete $params{'cmd'};
|
|
|
|
if (%params) {
|
|
|
|
# this is a coding error => warn(), this'll make any test passing through it automatically fail
|
|
warn("Spurious parameter passed to jailify(): " . join(", ", keys %params));
|
|
return R('ERR_INTERNAL', msg => "Spurious parameter passed to jailify()");
|
|
}
|
|
|
|
if (!$cmd || ref $cmd ne 'ARRAY') {
|
|
return R('ERR_INVALID_PARAMETER', msg => "Specified cmd is either missing or not an arrayref");
|
|
}
|
|
|
|
if (!-e -x OVH::Bastion::MINIJAIL_PATH) {
|
|
return R('ERR_INTERNAL', msg => "minijail not available, please warn your bastion administrator") if $required;
|
|
|
|
# not installed and not required? just return the @cmd untouched
|
|
return R('OK_NO_CHANGE', value => $cmd);
|
|
}
|
|
|
|
# we need to be root for several cases
|
|
if (($user || $group || $mount_ns || $pivot_root || $bind_mounts || $mounts) && ($> != 0) && !$use_sudo) {
|
|
|
|
# this is a coding error => warn(), this'll make any test passing through it automatically fail
|
|
warn(
|
|
'Jailify attempted with a feature needing root without being root ',
|
|
"\$user: ",
|
|
($user // "_undef_"),
|
|
"\$group: ",
|
|
($group // "_undef_"),
|
|
"\$mount_ns: ",
|
|
($mount_ns // "_undef_"),
|
|
"\$pivot_root: ",
|
|
($pivot_root // "_undef_"),
|
|
"\$bind_mounts: ",
|
|
($bind_mounts // "_undef_"),
|
|
"\$mounts: ",
|
|
($mounts // "_undef_"),
|
|
);
|
|
return R('ERR_INTERNAL', msg => "Bad use of jailify(), please warn your bastion administrator");
|
|
}
|
|
|
|
my @jailcmd;
|
|
if ($use_sudo) {
|
|
push @jailcmd, qw{ sudo -n -u root -- };
|
|
}
|
|
|
|
push @jailcmd, OVH::Bastion::MINIJAIL_PATH, "--logging=stderr";
|
|
push @jailcmd, "-u", $user if $user;
|
|
push @jailcmd, "-g", $group if $group;
|
|
push @jailcmd, "-n" if $no_new_privs;
|
|
push @jailcmd, "-v" if $mount_ns;
|
|
push @jailcmd, "-p" if $pid_ns;
|
|
push @jailcmd, "--uts" if $uts;
|
|
push @jailcmd, "-K$mount_mode" if $mount_mode;
|
|
push @jailcmd, "-d" if $dev;
|
|
push @jailcmd, "--child-ld-preload", $ld_preload if $ld_preload;
|
|
|
|
if ($pivot_root) {
|
|
return R('ERR_INVALID_PARAMETER', msg => "Specified pivot_root ($pivot_root) is not a directory") if !-d $pivot_root;
|
|
push @jailcmd, "-P", $pivot_root;
|
|
}
|
|
|
|
if ($seccomp) {
|
|
return R('ERR_INVALID_PARAMETER', msg => "Specified seccomp filter is not a file") if !-f -r $seccomp;
|
|
push @jailcmd, "-S", $seccomp;
|
|
}
|
|
|
|
if (defined $bind_mounts) {
|
|
return R('ERR_INVALID_PARAMETER', msg => "Specified bind_mounts is not an arrayref") if (ref $bind_mounts ne 'ARRAY');
|
|
push @jailcmd, "-b", $_ for (@$bind_mounts);
|
|
}
|
|
|
|
if (defined $mounts) {
|
|
return R('ERR_INVALID_PARAMETER', msg => "Specified mounts is not an arrayref") if (ref $mounts ne 'ARRAY');
|
|
push @jailcmd, "-k", $_ for (@$mounts);
|
|
}
|
|
|
|
if (defined $set_env) {
|
|
return R('ERR_INVALID_PARAMETER', msg => "Specified set_env is not an arrayref") if (ref $set_env ne 'ARRAY');
|
|
push @jailcmd, "--set-env", $_ for (@$set_env);
|
|
}
|
|
|
|
push @jailcmd, '--', @$cmd;
|
|
|
|
return R('OK', value => \@jailcmd);
|
|
}
|
|
|
|
1;
|