Skip to content

Support SSH config Host alias reference in jump_host configuration #170

@inureyes

Description

@inureyes

Problem / Background

Following up on #167 (per-jump-host SSH key configuration), there's another common pattern that users want to leverage: referencing SSH config Host aliases for jump hosts.

OpenSSH allows users to define comprehensive host configurations in ~/.ssh/config:

Host bastion
    HostName bastion.example.com
    User jumpuser
    Port 22
    IdentityFile ~/.ssh/bastion_key
    ServerAliveInterval 60

Users can then use ssh bastion instead of specifying all those options. However, in bssh's config.yaml, users cannot reference these predefined SSH config entries for jump hosts.

Proposed Solution

Support a new format for jump_host that allows referencing an SSH config Host alias:

Desired Config Syntax

New SSH config reference format:

clusters:
  internal:
    nodes:
      - host: internal1.private
    user: admin
    ssh_key: ~/.ssh/destination_key
    jump_host:
      ssh_config_host: bastion  # Reference to ~/.ssh/config Host alias

Or using a simpler string prefix:

clusters:
  internal:
    jump_host: "@bastion"  # "@" prefix indicates SSH config reference

Behavior

When ssh_config_host is specified (or @ prefix is used):

  1. Load the SSH config file (~/.ssh/config)
  2. Resolve the host configuration for the given alias
  3. Extract: HostName, User, Port, IdentityFile (first one if multiple)
  4. Use these values to construct the JumpHost

Benefits

  1. DRY (Don't Repeat Yourself): Users can define jump host configurations once in ~/.ssh/config and reuse them
  2. Consistency: Same jump host definition used by both OpenSSH and bssh
  3. Rich configuration: SSH config supports many more options that can be leveraged
  4. Existing workflow integration: Many users already have SSH configs set up

Implementation Plan

1. Extend JumpHostConfig enum

File: src/config/types.rs

Add a new variant to support SSH config references:

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum JumpHostConfig {
    /// SSH config Host alias reference format: "@hostname"
    SshConfigRef(String),  // Must start with "@"
    /// Legacy string format: "[user@]hostname[:port]"
    Simple(String),
    /// Structured format with optional ssh_key
    Detailed {
        host: String,
        #[serde(default)]
        user: Option<String>,
        #[serde(default)]
        port: Option<u16>,
        #[serde(default)]
        ssh_key: Option<String>,
    },
    /// SSH config reference with structured format
    SshConfigHostRef {
        ssh_config_host: String,
    },
}

2. Update config resolver to handle SSH config references

File: src/config/resolver.rs

Update process_jump_host_config to:

  1. Detect SSH config reference (@ prefix or ssh_config_host field)
  2. Load SSH config
  3. Resolve host alias to actual connection parameters
  4. Return the resolved JumpHost with all settings from SSH config

3. Create SSH config resolution helper

File: src/ssh/ssh_config/mod.rs

Add method to resolve jump host parameters from SSH config:

impl SshConfig {
    /// Resolve jump host parameters from a Host alias
    pub fn resolve_jump_host(&self, host_alias: &str) -> Option<(String, Option<String>, Option<u16>, Option<String>)> {
        // Returns (hostname, user, port, identity_file)
    }
}

4. Update example config and documentation

Acceptance Criteria

  • jump_host: "@alias" string format works (@ prefix for SSH config reference)
  • jump_host: { ssh_config_host: "alias" } structured format works
  • SSH config Host alias is resolved to actual HostName
  • User from SSH config is used if specified
  • Port from SSH config is used if specified
  • IdentityFile from SSH config is used as ssh_key
  • Falls back gracefully if SSH config doesn't exist or alias not found
  • Works at node-level, cluster-level, and global defaults level
  • Documentation and examples updated
  • Unit tests cover SSH config reference resolution

Related Issues

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions