diff --git a/command/ssh.go b/command/ssh.go index c3d8d08b7e..790e35762c 100644 --- a/command/ssh.go +++ b/command/ssh.go @@ -31,11 +31,13 @@ type SSHCredentialResp struct { } func (c *SSHCommand) Run(args []string) int { - var role, mountPoint, format string + var role, mountPoint, format, userKnownHostsFile, strictHostKeyChecking string var noExec bool var sshCmdArgs []string var sshDynamicKeyFileName string flags := c.Meta.FlagSet("ssh", meta.FlagSetDefault) + flags.StringVar(&strictHostKeyChecking, "strict-host-key-checking", "ask", "") + flags.StringVar(&userKnownHostsFile, "user-known-hosts-file", "~/.ssh/known_hosts", "") flags.StringVar(&format, "format", "table", "") flags.StringVar(&role, "role", "", "") flags.StringVar(&mountPoint, "mount-point", "ssh", "") @@ -150,7 +152,7 @@ func (c *SSHCommand) Run(args []string) int { // Feel free to try and remove this dependency. sshpassPath, err := exec.LookPath("sshpass") if err == nil { - sshCmdArgs = append(sshCmdArgs, []string{"-p", string(resp.Key), "ssh", "-p", resp.Port, username + "@" + ip.String()}...) + sshCmdArgs = append(sshCmdArgs, []string{"-p", string(resp.Key), "ssh", "-o UserKnownHostsFile=" + userKnownHostsFile, "-o StrictHostKeyChecking=" + strictHostKeyChecking, "-p", resp.Port, username + "@" + ip.String()}...) sshCmd := exec.Command(sshpassPath, sshCmdArgs...) sshCmd.Stdin = os.Stdin sshCmd.Stdout = os.Stdout @@ -163,7 +165,7 @@ func (c *SSHCommand) Run(args []string) int { c.Ui.Output("OTP for the session is " + resp.Key) c.Ui.Output("[Note: Install 'sshpass' to automate typing in OTP]") } - sshCmdArgs = append(sshCmdArgs, []string{"-p", resp.Port, username + "@" + ip.String()}...) + sshCmdArgs = append(sshCmdArgs, []string{"-o UserKnownHostsFile=" + userKnownHostsFile, "-o StrictHostKeyChecking=" + strictHostKeyChecking, "-p", resp.Port, username + "@" + ip.String()}...) sshCmd := exec.Command("ssh", sshCmdArgs...) sshCmd.Stdin = os.Stdin @@ -261,24 +263,35 @@ General Options: ` + meta.GeneralOptionsUsage() + ` SSH Options: - -role Role to be used to create the key. - Each IP is associated with a role. To see the associated - roles with IP, use "lookup" endpoint. If you are certain - that there is only one role associated with the IP, you can - skip mentioning the role. It will be chosen by default. If - there are no roles associated with the IP, register the - CIDR block of that IP using the "roles/" endpoint. + -role Role to be used to create the key. + Each IP is associated with a role. To see the associated + roles with IP, use "lookup" endpoint. If you are certain + that there is only one role associated with the IP, you can + skip mentioning the role. It will be chosen by default. If + there are no roles associated with the IP, register the + CIDR block of that IP using the "roles/" endpoint. - -no-exec Shows the credentials but does not establish connection. + -no-exec Shows the credentials but does not establish connection. - -mount-point Mount point of SSH backend. If the backend is mounted at - 'ssh', which is the default as well, this parameter can be - skipped. + -mount-point Mount point of SSH backend. If the backend is mounted at + 'ssh', which is the default as well, this parameter can be + skipped. - -format If no-exec option is enabled, then the credentials will be - printed out and SSH connection will not be established. The - format of the output can be 'json' or 'table'. JSON output - is useful when writing scripts. Default is 'table'. + -format If no-exec option is enabled, then the credentials will be + printed out and SSH connection will not be established. The + format of the output can be 'json' or 'table'. JSON output + is useful when writing scripts. Default is 'table'. + + -strict-host-key-checking This option corresponds to StrictHostKeyChecking of SSH configuration. + If 'sshpass' is employed to enable automated login, then if host key + is not "known" to the client, 'vault ssh' command will fail. Set this + option to "no" to bypass the host key checking. Defaults to "ask". + + -user-known-hosts-file This option corresponds to UserKnownHostsFile of SSH configuration. + Assigns the file to use for storing the host keys. If this option is + set to "/dev/null" along with "-strict-host-key-checking=no", both + warnings and host key checking can be avoided while establishing the + connection. Defaults to "~/.ssh/known_hosts". ` return strings.TrimSpace(helpText) } diff --git a/website/source/docs/secrets/ssh/index.html.md b/website/source/docs/secrets/ssh/index.html.md index 0d562906bc..4c554c59c4 100644 --- a/website/source/docs/secrets/ssh/index.html.md +++ b/website/source/docs/secrets/ssh/index.html.md @@ -79,7 +79,7 @@ Success! Data written to: ssh/roles/otp_key_role ### Create a Credential -Create an OTP credential for an IP that belongs to `otp_key_role`. +Create an OTP credential for an IP of the remote host that belongs to `otp_key_role`. ```text $ vault write ssh/creds/otp_key_role ip=x.x.x.x @@ -117,10 +117,13 @@ Password: The OTP will be entered automatically using `sshpass` if it is installed. ```text -$ vault ssh -role otp_key_role username@x.x.x.x -username@ip:~$ +$ vault ssh -role otp_key_role -strict-host-key-checking=no username@x.x.x.x +username@:~$ ``` +Note: `sshpass` cannot handle host key checking. Host key checking can be +disabled by setting `-strict-host-key-checking=no`. + ---------------------------------------------------- ## II. Dynamic Key Type @@ -222,7 +225,7 @@ To see the default, see [linux_install_script.go](https://github.com/hashicorp/v ### Create a credential -Create a dynamic key for an IP that is covered by `dynamic_key_role`'s CIDR +Create a dynamic key for an IP of the remote host that is covered by `dynamic_key_role`'s CIDR list. ```text @@ -270,8 +273,8 @@ Save the key to a file (e.g. `dyn_key.pem`) and then use it to establish an SSH session. ```text -$ ssh -i dyn_key.pem username@ip -username@ip:~$ +$ ssh -i dyn_key.pem username@ +username@:~$ ``` ### Automate it! @@ -280,8 +283,8 @@ Creation of new key, saving to a file, and using it to establish an SSH session can all be done with a single Vault CLI command. ```text -$ vault ssh -role dynamic_key_role username@ip -username@ip:~$ +$ vault ssh -role dynamic_key_role username@ +username@:~$ ``` ----------------------------------------------------