Skip to content

espeer/ssh-auth-cmd

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ssh-auth-cmd Configuration and Setup

Overview

ssh-auth-cmd is a Rust application designed to chain multiple SSH AuthorizedKeysCommand configurations, since OpenSSH only supports configuring a single one. The new version supports individual configuration files, user switching, comprehensive OpenSSH placeholder support, and automatic installation.

Installation

  1. Build the application:
cargo build --release
  1. Install the binary:
sudo cp target/release/ssh-auth-cmd /usr/local/bin/
sudo chmod +x /usr/local/bin/ssh-auth-cmd
  1. Install using the built-in installer (recommended):
sudo /usr/local/bin/ssh-auth-cmd install

Or with a specific user:

sudo /usr/local/bin/ssh-auth-cmd install --user nobody

Configuration Directory Structure

Commands are now configured in individual TOML files in /etc/ssh/auth_cmd.d/:

/etc/ssh/auth_cmd.d/
├── 01-local-keys.toml
├── 02-ldap-keys.toml
├── 03-database-keys.toml
└── 99-emergency-keys.toml

Files are processed in alphabetical order, so you can use prefixes to control execution order.

Configuration File Format

Each configuration file contains a single command definition:

Example: /etc/ssh/auth_cmd.d/01-local-keys.toml

name = "local_keys"
command = "cat"
args = ["/home/%u/.ssh/authorized_keys"]
enabled = true
timeout = 30
user = "nobody"
readonly = false

Example: /etc/ssh/auth_cmd.d/02-ldap-keys.toml

name = "ldap_keys"
command = "/usr/local/bin/ldap-ssh-keys"
args = ["--user", "%u", "--hostname", "%h", "--connection", "%C"]
enabled = true
timeout = 60
user = "ldap-user"
readonly = false

Example: /etc/ssh/auth_cmd.d/03-audit-only.toml

name = "audit_logger"
command = "/usr/local/bin/ssh-audit-log"
args = ["--user", "%u", "--key-type", "%t", "--fingerprint", "%f"]
enabled = true
timeout = 10
user = "audit"
readonly = true  # Don't include output in authorized keys

Configuration Options

Required Fields

  • name: A descriptive name for the command
  • command: The command/script to execute

Optional Fields

  • args: Array of arguments to pass to the command
  • enabled: Whether this command is enabled (default: true)
  • timeout: Timeout in seconds for command execution (default: 30)
  • user: UNIX user to run the command as (only when ssh-auth-cmd runs as root)
  • readonly: If true, discard stdout output (useful for logging/auditing)

OpenSSH Placeholder Support

