{"record":{"id":"65b598badf012ea7","repo":"jdx/mise","slug":"ssh-connection-must-contain-client-address-port-an","errorCode":null,"errorMessage":"SSH_CONNECTION must contain client address/port and server address/port","messagePattern":"SSH_CONNECTION must contain client address/port and server address/port","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/firewall.rs","lineNumber":1983,"sourceCode":"    Ok(())\n}\n\nfn validate_interface(interface: &str) -> Result<String> {\n    if interface.is_empty()\n        || interface.len() > 15\n        || !interface\n            .bytes()\n            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_' | b'.' | b':'))\n    {\n        bail!(\"firewall interface '{interface}' is invalid\");\n    }\n    Ok(interface.to_string())\n}\n\nfn parse_ssh_connection(value: &str) -> Result<SshConnection> {\n    let fields = value.split_ascii_whitespace().collect::<Vec<_>>();\n    if fields.len() != 4 {\n        bail!(\"SSH_CONNECTION must contain client address/port and server address/port\");\n    }\n    Ok(SshConnection {\n        peer: fields[0].parse()?,\n        server: fields[2].parse()?,\n        server_port: fields[3].parse()?,\n    })\n}\n\n/// Detect an sshd ancestor when SSH_CONNECTION was stripped by sudo, env -i,\n/// or a wrapper. `None` fails closed because ancestry could not be inspected.\nfn ssh_ancestor_present() -> Option<bool> {\n    let mut pid = std::process::id();\n    let mut visited = HashSet::new();\n    for _ in 0..64 {\n        if !visited.insert(pid) {\n            return None;\n        }\n        let comm = fs::read_to_string(format!(\"/proc/{pid}/comm\")).ok()?;","sourceCodeStart":1965,"sourceCodeEnd":2001,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/firewall.rs#L1965-L2001","documentation":"parse_ssh_connection (src/system/firewall.rs) parses the sshd-provided SSH_CONNECTION env var, which has the form \"client-addr client-port server-addr server-port\". During firewall bootstrap mise reads it to detect the active SSH session so generated rules cannot lock the user out. The error fires when the value does not split into exactly 4 whitespace-separated tokens (the client port, fields[1], is not even consumed; fields[0]/[2]/[3] must also parse as address/port afterwards).","triggerScenarios":"mise bootstrap reaches the firewall step while SSH_CONNECTION holds fewer or more than 4 tokens — e.g. exported manually as \"10.0.0.5\", rewritten by a wrapper script, or seeded from a partial env dump in a container/CI image.","commonSituations":"sudo/env -i wrappers that strip or truncate env vars; CI or container images that set SSH_CONNECTION for tooling detection; test scripts faking an SSH environment; users copying shell rc files that re-export the variable.","solutions":["If not inside a real sshd session, unset it: `env -u SSH_CONNECTION mise bootstrap`","If it must be set, use the exact sshd format 'client-ip client-port server-ip server-port' (e.g. \"203.0.113.9 51234 10.0.0.1 22\")","Run bootstrap from a genuine ssh login rather than a wrapper that mangles the environment"],"exampleFix":"# before\nexport SSH_CONNECTION=\"10.0.0.5\"\n\n# after\nexport SSH_CONNECTION=\"203.0.113.9 51234 10.0.0.1 22\"\n# or, when not in a real ssh session:\n# unset SSH_CONNECTION","handlingStrategy":"validation","validationCode":"# only forward SSH_CONNECTION when it is well-formed\nif [ -n \"${SSH_CONNECTION:-}\" ] && [ \"$(echo \"$SSH_CONNECTION\" | wc -w)\" -ne 4 ]; then\n  unset SSH_CONNECTION\nfi\nmise bootstrap","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not set SSH_CONNECTION manually; let sshd provide it","In wrappers around mise bootstrap, drop malformed SSH_CONNECTION values before exec","Treat SSH_CONNECTION as an sshd-owned variable in CI images and never seed it with partial data"],"tags":["mise","firewall","ssh","environment-variable","bootstrap"],"backgroundTag":"invalid-environment-variable","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}