Kaynağa Gözat

Wrote a dockerfile for building a container for btfsd.

Matthew Carr 1 yıl önce
ebeveyn
işleme
abfcd2af55

+ 6 - 0
.dockerignore

@@ -0,0 +1,6 @@
+.vscode/
+doc/
+dockerfiles/
+target/
+tools/
+website/

+ 1 - 1
crates/btfproto/src/lib.rs

@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: AGPL-3.0-or-later
-#![feature(type_alias_impl_trait)]
+#![feature(impl_trait_in_assoc_type)]
 
 pub type Inode = btlib::Inode;
 pub type Handle = u64;

+ 2 - 2
crates/btfsd/Cargo.toml

@@ -12,11 +12,11 @@ btfproto = { path = "../btfproto" }
 tokio = { version = "1.24.2", features = ["rt", "rt-multi-thread", "time"] }
 log = "0.4.17"
 env_logger = "0.9.0"
+btlib-tests = { path = "../btlib-tests" }
 
 [dev-dependencies]
-btserde = { path = "../btserde" }
 swtpm-harness = { path = "../swtpm-harness" }
-btlib-tests = { path = "../btlib-tests" }
+btserde = { path = "../btserde" }
 tempdir = "0.3.7"
 ctor = { version = "0.1.22" }
 libc = { version = "0.2.137" }

+ 10 - 0
crates/btfsd/btfsd_init.sh

@@ -0,0 +1,10 @@
+#!/bin/sh
+# Init script to run in the btfsd container.
+set -e
+
+if [ "$BTFSD_USESWTPM" = 'true' ]; then
+    export DBUS_SESSION_BUS_ADDRESS="$(dbus-daemon --fork --session --print-address)"
+fi
+
+cd app
+./btfsd "$@"

+ 10 - 0
crates/btfsd/src/config.rs

@@ -10,6 +10,7 @@ pub struct Config {
     pub tabrmd: String,
     pub tpm_state_path: PathBuf,
     pub block_dir: PathBuf,
+    pub use_swtpm: bool,
 }
 
 impl Config {
@@ -24,6 +25,7 @@ pub struct ConfigBuilder {
     pub tabrmd: Option<String>,
     pub tpm_state_path: Option<PathBuf>,
     pub block_dir: Option<PathBuf>,
+    pub use_swtpm: Option<bool>,
 }
 
 impl ConfigBuilder {
@@ -51,6 +53,11 @@ impl ConfigBuilder {
         self
     }
 
+    pub fn with_use_swtpm(mut self, use_swtpm: Option<bool>) -> Self {
+        self.use_swtpm = use_swtpm;
+        self
+    }
+
     pub fn build(self) -> Config {
         Config {
             ip_addr: self.ip_addr.unwrap_or(DEFAULT_CONFIG.ip_addr),
@@ -61,6 +68,7 @@ impl ConfigBuilder {
             block_dir: self
                 .block_dir
                 .unwrap_or(Path::new(DEFAULT_CONFIG.block_dir).to_owned()),
+            use_swtpm: self.use_swtpm.unwrap_or(true),
         }
     }
 }
@@ -70,6 +78,7 @@ pub struct ConfigRef<'a> {
     pub tabrmd: &'a str,
     pub tpm_state_path: &'a str,
     pub block_dir: &'a str,
+    pub use_swtpm: &'a str,
 }
 
 pub struct Envvars<'a> {
@@ -77,4 +86,5 @@ pub struct Envvars<'a> {
     pub tabrmd: &'a str,
     pub tpm_state_path: &'a str,
     pub block_dir: &'a str,
+    pub use_swtpm: &'a str,
 }

+ 37 - 10
crates/btfsd/src/main.rs

