A less verbose and more legible way to manage .ssh/config
Go to file
2024-07-18 19:09:00 -06:00
src Parser: switch true/false to yes/no 2024-07-17 21:57:55 -06:00
systemd README: fix systemd target 2024-07-18 19:09:00 -06:00
tests Parser: switch true/false to yes/no 2024-07-17 21:57:55 -06:00
.gitignore Test: ignore .log files 2024-07-17 20:58:50 -06:00
LICENSE.md Init 2024-05-26 17:11:24 -06:00
README.md Parser: switch true/false to yes/no 2024-07-17 21:57:55 -06:00

SSH Compose Pro

Streamline repetitive ssh config files with trait-style property inheritance!

ssh_compose_pro is meant for users with very large and repetitive ssh configs. This includes templating, an inheretence-style way of copying fields, and for loops to reduce repetitive lines.

See the example/ directory for an idea of capabilities, but here's a snippet:

__preamble:
  ssh_props:
    Port: 22
    IdentitiesOnly: yes
    ForwardX11: no

__uni_template:
  template: __preamble
  ssh_props:
    IdentityFile: ~/.ssh/computer_labs_key
    User: emiliko

undergrad:
  template: __uni_template
  ssh_props:
    Hostname: ug22.cs.ualberta.ca

ohaton:
  template: __uni_template
  ssh_props:
    Hostname: ohaton.cs.ualberta.ca

coronation:
  template: __uni_template
  ssh_props:
    Hostname: coronation.cs.ualberta.ca

Quick Start

Convert your ~/.ssh/config into an ~/.ssh/config.yaml by following the rules below. Eventually we hope to have a conversion script, but not yet...

Run src/main.py on your ~/.ssh/config.yaml to convert it!

Systemd Integration

You can have systemd automatically run ssh_compose_pro when your yaml file changes!

Move the files under systemd/ to ~/.config/systemd/user and update the paths to match your system. Next:

systemctl --user enable --now ssh-compose-pro.path
journalctl --user -fu ssh-compose-pro.service

Make a change to your yaml file, and you should see the output appear in the terminal running journalctl. You can ^C the journalctl command, it'll still update on change.

Rules

SSH Properties

Standard SSH config properties go under the ssh_props heading for every host. For example:

Host github.com
    Hostname github.com
    IdentityFile ~/.ssh/github_main
    LocalForward 3306 localhost:3306
    LocalForward 3302 localhost:3302
    LocalForward 3000 localhost:3000

Becomes:

github.com:
  ssh_props:
    Hostname: github.com
    IdentityFile: ~/.ssh/github_main
    LocalForward:
      - 3306 localhost:3306
      - 3302 localhost:3302
      - 3000 localhost:3000

Note that yaml does not support duplicate keys, so keys can take a list of properties instead to mimic repeated keys, as seen above.

Templates

Templates are "default" properties inherited from another host. Templates must be declared above the host that uses it. You can make a template-only host by declaring it with __ at the start of the name. You can also use another host as a template.

__preamble:
  ssh_props:
    Port: 22
    IdentitiesOnly: yes
    ForwardX11: no

#############################################################################
# Uni Computers
#############################################################################
__uni_template:
  template: __preamble
  ssh_props:
    IdentityFile: ~/.ssh/id_ed25519
    User: emiliko

ohaton:
  template: __uni_template
  ssh_props:
    Hostname: ohaton.cs.ualberta.ca

coronation:
  # Using __uni_template here would make more sense, but ohaton works too
  template: ohaton
  ssh_props:
    Hostname: coronation.cs.ualberta.ca

Will generate:

Host ohaton:
    ForwardX11 no
    Hostname ohaton.cs.ualberta.ca
    IdentitiesOnly yes
    IdentityFile ~/.ssh/id_ed25519
    Port 22
    User emiliko

Host coronation:
    ForwardX11 no
    Hostname coronation.cs.ualberta.ca
    IdentitiesOnly yes
    IdentityFile ~/.ssh/id_ed25519
    Port: 22
    User emiliko

As a note, properties inherited from templates will be overwritten entirely, even if they're multi-valued. For example:

__uni:
  ssh_props:
   LocalForward:
    - 3306 localhost:3306
    - 3302 localhost:3302
    - 3000 localhost:3000

ohaton:
  template: __uni
  ssh_props:
      LocalForward:
       - 9000 localhost:9000

Will overwrite all the LocalForward properties provided by the __uni template, generating:

Host ohaton
    LocalForward 9000 localhost:9000

For loops

For loops allow simple substitution of a single variable over a range or set of values. Ranges must be numerical, but sets can be any arbitrary string. Multiple different for loops can be declared under the for section.

orca:
  ssh_props:
    Hostname: 10.42.43.1
    User: emiliko
  for:
    - variable: port
      range: [9026, 9042, 1]
      property: LocalForward
      template: ${port} localhost:${port}
    - variable: env
      iter: ["FOO=bar", "BAR=foo"]
      property: SendEnv
      template: ${env}

Expands to:

Host orca
    Hostname 10.42.43.1
    LocalForward 9026 localhost:9026
    LocalForward 9027 localhost:9027
    LocalForward 9028 localhost:9028
    LocalForward 9029 localhost:9029
    LocalForward 9030 localhost:9030
    LocalForward 9031 localhost:9031
    LocalForward 9032 localhost:9032
    LocalForward 9033 localhost:9033
    LocalForward 9034 localhost:9034
    LocalForward 9035 localhost:9035
    LocalForward 9036 localhost:9036
    LocalForward 9037 localhost:9037
    LocalForward 9038 localhost:9038
    LocalForward 9039 localhost:9039
    LocalForward 9040 localhost:9040
    LocalForward 9041 localhost:9041
    SendEnv FOO=bar
    SendEnv BAR=foo
    User emiliko

For loops can be part of templates