Skip to content

Instantly share code, notes, and snippets.

@mackee
Last active January 8, 2018 23:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mackee/10583799 to your computer and use it in GitHub Desktop.
Save mackee/10583799 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use constant {
GITHUB_ENDPOINT => 'https://github.com/%s.keys',
VULTR_ENDPOINT => 'https://api.vultr.com/v1/server/list'
};
use Getopt::Long qw/:config posix_default no_ignore_case bundling auto_help/;
use Pod::Usage qw/pod2usage/;
GetOptions(\my %opt, qw/
api_key=s
ip=s
user=s
/);
my @required_options = qw/api_key ip user/;
pod2usage(2) if grep {!exists $opt{$_}} @required_options;
use LWP::UserAgent;
use JSON qw/decode_json/;
use Net::OpenSSH;
use String::Random qw/random_string/;
my $ua = LWP::UserAgent->new;
my $github_key_url = sprintf(GITHUB_ENDPOINT, $opt{user});
my $github_response = $ua->get($github_key_url);
if (!$github_response->is_success) {
die $github_response->status_line;
}
my $public_key = $github_response->content;
my $vultr_response = $ua->get(VULTR_ENDPOINT . "?api_key=$opt{api_key}");
if (!$vultr_response->is_success) {
die $vultr_response->status_line;
}
my $json = decode_json $vultr_response->content;
my @target_hosts =
grep {
$_->{main_ip} eq $opt{ip} && $_->{status} eq 'active'
} values %$json;
if (scalar(@target_hosts) == 0) {
die $opt{ip} . 'is not found or inactive';
}
my $target_host = shift @target_hosts;
my $password = $target_host->{default_password};
my $ssh = Net::OpenSSH->new($opt{ip},
user => 'root',
password => $password,
master_opts => [
-o => "StrictHostKeyChecking=no",
-o => "UserKnownHostsFile=/dev/null"
],
);
$ssh->error and die "Couldn't establish SSH connection: ". $ssh->error;
my $user_password = crypt(random_string('ssssssss'), random_string('ss'));
if (!$ssh->test('id', $opt{user})) {
$ssh->system('useradd',
'-p', $user_password,
$opt{user}
) or die "remote command failed: " . $ssh->error;
}
$ssh->system('chsh',
'-s', '/bin/bash', $opt{user}
) or die "remote command failed: " . $ssh->error;
my $authorized_keys_path = "/home/$opt{user}/.ssh/authorized_keys";
$ssh->system('mkdir',
'-p', "/home/$opt{user}/.ssh/"
) or die "remote command failed: " . $ssh->error;
$ssh->system('chown',
'-R', "$opt{user}:$opt{user}",
"/home/$opt{user}"
) or die "remote command failed: " . $ssh->error;
$ssh->system(
{
stdin_data => $public_key
},
"cat > $authorized_keys_path"
) or die "remote command failed: " . $ssh->error;
$ssh->system('chown',
$opt{user}.':'.$opt{user},
$authorized_keys_path
) or die "remote command failed: " . $ssh->error;
$ssh->system('chmod',
'600',
$authorized_keys_path
) or die "remote command failed: " . $ssh->error;
print <<"SSH_CONFIG";
Host vultr
HostName $opt{ip}
User $opt{user}
Port 22
Identityfile ~/.ssh/id_rsa
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
SSH_CONFIG
=head1 SYNOPSIS
% vultr-add-rsa-key.pl --api_key=XXXX --ip=xx.xx.xx.xx --user=mackee
Options:
--api_key your api key. see https://my.vultr.com/settings/
--ip target ip address
--user your github account name
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment