Skip to content

Commit

Permalink
Merge pull request #36 from containers/passphrase
Browse files Browse the repository at this point in the history
Go back to using the host's SSH keypair but avoid asking for passphrase more than once
  • Loading branch information
albertofaria authored Mar 18, 2024
2 parents 0bbb058 + caa1913 commit 066501d
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 14 deletions.
4 changes: 2 additions & 2 deletions scripts/exec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if [[ ! -e /crun-vm/ssh-successful ]]; then
for (( i = 0; i < 60; ++i )); do

set +e
output=$( __ssh "$1" </dev/null 2>&1 )
output=$( __ssh "$1" -o BatchMode=yes </dev/null 2>&1 )
exit_code=$?
set -e

Expand All @@ -32,7 +32,7 @@ if [[ ! -e /crun-vm/ssh-successful ]]; then

done

if (( exit_code != 0 )); then
if (( exit_code != 0 )) && ! grep -iqE "Permission denied" <<< "$output"; then
>&2 printf '%s\n' "$output"
exit "$exit_code"
fi
Expand Down
49 changes: 37 additions & 12 deletions src/commands/create/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub fn create(global_args: &liboci_cli::GlobalOpts, args: &liboci_cli::Create) -
set_up_extra_container_mounts_and_devices(&mut spec)?;
set_up_security(&mut spec);

set_up_first_boot_config(&spec, &mounts, &custom_options)?;
set_up_first_boot_config(&spec, &mounts, &custom_options, runtime_env)?;
set_up_libvirt_domain_xml(&spec, &base_vm_image_info, &mounts, &custom_options)?;

adjust_container_rlimits_and_resources(&mut spec);
Expand Down Expand Up @@ -499,8 +499,9 @@ fn set_up_first_boot_config(
spec: &oci_spec::runtime::Spec,
mounts: &Mounts,
custom_options: &CustomOptions,
env: RuntimeEnv,
) -> Result<()> {
let container_public_key = gen_container_ssh_key_pair(spec)?;
let container_public_key = get_container_ssh_key_pair(spec, env)?;

let config = FirstBootConfig {
hostname: spec.hostname().as_deref(),
Expand Down Expand Up @@ -528,22 +529,46 @@ fn set_up_first_boot_config(
}

/// Returns the public key for the container.
fn gen_container_ssh_key_pair(spec: &oci_spec::runtime::Spec) -> Result<String> {
///
/// This first attempts to use the current user's key pair, in case the VM does not support
/// cloud-init but the user injected their public key into it themselves.
fn get_container_ssh_key_pair(spec: &oci_spec::runtime::Spec, env: RuntimeEnv) -> Result<String> {
let ssh_path = spec.root_path()?.join("root/.ssh");

if !ssh_path.join("id_rsa.pub").exists() {
fs::create_dir_all(&ssh_path)?;

let status = Command::new("ssh-keygen")
.arg("-q")
.arg("-f")
.arg(ssh_path.join("id_rsa"))
.arg("-N")
.arg("")
.spawn()?
.wait()?;
let try_copy_user_key_pair = || -> Result<bool> {
if env != RuntimeEnv::Other {
// definitely not Podman, we're probably not running as the user that invoked the engine
return Ok(false);
}

if let Some(user_home_path) = home::home_dir() {
let user_ssh = user_home_path.join(".ssh");

if user_ssh.join("id_rsa.pub").is_file() && user_ssh.join("id_rsa").is_file() {
fs::copy(user_ssh.join("id_rsa.pub"), ssh_path.join("id_rsa.pub"))?;
fs::copy(user_ssh.join("id_rsa"), ssh_path.join("id_rsa"))?;
return Ok(true);
}
}

Ok(false)
};

ensure!(status.success(), "ssh-keygen failed");
if !try_copy_user_key_pair()? {
let status = Command::new("ssh-keygen")
.arg("-q")
.arg("-f")
.arg(ssh_path.join("id_rsa"))
.arg("-N")
.arg("")
.spawn()?
.wait()?;

ensure!(status.success(), "ssh-keygen failed");
}
}

Ok(fs::read_to_string(ssh_path.join("id_rsa.pub"))?)
Expand Down

0 comments on commit 066501d

Please sign in to comment.