The following OpenSSH placeholders are supported in the args array:

  • %C: Connection specification (user, client IP, client port, server IP, server port)
  • %D: Routing domain
  • %f: Key fingerprint
  • %h: Hostname
  • %k`: Key being offered for authentication
  • %t: Key type
  • %U: Original username (before any transformations)
  • %u: Username being authenticated
  • %%: Literal % character

Example with Multiple Placeholders

name = "comprehensive_auth"
command = "/usr/local/bin/auth-checker"
args = [
    "--user", "%u",
    "--original-user", "%U", 
    "--hostname", "%h",
    "--connection", "%C",
    "--key-type", "%t",
    "--fingerprint", "%f",
    "--key", "%k",
    "--domain", "%D",
    "--literal-percent", "%%"
]

OpenSSH Configuration

When using the install command, ssh-auth-cmd configures OpenSSH as:

AuthorizedKeysCommand /usr/local/bin/ssh-auth-cmd key-cmd -c %C -D %D -f %f -h %h -k %k -t %t -U %U -u %u
AuthorizedKeysCommandUser root

This exhaustively uses all OpenSSH substitution variables currently defined.

User Switching

When ssh-auth-cmd runs as root (recommended), you can specify different users for each command:

  • If user is specified in a command config, that command runs as the specified user
  • If user is not specified, the command runs as the same user as ssh-auth-cmd
  • If ssh-auth-cmd is not running as root, the user field is ignored

This allows for principle of least privilege - each command can run with only the permissions it needs.

Commands and Usage

Key Command Mode (used by OpenSSH)

ssh-auth-cmd key-cmd -c %C -D %D -f %f -h %h -k %k -t %t -U %U -u %u

This is the mode OpenSSH calls. It processes all enabled configurations and outputs authorized keys.

Configuration Check

sudo ssh-auth-cmd config-check

Validates:

  • Configuration directory and file permissions
  • Configuration file syntax
  • Placeholder substitution validity
  • Command binary permissions
  • That all command binaries are only writable by root

Installation

# Install with default settings (AuthorizedKeysCommandUser root)
sudo ssh-auth-cmd install

# Install with specific user
sudo ssh-auth-cmd install --user nobody

# Install with custom sshd_config location
sudo ssh-auth-cmd install --config /etc/ssh/sshd_config.custom

The install command:

  • Migrates existing AuthorizedKeysCommand to a config file in /etc/ssh/auth_cmd.d/
  • Comments out the old configuration
  • Adds the new ssh-auth-cmd configuration
  • Preserves existing AuthorizedKeysCommandUser settings when migrating
  • Will not overwrite existing files in /etc/ssh/auth_cmd.d/

Security Considerations

File Permissions

All configuration files and the configuration directory must have secure permissions:

# Set proper permissions
sudo chown -R root:root /etc/ssh/auth_cmd.d/
sudo chmod 755 /etc/ssh/auth_cmd.d/
sudo chmod 600 /etc/ssh/auth_cmd.d/*.toml

The config-check command verifies these permissions automatically.

Command Security

  • All configured command binaries must be owned by root and not writable by others
  • Commands run with the privileges of the specified user (or the user running ssh-auth-cmd)
  • Use the readonly flag for commands that should only log/audit without providing keys

User Isolation

Different commands can run as different users for security isolation:

  • LDAP queries might run as a dedicated ldap-auth user
  • Database queries might run as a db-auth user
  • Local file access might run as nobody
  • Audit logging might run as an audit user

Example Configurations

Basic Local + LDAP Setup

/etc/ssh/auth_cmd.d/01-local.toml:

name = "local_keys"
command = "cat"
args = ["/home/%u/.ssh/authorized_keys"]
enabled = true
timeout = 30
user = "nobody"

/etc/ssh/auth_cmd.d/02-ldap.toml:

name = "ldap_lookup"
command = "/usr/local/bin/ldap-ssh-keys"
args = ["--user", "%u", "--hostname", "%h"]
enabled = true
timeout = 60
user = "ldap-auth"

Enterprise Setup with Audit Trail

/etc/ssh/auth_cmd.d/01-audit.toml:

name = "connection_audit"
command = "/usr/local/bin/log-ssh-attempt"
args = [
    "--user", "%u",
    "--original-user", "%U",
    "--connection", "%C",
    "--hostname", "%h",
    "--key-fingerprint", "%f",
    "--key-type", "%t"
]
enabled = true
timeout = 10
user = "audit"
readonly = true  # Just for logging, don't provide keys

/etc/ssh/auth_cmd.d/02-corporate-keys.toml:

name = "corporate_ldap"
command = "/usr/local/bin/corporate-auth"
args = ["--user", "%u", "--domain", "corp.example.com"]
enabled = true
timeout = 60
user = "corp-auth"

/etc/ssh/auth_cmd.d/03-emergency.toml:

name = "emergency_access"
command = "/usr/local/bin/emergency-keys"
args = ["--user", "%u", "--validate-emergency"]
enabled = true
timeout = 30
user = "emergency-auth"

Development/Testing Setup

/etc/ssh/auth_cmd.d/01-local.toml:

name = "local_keys"
command = "cat"
args = ["/home/%u/.ssh/authorized_keys"]
enabled = true
timeout = 30

/etc/ssh/auth_cmd.d/02-shared-dev.toml:

name = "shared_dev_keys"
command = "cat"
args = ["/etc/ssh/shared_dev_keys"]
enabled = true
timeout = 10

Migration from Single Configuration

If you're migrating from the original single-file configuration:

  1. Run the install command to automatically migrate:
sudo ssh-auth-cmd install
  1. The installer will:

    • Move your existing AuthorizedKeysCommand to a config file
    • Comment out the old configuration
    • Install the new ssh-auth-cmd configuration
  2. Verify the migration:

sudo ssh-auth-cmd config-check

Troubleshooting

Configuration Issues

# Check all configurations
sudo ssh-auth-cmd config-check

# Test manually for a specific user
sudo ssh-auth-cmd key-cmd -u testuser

# Test with full OpenSSH context
sudo ssh-auth-cmd key-cmd -c "testuser,192.168.1.100,22,10.0.0.1,22" -u testuser -h hostname.example.com

Permission Problems

# Fix directory permissions
sudo chown -R root:root /etc/ssh/auth_cmd.d/
sudo chmod 755 /etc/ssh/auth_cmd.d/
sudo chmod 600 /etc/ssh/auth_cmd.d/*.toml

# Check command permissions
ls -la /usr/local/bin/your-auth-command

SSH Debug Mode

Enable SSH debug logging to see what's happening:

# In /etc/ssh/sshd_config
LogLevel DEBUG

# Then check logs
sudo tail -f /var/log/auth.log

Common Issues

  1. "Configuration directory is writable by group or others"

    • Fix: sudo chmod 755 /etc/ssh/auth_cmd.d/
  2. "Configuration file is writable by group or others"

    • Fix: sudo chmod 600 /etc/ssh/auth_cmd.d/*.toml
  3. "Command is not owned by root"

    • Fix: sudo chown root:root /path/to/command
  4. "Invalid placeholder"

    • Check that you're only using supported placeholders: %C, %D, %f, %h, %k, %t, %U, %u, %%
  5. "User not found"

    • Ensure the user specified in the user field exists on the system

Performance Considerations

  • Commands run sequentially in alphabetical order by filename
  • Set appropriate timeouts to prevent hanging connections
  • Use readonly = true for audit/logging commands that don't provide keys
  • Consider disabling unnecessary commands in production environments

Best Practices

  1. Naming Convention: Use numbered prefixes (01-, 02-, etc.) to control execution order
  2. User Separation: Run different commands as different users for security isolation
  3. Timeouts: Set conservative timeouts to prevent hanging SSH connections
  4. Auditing: Use readonly commands for comprehensive audit logging
  5. Testing: Always test configurations with config-check before deployment
  6. Monitoring: Monitor command execution times and failure rates
  7. Backup: Keep backups of working configurations before making changes

Integration Examples

With HashiCorp Vault

name = "vault_ssh_ca"
command = "/usr/local/bin/vault-ssh-helper"
args = ["-mode", "ca", "-username", "%u"]
enabled = true
timeout = 45
user = "vault-ssh"

With FreeIPA/Red Hat IdM

name = "ipa_keys"
command = "/usr/bin/sss_ssh_authorizedkeys"
args = ["%u"]
enabled = true
timeout = 30
user = "sssd"

With Custom Database

name = "db_keys"
command = "/usr/local/bin/db-ssh-keys"
args = [
    "--user", "%u",
    "--client-ip", "%C",
    "--hostname", "%h"
]
enabled = true
timeout = 60
user = "db-auth"

This comprehensive setup provides a secure, flexible, and maintainable way to chain multiple SSH authentication sources while maintaining full OpenSSH compatibility and security best practices.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%