the-bastion/bin/plugin/open/selfGenerateEgressKey

138 lines
4.1 KiB
Text
Raw Normal View History

2020-10-16 00:32:37 +08:00
#! /usr/bin/env perl
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
use common::sense;
use Term::ReadKey;
use File::Basename;
use lib dirname(__FILE__) . '/../../../lib/perl';
use OVH::Result;
use OVH::Bastion;
use OVH::Bastion::Plugin qw( :DEFAULT );
my ($algo, $size, $encrypted);
my $remainingOptions = OVH::Bastion::Plugin::begin(
argv => \@ARGV,
header => "generating a new key pair for your account",
options => {
"algo=s" => \$algo,
"size=i" => \$size,
"encrypted" => \$encrypted,
},
help => \&help,
);
sub help {
require Term::ANSIColor;
my $fnret = OVH::Bastion::get_supported_ssh_algorithms_list(way => 'egress');
my @algoList = @{$fnret->value};
my $algos = Term::ANSIColor::colored(uc join(' ', @algoList), 'green');
my $helpAlgoSize = '--algo rsa --size 4096';
if (grep { $_ eq 'ecdsa' } @algoList) {
$helpAlgoSize = '--algo ecdsa --size 521';
}
if (grep { $_ eq 'ed25519' } @algoList) {
$helpAlgoSize = '--algo ed25519';
}
osh_info <<"EOF";
Create a new egress public + private key pair. The private key will stay on your account on this bastion.
Usage: --osh $scriptName $helpAlgoSize [--encrypted]
--algo ALGO Specifies the algo of the key, either rsa, ecdsa or ed25519.
--size SIZE Specifies the size of the key to be generated.
For RSA, choose between 2048 and 8192 (4096 is good).
For ECDSA, choose either 256, 384 or 521.
For ED25519, size is always 256.
--encrypted if specified, a passphrase will be prompted for the new key
With the policy and SSH version on this bastion,
the following algorithms are supported: $algos
algo size strength speed compatibility
------- ---- ---------- -------- -----------------------
RSA 4096 good slow works everywhere
ECDSA 521 strong fast debian7+ (OpenSSH 5.7+)
ED25519 256 verystrong veryfast debian8+ (OpenSSH 6.5+)
EOF
return 0;
}
#
# code
#
my $fnret;
if (!$algo) {
help();
osh_exit 'ERR_MISSING_PARAMETER', "Parameter 'algo' is missing";
}
# check if algo is supported by system
$fnret = OVH::Bastion::get_supported_ssh_algorithms_list(way => 'egress');
my @algoList = @{$fnret->value};
my $ok = 0;
foreach (@algoList) {
$algo =~ /^\Q$_\E/ and $ok = 1;
}
if (not $ok) {
osh_debug($algo);
osh_debug(join(' ', @algoList));
osh_exit 'ERR_INVALID_ALGORITHM', "Only the following list of algorithms is allowed: " . join(' ', @algoList);
}
$size = 256 if (not $size and $algo eq 'ed25519');
2020-10-16 00:32:37 +08:00
$fnret = OVH::Bastion::is_allowed_algo_and_size(algo => $algo, size => $size, way => 'egress');
$fnret or osh_exit $fnret;
$fnret = OVH::Bastion::config('bastionName');
$fnret or osh_exit $fnret;
my $bastionName = $fnret->value;
my $passphrase = ''; # empty by default
if ($encrypted) {
print "Please enter a passphrase for your new personal bastion key (not echoed): ";
ReadMode('noecho');
chomp(my $pass1 = <STDIN>);
if (length($pass1) < 5) {
# ssh-keygen will refuse
print "\n";
osh_exit 'ERR_PASSPHRASE_TOO_SHORT', "Passphrase needs to be at least 5 chars";
}
print "\nPlease enter it again: ";
chomp(my $pass2 = <STDIN>);
print "\n";
ReadMode('restore');
if ($pass1 ne $pass2) {
osh_exit 'ERR_PASSPHRASE_MISMATCH', "Passphrases don't match, please try again";
}
$passphrase = $pass1;
}
osh_info "Generating your key, this might take a while...";
$fnret = OVH::Bastion::generate_ssh_key(
folder => OVH::Bastion::get_home_from_env()->value . '/.ssh',
prefix => 'private',
name => $self,
algo => $algo,
size => $size,
passphrase => $passphrase,
);
$fnret or osh_exit $fnret;
osh_info "You new key pair has been generated:\n";
$fnret = OVH::Bastion::get_ssh_pub_key_info(file => $fnret->value->{'file'} . ".pub", way => "egress");
$fnret or osh_exit $fnret;
my $key = $fnret->value;
$fnret = OVH::Bastion::get_bastion_ips();
$fnret or osh_exit $fnret;
$key->{'prefix'} = 'from="' . join(',', @{$fnret->value}) . '"';
OVH::Bastion::print_public_key(key => $key);
osh_ok($key);