{"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":2053,"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":2035,"sourceCodeEnd":2071,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/firewall.rs#L2035-L2071","documentation":"The library parses the SSH_CONNECTION environment variable, which must contain exactly four whitespace-separated fields: client address, client port, server address, server port. When the variable is missing, empty, or has a different field count, parsing bails with this message. This is typically used to derive the connecting peer's address for dynamic firewall rules.","triggerScenarios":"Calling parse_ssh_connection when SSH_CONNECTION is unset or empty (not invoked over SSH), or contains fewer/more than 4 whitespace-separated fields (e.g. only \"1.2.3.4 22\").","commonSituations":"Running a bootstrap/firewall command in a local shell, CI job, systemd service, or tmux where SSH_CONNECTION is not propagated; custom SSH setups or proxies that alter the variable; shell quoting collapsing fields.","solutions":["Run the command inside a normal SSH session so SSH_CONNECTION is set to four fields.","Verify with `echo $SSH_CONNECTION` that it has exactly four whitespace-separated fields before invoking.","If running under systemd/tmux/sudo, propagate SSH_CONNECTION explicitly (e.g. `sudo --preserve-env=SSH_CONNECTION` or PassEnvironment).","If no SSH context applies, supply the peer/server addresses explicitly instead of relying on SSH_CONNECTION."],"exampleFix":"// before\n$ mise firewall bootstrap  # run locally, SSH_CONNECTION unset -> error\n// after\n$ ssh user@host\n$ echo $SSH_CONNECTION      # e.g. 203.0.113.7 51234 10.0.0.5 22\n$ mise firewall bootstrap","handlingStrategy":"validation","validationCode":"fn has_valid_ssh_connection() -> bool {\n    std::env::var(\"SSH_CONNECTION\")\n        .map(|v| v.split_ascii_whitespace().count() == 4)\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match parse_ssh_connection(&std::env::var(\"SSH_CONNECTION\").unwrap_or_default()) {\n    Err(_) => eprintln!(\"run inside an SSH session or pass addresses explicitly\"),\n    Ok(conn) => { /* use conn.peer / conn.server */ }\n}","preventionTips":["Verify SSH_CONNECTION exists before firewall bootstrap over SSH","Preserve SSH_CONNECTION through sudo/systemd/tmux","Fall back to explicit address arguments when no SSH context exists","Log the parsed connection for debugging in bootstrap scripts"],"tags":["firewall","ssh","environment"],"backgroundTag":"missing-env-var","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}