Overview of assh
masterProxyCommand in lib-ssh, it integrates seamlessly with standard tools like ssh, scp, rsync, git, and various desktop applications (e.g., Tower, Atom, SSH Tunnel Manager).repository·master·Indexed 25 days ago
https://github.com/moul/asshA transparent SSH wrapper that extends standard SSH capabilities with regex matching, aliases, gateways, and dynamic hostnames. It integrates with tools like ssh, scp, rsync, and git by managing the ~/.ssh/config file and providing a ProxyCommand implementation. Key features include YAML-based configuration, connection lifecycle hooks, Graphviz visualization, and support for chained gateways using host/gateway syntax.
ProxyCommand in lib-ssh, it integrates seamlessly with standard tools like ssh, scp, rsync, git, and various desktop applications (e.g., Tower, Atom, SSH Tunnel Manager).Follow these steps to transition to assh:
cp ~/.ssh/config ~/.ssh/config.backup.touch ~/.ssh/assh.yml.~/.ssh/assh.yml.assh config build > ~/.ssh/config.ssh alias to your shell profile to enable automatic updates.cp ~/.ssh/config ~/.ssh/config.backup
assh config build > ~/.ssh/configThe primary configuration file is ~/.ssh/assh.yml. It supports the following top-level sections:
hosts: A dictionary of host definitions.templates: Definitions that can be inherited by hosts but cannot be SSH'd into directly.defaults: Global flags applied to all hosts.includes: Paths to other configuration files to be merged.Warning: assh manages your ~/.ssh/config file. It is highly recommended to keep a backup of your existing ~/.ssh/config before starting.
To use assh as the SSH executable for Ansible, update your ansible.cfg file under the [ssh_connection] section. Replace the path with the actual location of your assh binary followed by the wrapper ssh command.
[ssh_connection]
ansible_ssh_executable = '/usr/local/bin/assh wrapper ssh'[ssh_connection]
ansible_ssh_executable = '/usr/local/bin/assh wrapper ssh'You can use assh to transparently chain SSH connections using the host/gateway syntax. This is equivalent to manually configuring complex ProxyCommand settings in OpenSSH.
hosta using hostb as a gateway, use:
ssh hosta/hostbhosta through multiple gateways (e.g., hostb then hostc), use:
ssh hosta/hostb/hostc$ ssh hosta/hostb
$ ssh hosta/hostb/hostcIn ~/.ssh/assh.yml, you can define hosts with various properties including Hostname, User, Port, Gateways, Inherits, and Aliases.
Key Features:
Inherits: [template_name] to pull settings from a template or another host.Gateways to allow fallback access (e.g., trying direct access before using a gateway).vm-*.school.com or *.shortcut1 for host definitions.ResolveCommand to dynamically determine host details (e.g., via shell commands or CLI tools like scw).${HOSTNAME} or user-$USER for dynamic values.hosts:
homer:
Hostname: 1.2.3.4
User: robert
Port: 2222
bart:
Hostname: 5.6.7.8
User: bart
Gateways:
- direct
- homer
maggie:
User: maggie
Inherits: bart
templates:
bart-template:
User: bartTo ensure ssh always uses the most up-to-date configuration generated by assh (especially when using advanced pattern matching), it is highly recommended to alias ssh to the assh wrapper. Add this to your .bashrc, .zshrc, or config.fish:
alias ssh="assh wrapper ssh --"alias ssh="assh wrapper ssh --"Assh supports hooks that trigger at specific lifecycle events. You can use different drivers to handle these events:
exec <binary> [args...]: Executes a shell command. These are blocking by default unless you background the process (e.g., exec sleep 60 &).write <line:string...>: Writes formatted text to stdout.notify <line:string...>: Triggers desktop notifications (macOS built-in, Linux via gnotifier).BeforeConnect: Called before attempting to connect to the remote port. Called for each gateway in a chain.OnConnect: Called immediately after a successful connection to the remote port.OnConnectError: Called when a TCP connection fails.OnDisconnect: Called when the socket is closed.BeforeConfigWrite: Called before assh rewrites the ~/.ssh/config file.AfterConfigWrite: Called after the config file is rewritten.You can install assh using several methods depending on your environment:
Using Go (Recommended): Requires Go 1.7 or above.
Using Homebrew (macOS):
brew install asshTo build from the latest HEAD:
brew install assh --HEADUsing asdf-vm:
asdf plugin add assh
asdf install assh latest
asdf global assh latestgo install moul.io/assh/v2@latestYou can define lifecycle hooks in the defaults section of ~/.ssh/assh.yml to execute commands at specific stages:
BeforeConfigWrite: Runs before assh rewrites the ~/.ssh/config file.AfterConfigWrite: Runs after the config file is updated.OnConnect: Runs when an SSH connection is established.OnDisconnect: Runs when an SSH connection is closed.Available template variables include {{.SSHConfigPath}}, {{.Host}}, {{.Stats.ConnectedAt}}, {{.Stats.WrittenBytes}}, and {{.Stats.ConnectionDuration}}.
defaults:
Hooks:
OnConnect:
- notify New SSH connection to {{.Host.Prototype}}
OnDisconnect:
- "notify SSH connection to {{.Host.HostName}} closed"To use slashes in your ControlPath option without manual directory management, enable ControlMasterMkdir in your host configuration or globally.
ControlMasterMkdir: trueDefine connection chains in your assh.yml configuration file using the Gateways key. You can also specify a GatewayConnectTimeout and use a list of gateways to provide fallback behavior.
If a list is provided, assh will attempt to connect directly first (if direct is included) or follow the order of the list. This allows for high-performance direct connections with reliable fallbacks when remote/external.
hosts:
hosta:
Hostname: 1.2.3.4
hostb:
Hostname: 5.6.7.8
Gateways: hosta
hostc:
Hostname: 9.10.11.12
Gateways: hostb
hostd:
Hostname: 13.14.15.16
GatewayConnectTimeout: 2
Gateways:
- direct
- hosta