@@ -8,14 +8,16 @@ use btfproto::{
 use btlib::{
     config_helpers::from_envvar,
     crypto::{tpm::TpmCredStore, CredStore, Creds},
+    log::BuilderExt,
 };
+use btlib_tests::TpmCredStoreHarness;
 use btmsg::Receiver;
 use config::{Config, ConfigRef, Envvars};
 use std::{
-    net::{IpAddr, Ipv6Addr},
+    net::{IpAddr, Ipv4Addr},
     path::PathBuf,
     str::FromStr,
-    sync::Arc,
+    sync::Arc, env::args,
 };
 
 const ENVVARS: Envvars<'static> = Envvars {
@@ -23,13 +25,15 @@ const ENVVARS: Envvars<'static> = Envvars {
     tabrmd: "BTFSD_TABRMD",
     tpm_state_path: "BTFSD_TPMSTATE",
     block_dir: "BTFSD_BLOCKDIR",
+    use_swtpm: "BTFSD_USESWTPM",
 };
 
 const DEFAULT_CONFIG: ConfigRef<'static> = ConfigRef {
-    ip_addr: IpAddr::V6(Ipv6Addr::LOCALHOST),
+    ip_addr: IpAddr::V4(Ipv4Addr::LOCALHOST),
     tabrmd: "bus_type=session",
-    tpm_state_path: "./tpm_state",
-    block_dir: "./bt",
+    tpm_state_path: "./state/tpm_state",
+    block_dir: "./state/bt",
+    use_swtpm: "true",
 };
 
 async fn provider<C: 'static + Send + Sync + Creds>(
