From 90a9db3a91b1a30db9487134c3c2f58d60b0ed96 Mon Sep 17 00:00:00 2001 From: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Date: Fri, 14 Jul 2023 12:30:52 -0600 Subject: [PATCH] disable encryption for new raspi setups (#2348) * disable encryption for new raspi setups * use config instead of OS_ARCH * fixes from testing --- backend/src/bins/start_init.rs | 6 +- backend/src/context/setup.rs | 4 + backend/src/disk/main.rs | 176 ++++++++++++++++++--------------- backend/src/disk/util.rs | 6 +- backend/src/setup.rs | 17 +++- build/raspberrypi/config.yaml | 3 +- 6 files changed, 123 insertions(+), 89 deletions(-) diff --git a/backend/src/bins/start_init.rs b/backend/src/bins/start_init.rs index a562eacf6..485d8e323 100644 --- a/backend/src/bins/start_init.rs +++ b/backend/src/bins/start_init.rs @@ -125,7 +125,11 @@ async fn setup_or_init(cfg_path: Option) -> Result<(), Error> { } else { RepairStrategy::Preen }, - DEFAULT_PASSWORD, + if guid.ends_with("_UNENC") { + None + } else { + Some(DEFAULT_PASSWORD) + }, ) .await?; if tokio::fs::metadata(REPAIR_DISK_PATH).await.is_ok() { diff --git a/backend/src/context/setup.rs b/backend/src/context/setup.rs index 8e516d719..7ae161b01 100644 --- a/backend/src/context/setup.rs +++ b/backend/src/context/setup.rs @@ -45,6 +45,8 @@ pub struct SetupContextConfig { pub migration_batch_rows: Option, pub migration_prefetch_rows: Option, pub datadir: Option, + #[serde(default)] + pub disable_encryption: bool, } impl SetupContextConfig { #[instrument(skip_all)] @@ -75,6 +77,7 @@ pub struct SetupContextSeed { pub config_path: Option, pub migration_batch_rows: usize, pub migration_prefetch_rows: usize, + pub disable_encryption: bool, pub shutdown: Sender<()>, pub datadir: PathBuf, pub selected_v2_drive: RwLock>, @@ -102,6 +105,7 @@ impl SetupContext { config_path: path.as_ref().map(|p| p.as_ref().to_owned()), migration_batch_rows: cfg.migration_batch_rows.unwrap_or(25000), migration_prefetch_rows: cfg.migration_prefetch_rows.unwrap_or(100_000), + disable_encryption: cfg.disable_encryption, shutdown, datadir, selected_v2_drive: RwLock::new(None), diff --git a/backend/src/disk/main.rs b/backend/src/disk/main.rs index 7d7247984..7d1ce1d3f 100644 --- a/backend/src/disk/main.rs +++ b/backend/src/disk/main.rs @@ -13,7 +13,7 @@ use crate::disk::mount::util::unmount; use crate::util::Invoke; use crate::{Error, ErrorKind, ResultExt}; -pub const PASSWORD_PATH: &'static str = "/etc/embassy/password"; +pub const PASSWORD_PATH: &'static str = "/run/embassy/password"; pub const DEFAULT_PASSWORD: &'static str = "password"; pub const MAIN_FS_SIZE: FsSize = FsSize::Gigabytes(8); @@ -22,13 +22,13 @@ pub async fn create( disks: &I, pvscan: &BTreeMap>, datadir: impl AsRef, - password: &str, + password: Option<&str>, ) -> Result where for<'a> &'a I: IntoIterator, P: AsRef, { - let guid = create_pool(disks, pvscan).await?; + let guid = create_pool(disks, pvscan, password.is_some()).await?; create_all_fs(&guid, &datadir, password).await?; export(&guid, datadir).await?; Ok(guid) @@ -38,6 +38,7 @@ where pub async fn create_pool( disks: &I, pvscan: &BTreeMap>, + encrypted: bool, ) -> Result where for<'a> &'a I: IntoIterator, @@ -62,13 +63,16 @@ where .invoke(crate::ErrorKind::DiskManagement) .await?; } - let guid = format!( + let mut guid = format!( "EMBASSY_{}", base32::encode( base32::Alphabet::RFC4648 { padding: false }, &rand::random::<[u8; 32]>(), ) ); + if !encrypted { + guid += "_UNENC"; + } let mut cmd = Command::new("vgcreate"); cmd.arg("-y").arg(&guid); for disk in disks { @@ -90,11 +94,8 @@ pub async fn create_fs>( datadir: P, name: &str, size: FsSize, - password: &str, + password: Option<&str>, ) -> Result<(), Error> { - tokio::fs::write(PASSWORD_PATH, password) - .await - .with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?; let mut cmd = Command::new("lvcreate"); match size { FsSize::Gigabytes(a) => cmd.arg("-L").arg(format!("{}G", a)), @@ -106,37 +107,38 @@ pub async fn create_fs>( .arg(guid) .invoke(crate::ErrorKind::DiskManagement) .await?; - let crypt_path = Path::new("/dev").join(guid).join(name); - Command::new("cryptsetup") - .arg("-q") - .arg("luksFormat") - .arg(format!("--key-file={}", PASSWORD_PATH)) - .arg(format!("--keyfile-size={}", password.len())) - .arg(&crypt_path) - .invoke(crate::ErrorKind::DiskManagement) - .await?; - Command::new("cryptsetup") - .arg("-q") - .arg("luksOpen") - .arg(format!("--key-file={}", PASSWORD_PATH)) - .arg(format!("--keyfile-size={}", password.len())) - .arg(&crypt_path) - .arg(format!("{}_{}", guid, name)) - .invoke(crate::ErrorKind::DiskManagement) - .await?; + let mut blockdev_path = Path::new("/dev").join(guid).join(name); + if let Some(password) = password { + tokio::fs::write(PASSWORD_PATH, password) + .await + .with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?; + Command::new("cryptsetup") + .arg("-q") + .arg("luksFormat") + .arg(format!("--key-file={}", PASSWORD_PATH)) + .arg(format!("--keyfile-size={}", password.len())) + .arg(&blockdev_path) + .invoke(crate::ErrorKind::DiskManagement) + .await?; + Command::new("cryptsetup") + .arg("-q") + .arg("luksOpen") + .arg(format!("--key-file={}", PASSWORD_PATH)) + .arg(format!("--keyfile-size={}", password.len())) + .arg(&blockdev_path) + .arg(format!("{}_{}", guid, name)) + .invoke(crate::ErrorKind::DiskManagement) + .await?; + tokio::fs::remove_file(PASSWORD_PATH) + .await + .with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?; + blockdev_path = Path::new("/dev/mapper").join(format!("{}_{}", guid, name)); + } Command::new("mkfs.btrfs") - .arg(Path::new("/dev/mapper").join(format!("{}_{}", guid, name))) + .arg(&blockdev_path) .invoke(crate::ErrorKind::DiskManagement) .await?; - mount( - Path::new("/dev/mapper").join(format!("{}_{}", guid, name)), - datadir.as_ref().join(name), - ReadWrite, - ) - .await?; - tokio::fs::remove_file(PASSWORD_PATH) - .await - .with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?; + mount(&blockdev_path, datadir.as_ref().join(name), ReadWrite).await?; Ok(()) } @@ -144,7 +146,7 @@ pub async fn create_fs>( pub async fn create_all_fs>( guid: &str, datadir: P, - password: &str, + password: Option<&str>, ) -> Result<(), Error> { create_fs(guid, &datadir, "main", MAIN_FS_SIZE, password).await?; create_fs( @@ -161,12 +163,14 @@ pub async fn create_all_fs>( #[instrument(skip_all)] pub async fn unmount_fs>(guid: &str, datadir: P, name: &str) -> Result<(), Error> { unmount(datadir.as_ref().join(name)).await?; - Command::new("cryptsetup") - .arg("-q") - .arg("luksClose") - .arg(format!("{}_{}", guid, name)) - .invoke(crate::ErrorKind::DiskManagement) - .await?; + if !guid.ends_with("_UNENC") { + Command::new("cryptsetup") + .arg("-q") + .arg("luksClose") + .arg(format!("{}_{}", guid, name)) + .invoke(crate::ErrorKind::DiskManagement) + .await?; + } Ok(()) } @@ -203,7 +207,7 @@ pub async fn import>( guid: &str, datadir: P, repair: RepairStrategy, - password: &str, + mut password: Option<&str>, ) -> Result { let scan = pvscan().await?; if scan @@ -261,46 +265,56 @@ pub async fn mount_fs>( datadir: P, name: &str, repair: RepairStrategy, - password: &str, + password: Option<&str>, ) -> Result { - tokio::fs::write(PASSWORD_PATH, password) - .await - .with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?; - let crypt_path = Path::new("/dev").join(guid).join(name); + let orig_path = Path::new("/dev").join(guid).join(name); + let mut blockdev_path = orig_path.clone(); let full_name = format!("{}_{}", guid, name); - Command::new("cryptsetup") - .arg("-q") - .arg("luksOpen") - .arg(format!("--key-file={}", PASSWORD_PATH)) - .arg(format!("--keyfile-size={}", password.len())) - .arg(&crypt_path) - .arg(&full_name) - .invoke(crate::ErrorKind::DiskManagement) - .await?; - let mapper_path = Path::new("/dev/mapper").join(&full_name); - let reboot = repair.fsck(&mapper_path).await?; - // Backup LUKS header if e2fsck succeeded - let luks_folder = Path::new("/media/embassy/config/luks"); - tokio::fs::create_dir_all(luks_folder).await?; - let tmp_luks_bak = luks_folder.join(format!(".{full_name}.luks.bak.tmp")); - if tokio::fs::metadata(&tmp_luks_bak).await.is_ok() { - tokio::fs::remove_file(&tmp_luks_bak).await?; + if !guid.ends_with("_UNENC") { + let password = password.unwrap_or(DEFAULT_PASSWORD); + if let Some(parent) = Path::new(PASSWORD_PATH).parent() { + tokio::fs::create_dir_all(parent).await?; + } + tokio::fs::write(PASSWORD_PATH, password) + .await + .with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?; + Command::new("cryptsetup") + .arg("-q") + .arg("luksOpen") + .arg(format!("--key-file={}", PASSWORD_PATH)) + .arg(format!("--keyfile-size={}", password.len())) + .arg(&blockdev_path) + .arg(&full_name) + .invoke(crate::ErrorKind::DiskManagement) + .await?; + tokio::fs::remove_file(PASSWORD_PATH) + .await + .with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?; + blockdev_path = Path::new("/dev/mapper").join(&full_name); } - let luks_bak = luks_folder.join(format!("{full_name}.luks.bak")); - Command::new("cryptsetup") - .arg("-q") - .arg("luksHeaderBackup") - .arg("--header-backup-file") - .arg(&tmp_luks_bak) - .arg(&crypt_path) - .invoke(crate::ErrorKind::DiskManagement) - .await?; - tokio::fs::rename(&tmp_luks_bak, &luks_bak).await?; - mount(&mapper_path, datadir.as_ref().join(name), ReadWrite).await?; + let reboot = repair.fsck(&blockdev_path).await?; - tokio::fs::remove_file(PASSWORD_PATH) - .await - .with_ctx(|_| (crate::ErrorKind::Filesystem, PASSWORD_PATH))?; + if !guid.ends_with("_UNENC") { + // Backup LUKS header if e2fsck succeeded + let luks_folder = Path::new("/media/embassy/config/luks"); + tokio::fs::create_dir_all(luks_folder).await?; + let tmp_luks_bak = luks_folder.join(format!(".{full_name}.luks.bak.tmp")); + if tokio::fs::metadata(&tmp_luks_bak).await.is_ok() { + tokio::fs::remove_file(&tmp_luks_bak).await?; + } + let luks_bak = luks_folder.join(format!("{full_name}.luks.bak")); + Command::new("cryptsetup") + .arg("-q") + .arg("luksHeaderBackup") + .arg("--header-backup-file") + .arg(&tmp_luks_bak) + .arg(&orig_path) + .invoke(crate::ErrorKind::DiskManagement) + .await?; + tokio::fs::rename(&tmp_luks_bak, &luks_bak).await?; + } + + mount(&blockdev_path, datadir.as_ref().join(name), ReadWrite).await?; Ok(reboot) } @@ -310,7 +324,7 @@ pub async fn mount_all_fs>( guid: &str, datadir: P, repair: RepairStrategy, - password: &str, + password: Option<&str>, ) -> Result { let mut reboot = RequiresReboot(false); reboot |= mount_fs(guid, &datadir, "main", repair, password).await?; diff --git a/backend/src/disk/util.rs b/backend/src/disk/util.rs index 282edc380..27b2bb5f0 100644 --- a/backend/src/disk/util.rs +++ b/backend/src/disk/util.rs @@ -324,11 +324,13 @@ pub async fn list(os: &OsPartitionInfo) -> Result, Error> { if index.internal { for part in index.parts { let mut disk_info = disk_info(disk.clone()).await; - disk_info.logicalname = part; + let part_info = part_info(part).await; + disk_info.logicalname = part_info.logicalname.clone(); + disk_info.capacity = part_info.capacity; if let Some(g) = disk_guids.get(&disk_info.logicalname) { disk_info.guid = g.clone(); } else { - disk_info.partitions = vec![part_info(disk_info.logicalname.clone()).await]; + disk_info.partitions = vec![part_info]; } res.push(disk_info); } diff --git a/backend/src/setup.rs b/backend/src/setup.rs index afe92670f..1612d579f 100644 --- a/backend/src/setup.rs +++ b/backend/src/setup.rs @@ -125,7 +125,7 @@ pub async fn attach( } else { RepairStrategy::Preen }, - DEFAULT_PASSWORD, + if guid.ends_with("_UNENC") { None } else { Some(DEFAULT_PASSWORD) }, ) .await?; if tokio::fs::metadata(REPAIR_DISK_PATH).await.is_ok() { @@ -337,12 +337,17 @@ pub async fn execute_inner( recovery_source: Option, recovery_password: Option, ) -> Result<(Arc, Hostname, OnionAddressV3, X509), Error> { + let encryption_password = if ctx.disable_encryption { + None + } else { + Some(DEFAULT_PASSWORD) + }; let guid = Arc::new( crate::disk::main::create( &[embassy_logicalname], &pvscan().await?, &ctx.datadir, - DEFAULT_PASSWORD, + encryption_password, ) .await?, ); @@ -350,7 +355,7 @@ pub async fn execute_inner( &*guid, &ctx.datadir, RepairStrategy::Preen, - DEFAULT_PASSWORD, + encryption_password, ) .await?; @@ -418,7 +423,11 @@ async fn migrate( &old_guid, "/media/embassy/migrate", RepairStrategy::Preen, - DEFAULT_PASSWORD, + if guid.ends_with("_UNENC") { + None + } else { + Some(DEFAULT_PASSWORD) + }, ) .await?; diff --git a/build/raspberrypi/config.yaml b/build/raspberrypi/config.yaml index cd242269f..7c81ad513 100644 --- a/build/raspberrypi/config.yaml +++ b/build/raspberrypi/config.yaml @@ -2,4 +2,5 @@ os-partitions: boot: /dev/mmcblk0p1 root: /dev/mmcblk0p2 ethernet-interface: end0 -wifi-interface: wlan0 \ No newline at end of file +wifi-interface: wlan0 +disable-encryption: true