Skip to content

Commit

Permalink
refactor: optimize pubkeys authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
windvalley committed Jan 16, 2024
1 parent 13bcf3b commit 8989e59
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 31 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Feel free to open a new issue if you have any issues, questions or suggestions a

- Auto detect following authentication methods for the login user(default `$USER`):
`Password`: from inventory file, or from flag `-k/--auth.ask-pass`,`-p/--auth.password`,`-a/--auth.pass-file`, or from configuration file.
`Pubkey Authentication`: by identity files(default `$HOME/.ssh/{id_rsa,id_dsa}`), also include that with passphrase.
`Pubkey Authentication`: by identity files(default `~/.ssh/id_rsa`), also include that with passphrase.
`SSH-Agent Authentication`: through the system environment variable `$SSH_AUTH_SOCK`.
If the above three authentication methods are valid at the same time, the priority order is: `SSH-Agent` > `Pubkey` > `Password`.

Expand All @@ -48,7 +48,7 @@ Feel free to open a new issue if you have any issues, questions or suggestions a

```text
alias_name_node1 host=node1.sre.im
alias_name_node2 host=192.168.33.12 port=8022 user=vagrant password=123456 keys=~/.ssh/id_dsa,~/.ssh/id_rsa passphrase=xxx
alias_name_node2 host=192.168.33.12 port=8022 user=vagrant password=123456 keys=~/.ssh/id_rsa passphrase=xxx
node3.sre.im user=vagrant password=GOSSH-AES256:9cfe499133b69a6c7fc62b5b6ba72d3d8dfb4d0e7987170a40c5d50bb5d71e19
```

Expand Down Expand Up @@ -148,7 +148,7 @@ Flags:
-p, --auth.password string password of login user
-k, --auth.ask-pass ask for the password of login user
-a, --auth.pass-file string file that holds the password of login user
-I, --auth.identity-files strings identity files (default $HOME/.ssh/{id_rsa,id_dsa})
-I, --auth.identity-files strings identity files (default ~/.ssh/id_rsa)
-K, --auth.passphrase string passphrase of the identity files
-V, --auth.vault-pass-file string text file or executable file that holds the vault password
for encryption and decryption
Expand Down
14 changes: 7 additions & 7 deletions docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ It will auto detect above three authentication methods for the login user. The d

`Password` can be from variable `password` that in inventory file, or from flag `-k/--auth.ask-pass`,`-p/--auth.password`,`-a/--auth.pass-file`, or from relative items in configuration file.

`Pubkey Authentication` is enabled by default through identity files(default `$HOME/.ssh/{id_rsa,id_dsa}` if not specified). The identity files with passphrase are also supported, you can use flag `-K, --auth.passphrase` to specify it.
`Pubkey Authentication` is enabled by default through identity files(default `~/.ssh/id_rsa` if not specified). The identity files with passphrase are also supported, you can use flag `-K, --auth.passphrase` to specify it.

If the system environment variable `$SSH_AUTH_SOCK` exists, `SSH-Agent Authentication` will be auto enabled.

Expand Down Expand Up @@ -36,10 +36,10 @@ $ gossh command target_host -e "uptime"
### Use Pubkey Authentication with no passphrase

```sh
# generate rsa or dsa
$ ssh-keygen -t dsa -f /path/id_rsa -N ""
# Generate identity files with no passphrase.
$ ssh-keygen -t rsa -f /path/id_rsa -N ""

# copy pubkey to target host
# Copy pubkey to target host.
$ ssh-copy-id -i /path/id_rsa target_host

# If /path/id_rsa is '~/.ssh/id_rsa', the flag '-I /path/id_rsa' can be omitted.
Expand All @@ -49,10 +49,10 @@ $ gossh command target_host -e "uptime" -I /path/id_rsa
### Use Pubkey Authentication with passphrase

```sh
# generate rsa or dsa
$ ssh-keygen -t dsa -f /path/id_rsa -N "the-passphrase"
# Generate identity files with passphrase.
$ ssh-keygen -t rsa -f /path/id_rsa -N "the-passphrase"

