fix(fedimint): run fmcd with seccomp=unconfined so its DHT can start (#7)
fmcd crash-looped "Operation not permitted (os error 1)" on .116 (kernel 6.12.74): the default rootless seccomp profile blocks a syscall its Mainline-DHT / iroh transport needs, so the REST API never came up (:8178 → HTTP 000) and federations couldn't be joined. Verified: with seccomp=unconfined fmcd boots and answers /v2/* (HTTP 401 instead of dead). fmcd works on other nodes, so this is kernel/seccomp-specific — but the relaxation is safe for an outbound-networking daemon and harmless where not needed. - new `security.seccomp_unconfined` manifest flag (SecurityPolicy); - libpod backend sets `seccomp_profile_path: "unconfined"` (== --security-opt seccomp=unconfined); quadlet backend emits `SeccompProfile=unconfined`; - enabled in apps/fedimint-clientd/manifest.yml. NOTE: manifests live on-disk at /opt/archipelago/apps/<id>/manifest.yml, so the node needs the updated manifest deployed + the fmcd container recreated to apply. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d59cf6d299
commit
409543c41e
@@ -228,6 +228,13 @@ pub struct SecurityPolicy {
|
||||
pub network_policy: String,
|
||||
#[serde(default)]
|
||||
pub apparmor_profile: Option<String>,
|
||||
/// Run the container with `seccomp=unconfined`. Needed by daemons whose
|
||||
/// networking uses syscalls blocked by the default rootless seccomp profile
|
||||
/// on some kernels — e.g. fmcd's Mainline-DHT/iroh transport, which otherwise
|
||||
/// crash-loops with "Operation not permitted (os error 1)" (#7). Opt-in only;
|
||||
/// a mild relaxation, so reserve it for apps that genuinely need it.
|
||||
#[serde(default)]
|
||||
pub seccomp_unconfined: bool,
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
|
||||
@@ -384,6 +384,17 @@ impl PodmanClient {
|
||||
"nsmode": net_mode
|
||||
},
|
||||
});
|
||||
// seccomp=unconfined for apps that need syscalls the default rootless
|
||||
// profile blocks (e.g. fmcd's DHT) — libpod takes the literal "unconfined"
|
||||
// as the profile path, mirroring `--security-opt seccomp=unconfined` (#7).
|
||||
if manifest.app.security.seccomp_unconfined {
|
||||
body.as_object_mut()
|
||||
.expect("container create body is a JSON object")
|
||||
.insert(
|
||||
"seccomp_profile_path".to_string(),
|
||||
serde_json::json!("unconfined"),
|
||||
);
|
||||
}
|
||||
if let Some(network) = custom_network {
|
||||
body.as_object_mut()
|
||||
.expect("container create body is a JSON object")
|
||||
|
||||
Reference in New Issue
Block a user