Skip to content

Commit

Permalink
Improve the ssh_config README.md
Browse files Browse the repository at this point in the history
Signed-off-by: Kimmo Lehto <[email protected]>
  • Loading branch information
kke committed Apr 4, 2024
1 parent fd7d2ef commit 45ccc38
Showing 1 changed file with 48 additions and 48 deletions.
96 changes: 48 additions & 48 deletions sshconfig/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,32 @@ If there's interest, the parser can be extracted from the `rig` repository and p

### Usage

Typically you first create a parser via `sshconfig.NewParser(nil)` and then call `Apply` on it with a struct that you want to populate with the values for a given host from the system's ssh configuration files.
Typically you first create a parser via `sshconfig.NewParser(nil)` and then call `Apply(obj)` on it with a struct that you want to populate with the values for a given host from the system's ssh configuration files. You can also pass in an `io.Reader` to `NewParser` to read from a custom source instead of the default locations.

You can use the provided `sshconfig.Config` which includes all the known configuration fields or you can define a struct with a subset of the fields. The object must have the same field names as the `ssh_config` man page describes them and at least a "Host (string)" field must exist.
You can use the provided `sshconfig.Config` which includes all the known configuration fields or you can define a struct with only a subset of the fields. The object must have the same field names as listed in the `ssh_config` man page and at least a `Host string` field must exist for the parsing to work.

```go
package main

import(
"fmt"
"github.com/k0sproject/rig/v2/sshconfig"
"fmt"
"github.com/k0sproject/rig/v2/sshconfig"
)

func main() {
// this will read the configurations from the default locations.
parser, err := sshconfig.NewParser(nil)
// To read from a specific file or a string, pass in an io.Reader like:
// parser, err := sshconfig.NewParser(strings.NewReader("Host example.com\nIdentityFile ~/.ssh/id_rsa\n"))

if err != nil {
panic(err)
}
host := &sshconfig.Config{}
if err := parser.Apply(host, "example.com"); err != nil {
panic(err)
}
fmt.Println(host.IdentityFile[0])
// this will read the configurations from the default locations.
parser, err := sshconfig.NewParser(nil)
// To read from a specific file or a string, pass in an io.Reader like:
// parser, err := sshconfig.NewParser(strings.NewReader("Host example.com\nIdentityFile ~/.ssh/id_rsa\n"))

if err != nil {
panic(err)
}
host := &sshconfig.Config{}
if err := parser.Apply(host, "example.com"); err != nil {
panic(err)
}
fmt.Println(host.IdentityFile[0])
}
```

Expand All @@ -71,16 +71,16 @@ There's also a `sshconfig.ConfigFor` shorthand for when you're not expecting to
package main

import(
"fmt"
"github.com/k0sproject/rig/v2/sshconfig"
"fmt"
"github.com/k0sproject/rig/v2/sshconfig"
)

func main() {
config, err := sshconfig.ConfigFor("example.com")
if err != nil {
panic(err)
}
fmt.Println(config.IdentityFile[0])
config, err := sshconfig.ConfigFor("example.com")
if err != nil {
panic(err)
}
fmt.Println(config.IdentityFile[0])
}
```

Expand All @@ -90,28 +90,28 @@ You can output a `ssh_config` formatted string using `sshconfig.Dump`:
package main

import(
"fmt"
"github.com/k0sproject/rig/v2/sshconfig"
"fmt"
"github.com/k0sproject/rig/v2/sshconfig"
)

func main() {
config, err := sshconfig.ConfigFor("example.com")
if err != nil {
panic(err)
}
str, err := sshconfig.Dump(config)
fmt.Println(str)
config, err := sshconfig.ConfigFor("example.com")
if err != nil {
panic(err)
}
str, err := sshconfig.Dump(config)
fmt.Println(str)
}
```

This will output something like:

```text
Host example.com
AddKeysToAgent no
AddressFamily any
BatchMode no
...
AddKeysToAgent no
AddressFamily any
BatchMode no
...
```

### Alternatives
Expand All @@ -120,22 +120,22 @@ Currently there seems to exist two alternatives:

