Skip to content

Commit

Permalink
install: manually label {/etc/fstab,tmpfile.d/bootc-root-ssh.conf}
Browse files Browse the repository at this point in the history
Right now bootc supports an experimental install from a non-selinux
host when using the `BOOTC_SKIP_SELINUX_HOST_CHECK=1` option.

This is nice and works relatively well. However files written
during the install like /etc/fstab or the tmpfiles.dfile
in /etc/tmpfile.d/bootc-root-ssh.conf must be labeled too.

This commit adds a (rather crude) manual way to do this.

Closes containers#362

Signed-off-by: Michael Vogt <[email protected]>
  • Loading branch information
mvo5 committed Mar 15, 2024
1 parent ac17000 commit da70509
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
11 changes: 10 additions & 1 deletion lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ async fn initialize_ostree_root_from_self(
let root = rootfs_dir
.open_dir(path.as_str())
.context("Opening deployment dir")?;
let root_path = &rootfs.join(&path.as_str());
let mut f = {
let mut opts = cap_std::fs::OpenOptions::new();
root.open_with("etc/fstab", opts.append(true).write(true).create(true))
Expand All @@ -644,8 +645,16 @@ async fn initialize_ostree_root_from_self(
}
f.flush()?;

let fstab_path = root_path.join("etc/fstab");
state.lsm_label(&fstab_path, "/etc/fstab".into(), false)?;

if let Some(contents) = state.root_ssh_authorized_keys.as_deref() {
osconfig::inject_root_ssh_authorized_keys(&root, contents)?;
osconfig::inject_root_ssh_authorized_keys(
&root,
&root_path,
|target, path, recurse| state.lsm_label(target, path, recurse),
contents,
)?;
}

let uname = rustix::system::uname();
Expand Down
45 changes: 43 additions & 2 deletions lib/src/install/osconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ const ETC_TMPFILES: &str = "etc/tmpfiles.d";
const ROOT_SSH_TMPFILE: &str = "bootc-root-ssh.conf";

#[context("Injecting root authorized_keys")]
pub(crate) fn inject_root_ssh_authorized_keys(root: &Dir, contents: &str) -> Result<()> {
pub(crate) fn inject_root_ssh_authorized_keys<F>(
root: &Dir,
root_path: &Utf8Path,
lsm_label_fn: F,
contents: &str,
) -> Result<()>
where
F: Fn(&Utf8Path, &Utf8Path, bool) -> Result<()>,
{
// While not documented right now, this one looks like it does not newline wrap
let b64_encoded = ostree_ext::glib::base64_encode(contents.as_bytes());
// See the example in https://systemd.io/CREDENTIALS/
Expand All @@ -18,20 +26,53 @@ pub(crate) fn inject_root_ssh_authorized_keys(root: &Dir, contents: &str) -> Res
root.create_dir_all(tmpfiles_dir)?;
let target = tmpfiles_dir.join(ROOT_SSH_TMPFILE);
root.atomic_write(&target, &tmpfiles_content)?;

let as_path = Utf8Path::new(ETC_TMPFILES).join(ROOT_SSH_TMPFILE);
lsm_label_fn(
&root_path.join(&as_path),
&Utf8Path::new("/").join(&as_path),
false,
)?;

println!("Injected: {target}");
Ok(())
}

#[test]
fn test_inject_root_ssh() -> Result<()> {
use camino::Utf8PathBuf;
use std::cell::Cell;

let fake_lsm_label_called = Cell::new(0);
let fake_lsm_label = |target: &Utf8Path, as_path: &Utf8Path, recurse: bool| -> Result<()> {
assert_eq!(
target,
format!("/root/path/etc/tmpfiles.d/{ROOT_SSH_TMPFILE}")
);
assert_eq!(as_path, format!("/etc/tmpfiles.d/{ROOT_SSH_TMPFILE}"));
assert_eq!(recurse, false);

fake_lsm_label_called.set(fake_lsm_label_called.get() + 1);
Ok(())
};

let root_path = &Utf8PathBuf::from("/root/path");
let root = &cap_std_ext::cap_tempfile::TempDir::new(cap_std::ambient_authority())?;

inject_root_ssh_authorized_keys(root, "ssh-ed25519 ABCDE example@demo\n").unwrap();
inject_root_ssh_authorized_keys(
root,
root_path,
fake_lsm_label,
"ssh-ed25519 ABCDE example@demo\n",
)
.unwrap();

let content = root.read_to_string(format!("etc/tmpfiles.d/{ROOT_SSH_TMPFILE}"))?;
assert_eq!(
content,
"f~ /root/.ssh/authorized_keys 600 root root - c3NoLWVkMjU1MTkgQUJDREUgZXhhbXBsZUBkZW1vCg==\n"
);
assert_eq!(fake_lsm_label_called, 1.into());

Ok(())
}

0 comments on commit da70509

Please sign in to comment.