@@ -55,6 +59,8 @@ async fn receiver(config: Config) -> impl Receiver {
 
 #[tokio::main]
 async fn main() {
+    env_logger::Builder::from_default_env().btformat().init();
+
     let ip_addr = from_envvar(ENVVARS.ip_addr)
         .unwrap()
         .map(|txt| IpAddr::from_str(&txt).unwrap());
@@ -63,13 +69,33 @@ async fn main() {
         .unwrap()
         .map(PathBuf::from);
     let block_dir = from_envvar(ENVVARS.block_dir).unwrap().map(PathBuf::from);
-    let config = Config::builder()
+    let use_swtpm = from_envvar(ENVVARS.use_swtpm)
+        .unwrap()
+        .map(|str| bool::from_str(&str).unwrap());
+    let mut config = Config::builder()
         .with_ip_addr(ip_addr)
         .with_tabrmd(tabrmd)
         .with_tpm_state_path(tpm_state_path)
         .with_block_dir(block_dir)
+        .with_use_swtpm(use_swtpm)
         .build();
+    let _swtpm = if config.use_swtpm {
+        log::debug!("starting swtpm");
+        let root_pw = if let Some(root_pw) = args().next() {
+            root_pw
+        } else {
+            panic!("when BTFSD_USESWTPM is true, the root password must be given as the first argument")
+        };
+        let swtpm = TpmCredStoreHarness::new(root_pw).unwrap(); 
+        config.tabrmd = swtpm.swtpm().tabrmd_config().to_owned();
+        config.tpm_state_path = swtpm.swtpm().state_path().to_owned();
+        Some(swtpm)
+    } else {
+        None
+    };
+
     let receiver = receiver(config).await;
+    log::debug!("ready to accept connections");
     receiver.complete().unwrap().await.unwrap();
 }
 
@@ -106,7 +132,7 @@ mod tests {
     }
 
     const ROOT_PASSWD: &str = "existential_threat";
-    const LOCALHOST: IpAddr = IpAddr::V6(Ipv6Addr::LOCALHOST);
+    const LOCALHOST: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST);
     const BT_DIR: &str = "bt";
 
     async fn test_case(
@@ -119,6 +145,7 @@ mod tests {
             tabrmd: harness.swtpm().tabrmd_config().to_owned(),
             tpm_state_path: harness.swtpm().state_path().to_owned(),
             block_dir: dir.path().join(BT_DIR),
+            use_swtpm: false,
         };
         let rx = receiver(config).await;
         let tx = rx.transmitter(rx.addr().clone()).await.unwrap();
@@ -676,7 +703,7 @@ mod tests {
             .unwrap();
         creds.set_writecap(writecap);
         let expected = IssuedProcRec {
-            addr: IpAddr::V6(Ipv6Addr::LOCALHOST),
+            addr: IpAddr::V4(Ipv4Addr::LOCALHOST),
             pub_creds: creds.concrete_pub(),
             writecap: creds.writecap().unwrap().to_owned(),
             authz_attrs: AuthzAttrs {
@@ -726,7 +753,7 @@ mod tests {
             .unwrap();
         creds.set_writecap(writecap);
         let expected = IssuedProcRec {
-            addr: IpAddr::V6(Ipv6Addr::LOCALHOST),
+            addr: IpAddr::V4(Ipv4Addr::LOCALHOST),
             pub_creds: creds.concrete_pub(),
             writecap: creds.writecap().unwrap().to_owned(),
             authz_attrs: AuthzAttrs {
@@ -803,7 +830,7 @@ mod tests {
             creds
         };
         let expected = IssuedProcRec {
-            addr: IpAddr::V6(Ipv6Addr::LOCALHOST),
+            addr: IpAddr::V4(Ipv4Addr::LOCALHOST),
             pub_creds: user_creds.concrete_pub(),
             writecap: user_creds.writecap().unwrap().to_owned(),
             authz_attrs: AuthzAttrs {

+ 1 - 1
crates/btlib/src/error.rs

@@ -45,7 +45,7 @@ macro_rules! btensure {
 /// `Ok($count)` is returned.
 /// If the result is an error and count is zero, then the `Err` variant is returned
 /// containing it.
-#[macro_export(crate)]
+#[macro_export]
 macro_rules! suppress_err_if_non_zero {
     ($count:expr, $result:expr) => {
         match $result {

+ 1 - 1
crates/btmsg/src/lib.rs

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: AGPL-3.0-or-later
 //! Code which enables sending messages between processes in the blocktree system.
-#![feature(type_alias_impl_trait)]
+#![feature(impl_trait_in_assoc_type)]
 
 mod tls;
 use tls::*;

+ 1 - 1
crates/btmsg/tests/tests.rs

@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: AGPL-3.0-or-later
-#![feature(type_alias_impl_trait)]
+#![feature(impl_trait_in_assoc_type)]
 
 use btmsg::*;
 

+ 25 - 0
dockerfiles/btfsd.Dockerfile

@@ -0,0 +1,25 @@
+FROM archlinux:base-devel AS build
+RUN pacman -Syu --noconfirm
+RUN pacman -S --noconfirm rustup clang openssl tpm2-tss
+RUN rustup toolchain install nightly
+RUN rustup default nightly
+RUN mkdir -p src/crates
+COPY ./crates /src/crates
+COPY Cargo.toml /src/
+COPY Cargo.lock /src/
+WORKDIR /src
+RUN cargo fetch --target x86_64-unknown-linux-gnu
+WORKDIR /src/crates/btfsd
+RUN cargo build --release
+
+FROM archlinux:base AS release
+RUN pacman -Syu --noconfirm\
+    && pacman -S --noconfirm openssl tpm2-tss swtpm tpm2-abrmd dbus\
+    && pacman -Scc --noconfirm\
+    && useradd btfsd\
+    && mkdir -p /app/state\
+    && chown btfsd:btfsd /app/state
+COPY --from=build /src/target/release/btfsd /app/
+COPY --from=build /src/crates/btfsd/btfsd_init.sh /init.sh
+USER btfsd
+ENTRYPOINT ["/init.sh"]

+ 4 - 0
dockerfiles/build_images.sh

@@ -0,0 +1,4 @@
+#!/bin/sh
+set -e
+
+sudo docker build -t btfsd:latest -f btfsd.Dockerfile ..

+ 5 - 0
dockerfiles/run_btfsd.sh

@@ -0,0 +1,5 @@
+#!/bin/sh
+sudo docker run -d --rm --name btfsd\
+    --env BTFSD_USESWTPM=true\
+    --env RUST_LOG='warn,btfsd=debug'\
+    btfsd:latest password