new guest_api working
This commit is contained in:
parent
e212e9a99c
commit
f9781c659b
@ -15,8 +15,8 @@ use std::{
|
||||
io::{BufReader, Read},
|
||||
};
|
||||
|
||||
const CRT_FILE: &str = "/tmp/certs/guest_api.crt";
|
||||
const KEY_FILE: &str = "/tmp/certs/guest_api.key";
|
||||
const CRT_FILE: &str = "/tmp/certs/dtrfs_api.crt";
|
||||
const KEY_FILE: &str = "/tmp/certs/dtrfs_api.key";
|
||||
const CMDLINE_FILE: &str = "/proc/cmdline";
|
||||
|
||||
lazy_static! {
|
||||
@ -94,8 +94,8 @@ async fn post_install_form(req: HttpRequest, form: web::Form<InstallForm>) -> Ht
|
||||
return HttpResponse::BadRequest().body(format!("Signature verification failed: {}", e));
|
||||
};
|
||||
match os::encrypt_and_install_os(&form.url, &form.sha, &form.keyfile) {
|
||||
Ok(()) => HttpResponse::Ok().body("Successfully installed OS"),
|
||||
Err(e) => HttpResponse::BadRequest().body(format!("{e:?}")),
|
||||
Ok(s) => HttpResponse::Ok().body(s),
|
||||
Err(e) => HttpResponse::InternalServerError().body(format!("{e:?}")),
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +179,15 @@ fn load_rustls_config() -> rustls::ServerConfig {
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
os::try_hot_keyfile().unwrap();
|
||||
match os::try_hot_keyfile() {
|
||||
Ok(_) => {
|
||||
println!("Hot decryption successful. Booting OS...");
|
||||
return Ok(());
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Hot decryption failed: {e:?}");
|
||||
}
|
||||
}
|
||||
let config = load_rustls_config();
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
|
@ -11,10 +11,15 @@ use std::{
|
||||
const SNP_KEYFILE_PATH: &str = "/tmp/detee_snp_keyfile";
|
||||
const BACKUP_KEYFILE_PATH: &str = "/tmp/detee_backup_keyfile";
|
||||
|
||||
pub fn encrypt_and_install_os(install_url: &str, install_sha: &str, keyfile: &str) -> Result<()> {
|
||||
pub fn encrypt_and_install_os(
|
||||
install_url: &str,
|
||||
install_sha: &str,
|
||||
keyfile: &str,
|
||||
) -> Result<String> {
|
||||
let binary_keyfile = BASE64_URL_SAFE.decode(keyfile)?;
|
||||
std::fs::write(BACKUP_KEYFILE_PATH, binary_keyfile)?;
|
||||
let install_result = Command::new("install_os.sh")
|
||||
// this path is hardcoded also in the initrd creation script
|
||||
let install_result = Command::new("/usr/lib/dtrfs/install_os.sh")
|
||||
.env("INSTALL_URL", install_url)
|
||||
.env("INSTALL_SHA", install_sha)
|
||||
.env("SNP_KEY_FILE", SNP_KEYFILE_PATH)
|
||||
@ -23,13 +28,20 @@ pub fn encrypt_and_install_os(install_url: &str, install_sha: &str, keyfile: &st
|
||||
|
||||
if !install_result.status.success() {
|
||||
return Err(anyhow!(
|
||||
"Could not install OS.\nstdout:{:?}\nstderr:\n{:?}",
|
||||
install_result.stdout,
|
||||
install_result.stderr
|
||||
"OS installation script failed.\nScript stdout:\n{}\nScript stderr:\n{}",
|
||||
String::from_utf8(install_result.stdout)
|
||||
.unwrap_or("Could not grab stdout from installation script.".to_string()),
|
||||
String::from_utf8(install_result.stderr)
|
||||
.unwrap_or("Could not grab stderr from installation script.".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(format!(
|
||||
"Successfully installed OS. Script stdout:\n{}\nScript stderr:\n{}",
|
||||
String::from_utf8(install_result.stdout)
|
||||
.unwrap_or("Could not grab stdout from installation script.".to_string()),
|
||||
String::from_utf8(install_result.stderr)
|
||||
.unwrap_or("Could not grab stderr from installation script.".to_string()),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn try_hot_keyfile() -> Result<()> {
|
||||
@ -46,6 +58,24 @@ pub fn try_backup_keyfile(keyfile: &str) -> Result<String> {
|
||||
Ok("Succesfully mounted /mnt using backup keyfile.".to_string())
|
||||
}
|
||||
|
||||
fn decrypt_and_mount(keyfile_path: &str) -> Result<()> {
|
||||
let decryption_result = Command::new("cryptsetup")
|
||||
.arg("open")
|
||||
.arg("--key-file")
|
||||
.arg(keyfile_path)
|
||||
.arg("/dev/vda1")
|
||||
.arg("root")
|
||||
.output()?;
|
||||
if !decryption_result.status.success() {
|
||||
return Err(anyhow!("Could not decrypt disk."));
|
||||
}
|
||||
let mount_result = Command::new("mount").arg("/dev/mapper/root").arg("/mnt").output()?;
|
||||
if !mount_result.status.success() {
|
||||
return Err(anyhow!("Could not mount /dev/mapper/root to /mnt"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn replace_hot_keyfile() -> Result<String> {
|
||||
let _delete_old_keyfile = Command::new("cryptsetup")
|
||||
.arg("luksKillSlot")
|
||||
@ -72,24 +102,6 @@ pub fn replace_hot_keyfile() -> Result<String> {
|
||||
Ok("Succesfully replaced hot keyfile using SNP KDF.".to_string())
|
||||
}
|
||||
|
||||
fn decrypt_and_mount(keyfile_path: &str) -> Result<()> {
|
||||
let decryption_result = Command::new("cryptsetup")
|
||||
.arg("open")
|
||||
.arg("--key-file")
|
||||
.arg(keyfile_path)
|
||||
.arg("/dev/vda1")
|
||||
.arg("root")
|
||||
.output()?;
|
||||
if !decryption_result.status.success() {
|
||||
return Err(anyhow!("Could not decrypt disk."));
|
||||
}
|
||||
let mount_result = Command::new("mount").arg("/dev/mapper/root").arg("/mnt").output()?;
|
||||
if !mount_result.status.success() {
|
||||
return Err(anyhow!("Could not mount /dev/mapper/root to /mnt"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_ssh_key(key: &str) -> Result<()> {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
if !Path::new("/mnt/etc/os-release").try_exists().is_ok_and(|found| found == true) {
|
||||
|
@ -23,7 +23,7 @@ install_binary $(which mkfs.ext4)
|
||||
install_binary $(which fsarchiver)
|
||||
install_kmod
|
||||
install_busybox
|
||||
install_guest_api
|
||||
install_dtrfs_api
|
||||
|
||||
echo_cyan "Installing scripts..."
|
||||
install_init_script
|
||||
|
@ -10,9 +10,6 @@ script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
# choose a kernel if you don't want to use the active one
|
||||
[[ -n "$KERNEL" ]] ||
|
||||
export KERNEL="$(uname -r)"
|
||||
# this is the DeTEE Guest API that allows you to control the initrd
|
||||
[[ -n "$GUEST_API_URL" ]] ||
|
||||
export GUEST_API_URL="https://gitea.detee.cloud/ghe0/stuff/releases/download/v0.0.0/guest_api.zst"
|
||||
# this will allow you to grab modules from the machine where the installer is running
|
||||
[[ -n "$GRAB_LOCAL_MODS" ]] ||
|
||||
export GRAB_LOCAL_MODS="no"
|
||||
|
@ -32,9 +32,8 @@ install_build_deps() {
|
||||
|
||||
create_dirs() {
|
||||
rm -rf "$ROOT" 2>/dev/null
|
||||
mkdir -p "${ROOT}/usr/bin/"
|
||||
mkdir -p "${ROOT}/usr/bin"
|
||||
mkdir -p "${ROOT}/usr/lib"
|
||||
mkdir -p "${ROOT}/usr/lib/dtrfs"
|
||||
mkdir -p "${ROOT}/dev"
|
||||
mkdir -p "${ROOT}/etc"
|
||||
mkdir -p "${ROOT}/mnt"
|
||||
@ -47,9 +46,9 @@ create_dirs() {
|
||||
ln -s usr/bin "${ROOT}/sbin"
|
||||
ln -s usr/lib "${ROOT}/lib"
|
||||
ln -s usr/lib "${ROOT}/lib64"
|
||||
ln -s lib "${ROOT}/usr/lib64"
|
||||
ln -s bin "${ROOT}/usr/sbin"
|
||||
ln -s ../run "${ROOT}/var/run"
|
||||
ln -s lib "${ROOT}/usr/lib64"
|
||||
ln -s bin "${ROOT}/usr/sbin"
|
||||
ln -s ../run "${ROOT}/var/run"
|
||||
}
|
||||
|
||||
# Installs a library. Expects absolute path.
|
||||
@ -116,7 +115,8 @@ install_busybox() {
|
||||
|
||||
install_init_script() {
|
||||
cp ../init.sh "${ROOT}/init"
|
||||
cp ../init_functions.sh "${ROOT}/"
|
||||
cp ../init_functions.sh "${ROOT}/usr/lib/dtrfs/"
|
||||
cp ../install_os.sh "${ROOT}/usr/lib/dtrfs/"
|
||||
}
|
||||
|
||||
install_module() {
|
||||
@ -182,13 +182,14 @@ scan_modules() {
|
||||
done <<< "$( echo "$drivers" )"
|
||||
}
|
||||
|
||||
install_guest_api() {
|
||||
echo_cyan "Installing the guest API from https://gitea.detee.cloud/SNP/remote_decryption/"
|
||||
wget -O guest_api.zst "$GUEST_API_URL" 2> /dev/null
|
||||
zstd --decompress guest_api.zst
|
||||
chmod +x guest_api
|
||||
install_binary "$(pwd)/guest_api"
|
||||
rm guest_api guest_api.zst
|
||||
install_dtrfs_api() {
|
||||
local my_location="$(pwd)"
|
||||
cd ../../dtrfs_api && cargo build --release || {
|
||||
echo_yellow "Could not build dtrfs_api. Looking for binary at $(pwd)/dtrfs_api"
|
||||
}
|
||||
cd "$my_location"
|
||||
cp ../../dtrfs_api/target/release/dtrfs_api ./
|
||||
install_binary "$(pwd)/dtrfs_api"
|
||||
}
|
||||
|
||||
create_archive() {
|
||||
@ -200,5 +201,5 @@ create_archive() {
|
||||
find . | cpio -o -H newc | gzip \
|
||||
> "${my_location}/detee-$(hostnamectl hostname)-${KERNEL}.cpio.gz"
|
||||
|
||||
cd $my_location
|
||||
cd "$my_location"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
source /init_functions.sh
|
||||
source /usr/lib/dtrfs/init_functions.sh
|
||||
|
||||
install_url="/tmp/detee_install_url"
|
||||
install_sha="/tmp/detee_install_sha"
|
||||
@ -14,6 +14,7 @@ setup_network
|
||||
# load this module again cause it fails the first time
|
||||
modprobe sev_guest
|
||||
|
||||
create_certs
|
||||
dtrfs_api
|
||||
|
||||
github_ssh_key
|
||||
|
@ -25,25 +25,17 @@ create_mounts() {
|
||||
ln -sfT /proc/self/fd/2 /dev/stderr
|
||||
}
|
||||
|
||||
try_hot_decrypt() {
|
||||
[[ -f "$snp_key_file" ]] && {
|
||||
cryptsetup open --key-file $snp_key_file /dev/vda1 root || return 1
|
||||
mount /dev/mapper/root /mnt || return 1
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
create_certs() {
|
||||
cert_dir="/tmp/certs"
|
||||
key="$cert_dir/guest_api.key"
|
||||
cert="$cert_dir/guest_api.crt"
|
||||
subject="/C=W3/O=DeTEE/OU=COCO/CN=guest-api"
|
||||
key="$cert_dir/dtrfs_api.key"
|
||||
cert="$cert_dir/dtrfs_api.crt"
|
||||
subject="/C=W3/O=DeTEE/OU=COCO/CN=dtrfs-api"
|
||||
mkdir -p "$cert_dir"
|
||||
openssl genpkey -algorithm RSA -out "$key" \
|
||||
-pkeyopt rsa_keygen_bits:4096 2>/dev/null
|
||||
openssl req -x509 -new \
|
||||
-key "$key" -out "$cert" \
|
||||
-addext "subjectAltName=DNS:dtrfs-api" \
|
||||
-days 365 -subj "$subject" 2>/dev/null
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
# This script is called by dtrfs_api to install an OS.
|
||||
|
||||
[[ -z "$INSTALL_URL" ]] || {
|
||||
[[ -z "$INSTALL_URL" ]] && {
|
||||
echo "Did not find INSTALL_URL env variable".
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ -z "$INSTALL_URL" ]] || {
|
||||
[[ -z "$INSTALL_URL" ]] && {
|
||||
echo "Did not find INSTALL_SHA env variable".
|
||||
exit 2
|
||||
}
|
||||
@ -33,23 +33,23 @@ echo === Creating partition /dev/vda1
|
||||
echo w
|
||||
) | fdisk /dev/vda
|
||||
echo "=== Formatting /dev/vda1 using cryptsetup luksFormat and opening as root"
|
||||
cryptsetup luksFormat --batch-mode -d $root_keyfile /dev/vda1
|
||||
cryptsetup luksFormat --batch-mode -d $ROOT_KEYFILE /dev/vda1 || exit 5
|
||||
[[ -f "$SNP_KEY_FILE" ]] && {
|
||||
echo "Adding LUKS slot via SNP KDF key found at $SNP_KEY_FILE"
|
||||
cryptsetup luksAddKey \
|
||||
--key-file $ROOT_KEYFILE \
|
||||
cryptsetup luksAddKey \
|
||||
--key-file $ROOT_KEYFILE \
|
||||
--new-keyfile $SNP_KEY_FILE /dev/vda1
|
||||
}
|
||||
cryptsetup open -d $ROOT_KEYFILE /dev/vda1 root
|
||||
cryptsetup open -d $ROOT_KEYFILE /dev/vda1 root || exit 6
|
||||
echo "=== Formatting /dev/mapper/root as ext4 and mounting at /mnt"
|
||||
mkfs.ext4 /dev/mapper/root
|
||||
mount /dev/mapper/root /mnt
|
||||
mkfs.ext4 /dev/mapper/root || exit 7
|
||||
mount /dev/mapper/root /mnt || exit 8
|
||||
echo "=== Downloading OS template from $INSTALL_URL and verifying hash"
|
||||
wget -O /mnt/template.fsa "$INSTALL_URL" || {
|
||||
echo "Failed to download $INSTALL_URL"
|
||||
exit 5
|
||||
exit 9
|
||||
}
|
||||
sha256sum /mnt/template.fsa | grep $(cat ${INSTALL_SHA}) || exit 1
|
||||
sha256sum /mnt/template.fsa | grep "${INSTALL_SHA}" || exit 1
|
||||
echo "=== Installing OS template"
|
||||
fsarchiver restdir /mnt/template.fsa /
|
||||
rm /mnt/template.fsa
|
@ -30,8 +30,16 @@ fi
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p tmp
|
||||
tar cf tmp/dtrfs.tar *.sh
|
||||
# TODO: test if this works
|
||||
mkdir -p tmp build
|
||||
my_location="$(pwd)"
|
||||
cd ../dtrfs_api && cargo build --release || {
|
||||
echo Could not build dtrfs_api
|
||||
exit 1
|
||||
}
|
||||
cd "$my_location"
|
||||
cp ../dtrfs_api/target/release/dtrfs_api ./build/
|
||||
tar cf tmp/dtrfs.tar *.sh build/dtrfs_api arch_guest_mods
|
||||
$ssh $server rm -rf ${dir}
|
||||
$ssh $server mkdir -p ${dir}
|
||||
$scp tmp/dtrfs.tar ${scp_server}:${dir}
|
||||
|
Loading…
Reference in New Issue
Block a user