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);
|
|
|
|
}
|
|
|
|
|
2020-11-23 05:05:45 +08:00
|
|
|
$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);
|