Skip to content

[Phase 2] Add certificate authentication and advanced port forwarding options #44

Description

@inureyes

Overview

This is Phase 2 of the SSH config parser enhancement roadmap. This phase focuses on adding support for certificate-based PKI authentication and advanced port forwarding control options that are commonly used in enterprise and production environments.

Background

Options to Implement

1. CertificateFile ⭐⭐⭐⭐

Importance: High - Standard in enterprise PKI environments

Functionality:

  • Specify SSH certificate files for authentication
  • Works alongside IdentityFile for certificate-based auth
  • Supports multiple certificate files
  • Eliminates need for authorized_keys management at scale

Use Cases:

  • Large-scale enterprise deployments
  • PKI-based authentication systems
  • Certificate expiration management
  • Centralized access control

Example:

Host *.corp.example.com
    IdentityFile ~/.ssh/id_rsa
    CertificateFile ~/.ssh/id_rsa-cert.pub

Implementation:

  • Add certificate_files: Vec<PathBuf> to SshHostConfig
  • Parse and validate certificate file paths
  • Support tilde expansion and environment variables

2. CASignatureAlgorithms ⭐⭐⭐⭐

Importance: High - Required for certificate validation

Functionality:

  • Specify accepted signature algorithms for CA certificates
  • Controls which CA signature algorithms are trusted
  • Security hardening for certificate-based auth

Example:

Host *
    CASignatureAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

Implementation:

  • Add ca_signature_algorithms: Vec<String> to SshHostConfig
  • Parse comma-separated algorithm list
  • Validate algorithm names

3. GatewayPorts ⭐⭐⭐⭐

Importance: High - Critical for remote port forwarding

Functionality:

  • Control whether remote port forwardings bind to wildcard address
  • Values: yes, no, clientspecified
  • Enables external access to forwarded ports

Use Cases:

  • Exposing local development servers remotely
  • Bypassing NAT/firewalls
  • Cloud service tunneling
  • Reverse proxy setups

Example:

Host tunnel-server
    RemoteForward 8080 localhost:3000
    GatewayPorts yes

Implementation:

  • Add gateway_ports: Option<String> to SshHostConfig
  • Parse yes/no/clientspecified values
  • Validation for valid values

4. ExitOnForwardFailure ⭐⭐⭐⭐

Importance: High - Critical for reliability

Functionality:

  • Terminate SSH connection if port forwarding fails
  • Prevents silent failures in automation
  • Ensures forwarding-dependent workflows fail fast

Use Cases:

  • Automated deployment scripts
  • Database tunneling (must succeed)
  • Service-critical port forwards
  • CI/CD pipelines

Example:

Host database-tunnel
    LocalForward 5432 db.internal:5432
    ExitOnForwardFailure yes

Implementation:

  • Add exit_on_forward_failure: Option<bool> to SshHostConfig
  • Parse yes/no values using existing parse_yes_no function
  • Document fail-fast behavior

5. PermitRemoteOpen ⭐⭐⭐

Importance: Medium-High - Security control

Functionality:

  • Restrict which remote hosts can be connected via port forwarding
  • Security hardening for port forwarding
  • Can specify host:port patterns or "none"

Example:

Host jump-host
    PermitRemoteOpen db.internal:5432 cache.internal:6379

Implementation:

  • Add permit_remote_open: Vec<String> to SshHostConfig
  • Parse space-separated host:port patterns
  • Support "none" and "any" special values

Additional Options (Lower Priority)

6. HostbasedAuthentication ⭐⭐

Functionality: Enable host-based authentication
Use Case: Trusted host groups, HPC clusters

7. HostbasedAcceptedAlgorithms ⭐⭐

Functionality: Specify accepted algorithms for host-based auth
Use Case: Works with HostbasedAuthentication

Technical Implementation

Files to Modify

Parser:

  • src/ssh/ssh_config/parser.rs:95-460 - Add new option parsing

Types:

  • src/ssh/ssh_config/types.rs:22-68 - Add new fields to SshHostConfig

Resolver:

  • src/ssh/ssh_config/resolver.rs - Add getter methods for new options

Security:

  • src/ssh/ssh_config/security.rs - Validate certificate file paths

Implementation Details

// In types.rs
pub struct SshHostConfig {
    // ... existing fields ...
    
    // Certificate authentication
    pub certificate_files: Vec<PathBuf>,
    pub ca_signature_algorithms: Vec<String>,
    
    // Port forwarding controls
    pub gateway_ports: Option<String>,
    pub exit_on_forward_failure: Option<bool>,
    pub permit_remote_open: Vec<String>,
    
    // Host-based authentication
    pub hostbased_authentication: Option<bool>,
    pub hostbased_accepted_algorithms: Vec<String>,
}
// In parser.rs parse_option()
"certificatefile" => {
    if args.is_empty() {
        anyhow::bail!("CertificateFile requires a value at line {line_number}");
    }
    let path = secure_validate_path(args[0], "certificate", line_number)?;
    host.certificate_files.push(path);
}
"casignaturealgorithms" => {
    if args.is_empty() {
        anyhow::bail!("CASignatureAlgorithms requires a value at line {line_number}");
    }
    host.ca_signature_algorithms = args.join(",")
        .split(',')
        .map(|s| s.trim().to_string())
        .collect();
}
"gatewayports" => {
    if args.is_empty() {
        anyhow::bail!("GatewayPorts requires a value at line {line_number}");
    }
    let value = args[0].to_lowercase();
    if !["yes", "no", "clientspecified"].contains(&value.as_str()) {
        anyhow::bail!("Invalid GatewayPorts value at line {line_number}");
    }
    host.gateway_ports = Some(value);
}
"exitonforwardfailure" => {
    if args.is_empty() {
        anyhow::bail!("ExitOnForwardFailure requires a value at line {line_number}");
    }
    host.exit_on_forward_failure = Some(parse_yes_no(args[0], line_number)?);
}
"permitremoteopen" => {
    if args.is_empty() {
        anyhow::bail!("PermitRemoteOpen requires a value at line {line_number}");
    }
    host.permit_remote_open.extend(args.iter().map(|s| s.to_string()));
}

Testing Requirements

Certificate Authentication Tests:

  • Parse CertificateFile with tilde expansion
  • Multiple certificate files
  • CASignatureAlgorithms parsing
  • Invalid algorithm names

Port Forwarding Tests:

  • GatewayPorts yes/no/clientspecified
  • Invalid GatewayPorts values
  • ExitOnForwardFailure parsing
  • PermitRemoteOpen patterns
  • PermitRemoteOpen "none" and "any"

Integration Tests:

  • Certificate + identity file combination
  • Port forwarding with GatewayPorts
  • Forwarding failure behavior

Success Criteria

  • CertificateFile supports multiple files
  • CASignatureAlgorithms parses algorithm lists
  • GatewayPorts validates yes/no/clientspecified
  • ExitOnForwardFailure parses yes/no
  • PermitRemoteOpen handles patterns and special values
  • All options work with Option=Value syntax (from Support various Option syntax and additional SSH config options in parser #42)
  • Test coverage >85%
  • Documentation with examples
  • No breaking changes

Dependencies

References

Priority: High - Enterprise and production use cases

Estimated Complexity: Medium - Straightforward option additions

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions