From 94d2a08577b641a608a574f9b7c698357286146b Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Sun, 16 May 2021 22:20:26 -0700 Subject: [PATCH] Add support for entering an SSH key when creating a virtual server --- CHANGELOG | 2 ++ create-domain.pl | 39 ++++++++++++++++++++++ domain_form.cgi | 8 +++++ domain_setup.cgi | 28 ++++++++++++++++ help/sshkey.html | 19 +++++++++++ lang/en | 10 ++++++ virtual-server-lib-funcs.pl | 65 ++++++++++++++++++++++++++++++------- 7 files changed, 160 insertions(+), 11 deletions(-) create mode 100644 help/sshkey.html diff --git a/CHANGELOG b/CHANGELOG index 3ce628dfe..e1fde2df2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1619,3 +1619,5 @@ SSL certicates can now be generated and managed for virtual servers even when th Added the Cloud DNS Providers page, for configuring Virtualmin to use Route53 to host DNS rather than doing it locally. ---- Changes since 6.15 ---- PHP-FPM using socket files instead of TCP ports is now fully supported, using the modify-web API command. +---- Changes since 6.16 ---- +Added a field to the virtual server creation page to use an existing SSH key for logins, or generate a new key. diff --git a/create-domain.pl b/create-domain.pl index 359a91ac6..1b8eeb51c 100755 --- a/create-domain.pl +++ b/create-domain.pl @@ -360,6 +360,17 @@ package virtual_server; elsif ($a eq "--generate-ssl-cert") { $always_ssl = 1; } + elsif ($a eq "--generate-ssh-key") { + $sshmode = 1; + } + elsif ($a eq "--use-ssh-key") { + $sshmode = 2; + $sshkey = shift(@ARGV); + if ($sshkey =~ /^\//) { + $sshkey = &read_file_contents($sshkey); + } + $sshkey =~ /\S/ || &usage("--use-ssh-key must be followed by a key file or data"); + } elsif ($a eq "--multiline") { $multiline = 1; } @@ -867,6 +878,33 @@ package virtual_server; &$second_print($text{'setup_done'}); } +if ($sshmode == 1) { + # Generate and use a key + &$first_print($text{'setup_sshkey1'}); + ($sshkey, $err) = &create_domain_ssh_key(\%dom); + if (!$err) { + $err = &save_domain_ssh_pubkey(\%dom, $sshkey); + } + if ($err) { + &$second_print(&text('setup_esshkey', $err)); + } + else { + &$second_print($text{'setup_done'}); + } + } +elsif ($sshmode == 2) { + # Just use an existing key + &$first_print($text{'setup_sshkey2'}); + $sshkey =~ s/\r|\n/ /g; + $err = &save_domain_ssh_pubkey(\%dom, $sshkey); + if ($err) { + &$second_print(&text('setup_esshkey', $err)); + } + else { + &$second_print($text{'setup_done'}); + } + } + &virtualmin_api_log(\@OLDARGV, \%dom, $dom{'hashpass'} ? [ "pass" ] : [ ]); &run_post_actions_silently(); &unlock_domain_name($domain); @@ -954,6 +992,7 @@ sub usage print " [--mysql-server hostname]\n"; print " [--break-ssl-cert | --link-ssl-cert]\n"; print " [--generate-ssl-cert]\n"; +print " [--generate-ssh-key | --use-ssh-key file|data]\n"; exit(1); } diff --git a/domain_form.cgi b/domain_form.cgi index d08165d48..1daca1188 100755 --- a/domain_form.cgi +++ b/domain_form.cgi @@ -209,6 +209,14 @@ if (!$parentuser) { print &ui_table_row(&hlink($text{'form_pass'}, "password"), &new_password_input("vpass"), undef, \@tds); + + # SSH public key for Unix user + print &ui_table_row(&hlink($text{'form_sshkey'}, "sshkey"), + &ui_radio("sshkey_mode", 0, + [ [ 0, $text{'form_sshkey0'} ], + [ 1, $text{'form_sshkey1'} ], + [ 2, $text{'form_sshkey2'} ] ])."
\n". + &ui_textarea("sshkey", undef, 3, 60), undef, \@tds); } # Generate Javascript for template change diff --git a/domain_setup.cgi b/domain_setup.cgi index 12b5120d6..6d86700d0 100755 --- a/domain_setup.cgi +++ b/domain_setup.cgi @@ -500,6 +500,34 @@ if (!$dom{'alias'} && &domain_has_website(\%dom) && &$second_print($text{'setup_done'}); } +# Setup SSH public key if one was given +if ($in{'sshkey_mode'} == 1) { + # Generate a keypair for the user + &$first_print($text{'setup_sshkey1'}); + ($sshkey, $err) = &create_domain_ssh_key(\%dom); + if (!$err) { + $err = &save_domain_ssh_pubkey(\%dom, $sshkey); + } + if ($err) { + &$second_print(&text('setup_esshkey', $err)); + } + else { + &$second_print($text{'setup_done'}); + } + } +elsif ($in{'sshkey_mode'} == 2) { + # Use only the given public key + &$first_print($text{'setup_sshkey2'}); + $in{'sshkey'} =~ s/\r|\n/ /g; + $err = &save_domain_ssh_pubkey(\%dom, $in{'sshkey'}); + if ($err) { + &$second_print(&text('setup_esshkey', $err)); + } + else { + &$second_print($text{'setup_done'}); + } + } + &run_post_actions(); &unlock_domain_name($dname); &webmin_log("create", "domain", $dom{'dom'}, \%dom); diff --git a/help/sshkey.html b/help/sshkey.html new file mode 100644 index 000000000..b65607d4e --- /dev/null +++ b/help/sshkey.html @@ -0,0 +1,19 @@ +
SSH public key
+ +This field can be used to grant SSH access authenticated via a public key +to the new virtual server's Unix user. The options are :

+ +

+
No default key +
Don't setup an SSH key. Only logins with a password will be allowed.

+ +

Generate public and private keys +
Create a new SSH key pair for this virtual server, and allow logins using + that key. The server owner should copy the private key after creation.

+ +

Use public key below +
SSH logins will be allowed using the private key that corresponds to the + public key entered in the text box below.

+

+ +