- [`kevinburke/ssh_config`](https://github.com/kevinburke/ssh_config)

This is a rather complete implementation but there are some issues with it:
This is a somewhat complete implementation but there are several issues with it:

- Does not support [`Match`](https://man.openbsd.org/ssh_config#Match) directives at all.
- Does not support [Hostname canonicalization](https://man.openbsd.org/ssh_config#CanonicalizeHostname).
- Not all of the Boolean fields listed [here](https://github.com/kevinburke/ssh_config/blob/1d09c0b50564c4a7f8c56c9d5d6d935e06ee94da/validators.go#L19) are actually strictly boolean. For example, `ForwardAgent` can be a path to agent socket or an environment variable name.
- Not all of the default values are correct or set. In fact, [the list of defaults](https://github.com/kevinburke/ssh_config/blame/1d09c0b50564c4a7f8c56c9d5d6d935e06ee94da/validators.go#L18) is from 2017. The default for `IdentityFile` is `~/.ssh/identity` which started to phase out upon the release of OpenSSH 3.0 in 2001 which started defaulting to `~/.ssh/id_dsa`.
- It does not support the list modifier prefixes for fields like `HostKeyAlgorithms` or `KexAlgorithms` where you can use `+` prefix to append to the existing list or `-` prefix to remove from the existing list.
- When you need to know multiple settings for a given host, you need to query for each setting separately. There doesn't seem to be a function that returns a list of settings that apply to a given host alias.
- Values need to be unquoted and expanded manually and values for comma separated list fields need to be split manually.
- No expansion of `~/` or environment variables in the values (there's a [pull request](https://github.com/kevinburke/ssh_config/pull/31) from 2021).
- No expansion of the [TOKENS](https://man.openbsd.org/ssh_config#TOKENS) (there's a [pull request](https://github.com/kevinburke/ssh_config/pull/49) from 2022).
- Doesn't seem to be actively maintained, there are open unanswered issues and unmerged pull requests from several years ago.
- Does not support [`Match`](https://man.openbsd.org/ssh_config#Match) directives at all.
- Does not support [Hostname canonicalization](https://man.openbsd.org/ssh_config#CanonicalizeHostname), which requires an additional pass of parsing if the hostname gets changed.
- Not all of the Boolean fields listed [here](https://github.com/kevinburke/ssh_config/blob/1d09c0b50564c4a7f8c56c9d5d6d935e06ee94da/validators.go#L19) are actually regular booleans. For example, `ForwardAgent` can be a path to an agent socket or an environment variable name.
- Not all of the default values are correct or set. In fact, [the list of defaults](https://github.com/kevinburke/ssh_config/blame/1d09c0b50564c4a7f8c56c9d5d6d935e06ee94da/validators.go#L18) is from 2017. The default for `IdentityFile` is [`~/.ssh/identity`](https://github.com/kevinburke/ssh_config/blob/1d09c0b50564c4a7f8c56c9d5d6d935e06ee94da/validators.go#L120) which started to phase out upon the release of OpenSSH 3.0 in 2001 which started defaulting to `~/.ssh/id_dsa`. The list of [`defaultProtocol2Identities`](https://github.com/kevinburke/ssh_config/blob/1d09c0b50564c4a7f8c56c9d5d6d935e06ee94da/validators.go#L165-L170) is not used and is missing a couple of entries.
- It does not support the list modifier prefixes for fields like `HostKeyAlgorithms` or `KexAlgorithms` where you can use the `+` or `^` prefixes to append or prepend to the default list or the `-` prefix to remove from it.
- When you need to know multiple settings for a given host, you have to query for each setting separately.
- Values need to be unquoted and expanded and converted to correct types manually and values for white-space or comma separated list fields need to be split manually.
- No expansion of `~/` or environment variables in the values (there's a [pull request](https://github.com/kevinburke/ssh_config/pull/31) from 2021).
- No expansion of the [TOKENS](https://man.openbsd.org/ssh_config#TOKENS) (there's a [pull request](https://github.com/kevinburke/ssh_config/pull/49) from 2022).
- Doesn't seem to be actively maintained, there are open unanswered issues and unmerged pull requests from several years ago. See [PR comment](https://github.com/kevinburke/ssh_config/pull/37#issuecomment-1095599334).

- [`mikkeloscar/sshconfig`](https://github.com/mikkeloscar/sshconfig)

This is a newer arrival. It supports a very limited subset of fields (`Host, HostName, User, Port, IdentityFile, HostKeyAlgorithms, ProxyCommand, LocalForward, RemoteForward, DynamicForward, Ciphers and MACs`). It implements even less features and quirks of the syntax.
A simplistic implementation that only supports a very limited subset of fields (`Host, HostName, User, Port, IdentityFile, HostKeyAlgorithms, ProxyCommand, LocalForward, RemoteForward, DynamicForward, Ciphers and MACs`). It implements even less features and quirks of the syntax. The GPL-3 license may be problematic for some.

### Contributing

Expand Down

0 comments on commit 45ccc38

Please sign in to comment.