# copy pubkey to target host
# Copy pubkey to target host.
$ ssh-copy-id -i /path/id_rsa target_host

# If /path/id_rsa is '~/.ssh/id_rsa', the flag '-I /path/id_rsa' can be omitted.
Expand Down
2 changes: 1 addition & 1 deletion docs/inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ node100.sre.im
# hosts group
[webserver]
# host entry
alias_name_node2 host=192.168.33.12 port=8022 user=vagrant password=123456 keys=~/.ssh/id_dsa,~/.ssh/id_rsa passphrase=xxx
alias_name_node2 host=192.168.33.12 port=8022 user=vagrant password=123456 keys=~/.ssh/id_rsa passphrase=xxx
node[06-07].sre.im port=9022 user=lisi password=654321
node08.sre.im

Expand Down
3 changes: 1 addition & 2 deletions internal/pkg/configflags/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (a *Auth) AddFlagsTo(fs *pflag.FlagSet) {
fs.StringVarP(&a.PassFile, flagAuthPassFile, "a", a.PassFile,
`file that holds the password of login user`)
fs.StringSliceVarP(&a.IdentityFiles, flagAuthIdentityFiles, "I", nil,
"identity files (default $HOME/.ssh/{id_rsa,id_dsa})")
"identity files (default ~/.ssh/id_rsa)")
fs.StringVarP(&a.Passphrase, flagAuthPassphrase, "K", a.Passphrase,
"passphrase of the identity files")
fs.StringVarP(&a.VaultPassFile, flagAuthVaultPassFile, "V", a.VaultPassFile,
Expand Down Expand Up @@ -118,7 +118,6 @@ func getDefaultIdentityFiles() ([]string, error) {

identityFiles := []string{
fmt.Sprintf("%s/.ssh/id_rsa", home),
fmt.Sprintf("%s/.ssh/id_dsa", home),
}

return identityFiles, nil
Expand Down
33 changes: 18 additions & 15 deletions internal/pkg/sshtask/sshtask.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,10 @@ func (t *Task) batchRunSSH() {
authConf := t.configFlags.Auth
runConf := t.configFlags.Run

log.Debugf("Default Auth: login user '%s'", authConf.User)
log.Debugf("Auth: login user '%s'", authConf.User)

if runConf.Sudo {
log.Debugf("Default Auth: use sudo as user '%s'", runConf.AsUser)
log.Debugf("Auth: use sudo as user '%s'", runConf.AsUser)
}

t.setDefaultSSHAuthMethods()
Expand Down Expand Up @@ -592,28 +592,28 @@ func (t *Task) setDefaultSSHAuthMethods() {
if sshAuthSock != "" {
sshAgent, err = net.Dial("unix", sshAuthSock)
if err != nil {
log.Debugf("Default Auth: connect ssh-agent failed: %s", err)
log.Debugf("Auth: connect ssh-agent failed: %s", err)
} else {
log.Debugf("Default Auth: connected to SSH_AUTH_SOCK: %s", sshAuthSock)
log.Debugf("Auth: connected to SSH_AUTH_SOCK: %s", sshAuthSock)

signers, err = agent.NewClient(sshAgent).Signers()
if err != nil {
log.Debugf("Default Auth: parse ssh-agent failed: %v", err)
log.Debugf("Auth: parse ssh-agent failed: %v", err)
} else {
log.Debugf("Default Auth: parse ssh-agent success")
log.Debugf("Auth: parse ssh-agent success")
}
}

t.sshAgent = sshAgent
}

if len(t.defaultIdentityFiles) != 0 {
sshSigners := getSigners(t.defaultIdentityFiles, t.configFlags.Auth.Passphrase, "Default")
sshSigners := getSigners(t.defaultIdentityFiles, t.configFlags.Auth.Passphrase, "")

if len(sshSigners) != 0 {
signers = append(signers, sshSigners...)
} else {
log.Debugf("Default Auth: no valid default identity files")
log.Debugf("Auth: no valid default identity files")
}
}

Expand All @@ -624,12 +624,12 @@ func (t *Task) setDefaultSSHAuthMethods() {
if t.defaultPass != "" {
auths = append(auths, ssh.Password(t.defaultPass))
} else {
log.Debugf("Default Auth: password of the login user '%s' not provided", t.defaultUser)
log.Debugf("Auth: password of the login user '%s' not provided", t.defaultUser)
}

if t.defaultPass == "" && t.configFlags.Run.Sudo {
log.Debugf(
"Default Auth: using sudo as other user needs password. Prompt for password of the login user '%s'",
"Auth: using sudo as other user needs password. Prompt for password of the login user '%s'",
t.defaultUser,
)

Expand Down Expand Up @@ -700,20 +700,20 @@ func getDefaultPassword(auth *configflags.Auth) string {

password = strings.TrimSpace(string(passwordContent))

log.Debugf("Default Auth: read password of user '%s' from file '%s'", authFile, auth.User)
log.Debugf("Auth: read password of user '%s' from file '%s'", authFile, auth.User)
}

passwordFromFlag := auth.Password
if passwordFromFlag != "" {
password = passwordFromFlag

log.Debugf("Default Auth: received password of user '%s' from commandline flag or configuration file", auth.User)
log.Debugf("Auth: received password of user '%s' from commandline flag or configuration file", auth.User)
}

realPassword := getRealPass(password, "default", "password")

if auth.AskPass {
log.Debugf("Default Auth: ask for password of user '%s' by flag '-k/--auth.ask-pass'", auth.User)
log.Debugf("Auth: ask for password of user '%s' by flag '-k/--auth.ask-pass'", auth.User)
realPassword = getPasswordFromPrompt(auth.User)
}

Expand All @@ -739,7 +739,10 @@ func getSigners(keyfiles []string, passphrase string, authKind string) []ssh.Sig
msgHead string
)

msgHead = authKind + " Auth: "
msgHead = "Auth: "
if authKind != "" {
msgHead = authKind + " Auth: "
}

for _, f := range keyfiles {
signer, msg := getSigner(f, passphrase)
Expand Down Expand Up @@ -792,7 +795,7 @@ func getPasswordFromPrompt(loginUser string) string {

fmt.Println("")

log.Debugf("Default Auth: received password of the login user '%s' from terminal prompt", loginUser)
log.Debugf("Auth: received password of the login user '%s' from terminal prompt", loginUser)

return password
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/inventory/hosts_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ node100.sre.im

# hosts group
[webserver]
alias_name_node2 host=192.168.33.12 port=8022 user=vagrant password=123456 keys=~/.ssh/id_dsa,~/.ssh/id_rsa passphrase=xxx
alias_name_node2 host=192.168.33.12 port=8022 user=vagrant password=123456 keys=~/.ssh/id_rsa passphrase=xxx
node[06-07].sre.im port=9022 user=lisi password=654321
node08.sre.im

Expand Down
4 changes: 2 additions & 2 deletions pkg/inventory/inventory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ func TestGetAllHosts(t *testing.T) {
User: "vagrant",
Password: "123456",
Keys: []string{
"~/.ssh/id_dsa",
"~/.ssh/id_rsa",
"~/.ssh/id_ecdsa",
},
Passphrase: "xxx",
},
Expand Down Expand Up @@ -121,8 +121,8 @@ func TestGetHostsByGroup(t *testing.T) {
User: "vagrant",
Password: "123456",
Keys: []string{
"~/.ssh/id_dsa",
"~/.ssh/id_rsa",
"~/.ssh/id_ecdsa",
},
Passphrase: "xxx",
},
Expand Down

0 comments on commit 8989e59

Please sign in to comment.