mirror of
https://github.com/ovh/the-bastion.git
synced 2025-01-08 00:12:10 +08:00
147 lines
5.9 KiB
Perl
Executable file
147 lines
5.9 KiB
Perl
Executable file
#! /usr/bin/env perl
|
|
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
|
use common::sense;
|
|
|
|
use File::Basename;
|
|
use lib dirname(__FILE__) . '/../../../lib/perl';
|
|
use OVH::Result;
|
|
use OVH::Bastion;
|
|
use OVH::Bastion::Plugin qw( :DEFAULT help );
|
|
|
|
my $remainingOptions = OVH::Bastion::Plugin::begin(
|
|
argv => \@ARGV,
|
|
header => "create a new bastion account",
|
|
options => {
|
|
'force-key-from=s' => \my $forceKeyFrom, # only to be used under root by the install script
|
|
'uid=i' => \my $uid,
|
|
'account=s' => \my $account,
|
|
'always-active' => \my $alwaysActive,
|
|
'pubKey|public-key=s' => \my $pubKey,
|
|
'comment=s' => \my $comment,
|
|
'uid-auto' => \my $uidAuto,
|
|
'osh-only' => \my $oshOnly,
|
|
'max-inactive-days=i' => \my $maxInactiveDays,
|
|
'immutable-key' => \my $immutableKey,
|
|
'no-key' => \my $noKey,
|
|
'ttl=s' => \my $ttl,
|
|
},
|
|
helptext => <<'EOF',
|
|
Create a new bastion account
|
|
|
|
Usage: --osh SCRIPT_NAME --account ACCOUNT <--uid UID|--uid-auto> [OPTIONS]
|
|
|
|
--account NAME Account name to create, NAME must contain only valid UNIX account name characters
|
|
--uid UID Account system UID, also see --uid-auto
|
|
--uid-auto Auto-select an UID from the allowed range (the upper available one will be used)
|
|
--always-active This account's activation won't be challenged on connection, even if the bastion is globally
|
|
configured to check for account activation
|
|
--osh-only This account will only be able to use ``--osh`` commands, and can't connect anywhere through the bastion
|
|
--max-inactive-days DAYS Set account expiration policy, overriding the global bastion configuration 'accountMaxInactiveDays',
|
|
setting this option to zero disables account expiration.
|
|
--immutable-key Deny any subsequent modification of the account key (selfAddKey and selfDelKey are denied)
|
|
--comment '"STRING"' An optional comment when creating the account. Quote it twice as shown if you're under a shell.
|
|
--public-key '"KEY"' Account public SSH key to deposit on the bastion, if not present,
|
|
you'll be prompted interactively for it. Quote it twice as shown if your're under a shell.
|
|
--no-key Don't prompt for an SSH key, no ingress public key will be installed
|
|
--ttl SECONDS|DURATION Time after which the account will be deactivated (amount of seconds, or duration string such as "4d12h15m")
|
|
EOF
|
|
);
|
|
|
|
# ugly hack for space-enabled parameter
|
|
# XXX should be removed, double quoting fixes the problem, but keep it for compatibility
|
|
if (ref $remainingOptions eq 'ARRAY' and @$remainingOptions) {
|
|
$pubKey .= " " . join(" ", @$remainingOptions);
|
|
}
|
|
|
|
#
|
|
# code
|
|
#
|
|
my $fnret;
|
|
|
|
#
|
|
# params check
|
|
#
|
|
|
|
if (!$account) {
|
|
help();
|
|
osh_exit 'ERR_MISSING_PARAMETER', "Missing mandatory parameter 'account'";
|
|
}
|
|
|
|
if (!defined $uid && !$uidAuto) {
|
|
help();
|
|
osh_exit 'ERR_MISSING_PARAMETER', "Missing mandatory parameter --uid or --uid-auto";
|
|
}
|
|
|
|
# quicky ensure these params are not pure bullshit (real check is done by helper script)
|
|
if ($account !~ /^[a-z0-9._-]+$/i) {
|
|
osh_exit 'ERR_INVALID_PARAMETER', "Parameter 'account' seems invalid";
|
|
}
|
|
|
|
if (defined $ttl) {
|
|
$fnret = OVH::Bastion::is_valid_ttl(ttl => $ttl);
|
|
$fnret or osh_exit $fnret;
|
|
$ttl = $fnret->value->{'seconds'};
|
|
}
|
|
|
|
if (defined $uid && $uid == 0) {
|
|
osh_exit 'ERR_IN_YOUR_DREAMS', "Tu l'as vu ?";
|
|
}
|
|
|
|
if (defined $uid && $uidAuto) {
|
|
help();
|
|
osh_exit 'ERR_INCOMPATIBLE_PARAMETERS', "Can't use --uid and --uid-auto at the same time";
|
|
}
|
|
|
|
if (defined $pubKey && $noKey) {
|
|
help();
|
|
osh_exit 'ERR_INCOMPATIBLE_PARAMETERS', "Can't use --public-key and --no-key at the same time";
|
|
}
|
|
|
|
if (defined $maxInactiveDays && $maxInactiveDays < 0) {
|
|
help();
|
|
osh_exit 'ERR_INVALID_PARAMETER', "Expected a >= 0 amount of days for --max-inactive-days";
|
|
}
|
|
|
|
if (!$pubKey && !$noKey) {
|
|
$fnret = OVH::Bastion::get_supported_ssh_algorithms_list(way => 'ingress');
|
|
$fnret or osh_exit $fnret;
|
|
my @algoList = @{$fnret->value};
|
|
my $algos = join(' ', @algoList);
|
|
osh_info "Please paste the SSH key you want to add. This bastion supports the following algorithms:\n";
|
|
if (grep { 'ed25519' eq $_ } @algoList) {
|
|
osh_info "ED25519: strongness[#####] speed[#####], use `ssh-keygen -t ed25519' to generate one";
|
|
}
|
|
if (grep { 'ecdsa' eq $_ } @algoList) {
|
|
osh_info "ECDSA : strongness[####.] speed[#####], use `ssh-keygen -t ecdsa -b 521' to generate one";
|
|
}
|
|
if (grep { 'rsa' eq $_ } @algoList) {
|
|
osh_info "RSA : strongness[###..] speed[#....], use `ssh-keygen -t rsa -b 4096' to generate one";
|
|
}
|
|
osh_info "\nIn any case, don't save it without a passphrase (your paste won't be echoed).";
|
|
$pubKey = <STDIN>;
|
|
}
|
|
|
|
if (!$noKey) {
|
|
$fnret = OVH::Bastion::is_valid_public_key(pubKey => $pubKey, way => 'ingress');
|
|
$fnret or osh_exit $fnret;
|
|
}
|
|
|
|
#
|
|
# Now create it
|
|
#
|
|
my @command = qw{ sudo -n -u root -- /usr/bin/env perl -T };
|
|
push @command, $OVH::Bastion::BASEPATH . '/bin/helper/osh-accountCreate';
|
|
push @command, "--type", "normal";
|
|
push @command, "--account", $account;
|
|
push @command, "--pubKey", $pubKey if !$noKey;
|
|
push @command, "--always-active" if $alwaysActive;
|
|
push @command, "--comment", $comment if $comment;
|
|
push @command, "--uid", $uid if defined $uid;
|
|
push @command, "--osh-only", if $oshOnly;
|
|
push @command, "--max-inactive-days", $maxInactiveDays if defined $maxInactiveDays;
|
|
push @command, "--uid-auto" if $uidAuto;
|
|
push @command, "--immutable-key" if $immutableKey;
|
|
push @command, '--ttl', $ttl if $ttl;
|
|
push @command, '--force-key-from', $forceKeyFrom if ($forceKeyFrom && $< == 0 && $> == 0); # only to be used under root by the install script
|
|
|
|
osh_exit OVH::Bastion::helper(cmd => \@command);
|