From a98b3befd9c9d291fa61a727dd1bc6f399f2faaa Mon Sep 17 00:00:00 2001 From: vishalnayak Date: Fri, 14 Aug 2015 12:41:26 -0700 Subject: [PATCH] Vault SSH: Website page for SSH backend --- builtin/logical/ssh/path_config_lease.go | 4 +- builtin/logical/ssh/path_creds_create.go | 6 +- builtin/logical/ssh/path_keys.go | 8 +- builtin/logical/ssh/path_lookup.go | 2 +- builtin/logical/ssh/path_roles.go | 2 +- builtin/logical/ssh/path_verify.go | 2 +- command/ssh.go | 2 +- website/source/docs/secrets/ssh/index.html.md | 621 ++++++++++++++++-- 8 files changed, 566 insertions(+), 81 deletions(-) diff --git a/builtin/logical/ssh/path_config_lease.go b/builtin/logical/ssh/path_config_lease.go index ba6131a870..a5b495d551 100644 --- a/builtin/logical/ssh/path_config_lease.go +++ b/builtin/logical/ssh/path_config_lease.go @@ -19,11 +19,11 @@ func pathConfigLease(b *backend) *framework.Path { Fields: map[string]*framework.FieldSchema{ "lease": &framework.FieldSchema{ Type: framework.TypeString, - Description: "Default lease for roles.", + Description: "[Required] Default lease for roles.", }, "lease_max": &framework.FieldSchema{ Type: framework.TypeString, - Description: "Maximum time a credential is valid for.", + Description: "[Required] Maximum time a credential is valid for.", }, }, diff --git a/builtin/logical/ssh/path_creds_create.go b/builtin/logical/ssh/path_creds_create.go index c50e9e2e46..d8b969c2bc 100644 --- a/builtin/logical/ssh/path_creds_create.go +++ b/builtin/logical/ssh/path_creds_create.go @@ -22,15 +22,15 @@ func pathCredsCreate(b *backend) *framework.Path { Fields: map[string]*framework.FieldSchema{ "role": &framework.FieldSchema{ Type: framework.TypeString, - Description: "Name of the role", + Description: "[Required] Name of the role", }, "username": &framework.FieldSchema{ Type: framework.TypeString, - Description: "Username in target", + Description: "[Optional] Username in remote host", }, "ip": &framework.FieldSchema{ Type: framework.TypeString, - Description: "IP of the target machine", + Description: "[Required] IP of the remote host", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ diff --git a/builtin/logical/ssh/path_keys.go b/builtin/logical/ssh/path_keys.go index cdd3810ba3..e320594e9b 100644 --- a/builtin/logical/ssh/path_keys.go +++ b/builtin/logical/ssh/path_keys.go @@ -19,11 +19,11 @@ func pathKeys(b *backend) *framework.Path { Fields: map[string]*framework.FieldSchema{ "key_name": &framework.FieldSchema{ Type: framework.TypeString, - Description: "Name of the key", + Description: "[Required] Name of the key", }, "key": &framework.FieldSchema{ Type: framework.TypeString, - Description: "SSH private key with root privileges for host", + Description: "[Required] SSH private key with super user privileges in host", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -80,6 +80,10 @@ func (b *backend) pathKeysDelete(req *logical.Request, d *framework.FieldData) ( func (b *backend) pathKeysWrite(req *logical.Request, d *framework.FieldData) (*logical.Response, error) { keyName := d.Get("key_name").(string) + if keyName == "" { + return logical.ErrorResponse("Missing key_name"), nil + } + keyString := d.Get("key").(string) signer, err := ssh.ParsePrivateKey([]byte(keyString)) diff --git a/builtin/logical/ssh/path_lookup.go b/builtin/logical/ssh/path_lookup.go index e4643349ea..33f02632b9 100644 --- a/builtin/logical/ssh/path_lookup.go +++ b/builtin/logical/ssh/path_lookup.go @@ -14,7 +14,7 @@ func pathLookup(b *backend) *framework.Path { Fields: map[string]*framework.FieldSchema{ "ip": &framework.FieldSchema{ Type: framework.TypeString, - Description: "IP address of target", + Description: "[Required] IP address of remote host", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ diff --git a/builtin/logical/ssh/path_roles.go b/builtin/logical/ssh/path_roles.go index 067d432a43..9f9db1119d 100644 --- a/builtin/logical/ssh/path_roles.go +++ b/builtin/logical/ssh/path_roles.go @@ -96,7 +96,7 @@ func pathRoles(b *backend) *framework.Path { [Optional for dynamic type][Not-applicable for otp type] Script used to install and uninstall public keys in the target machine. The inbuilt default install script will be for Linux hosts. For sample - script, refer the project's documentation website.`, + script, refer the project documentation website.`, }, "allowed_users": &framework.FieldSchema{ Type: framework.TypeString, diff --git a/builtin/logical/ssh/path_verify.go b/builtin/logical/ssh/path_verify.go index bd3682ec05..7ad232ec33 100644 --- a/builtin/logical/ssh/path_verify.go +++ b/builtin/logical/ssh/path_verify.go @@ -12,7 +12,7 @@ func pathVerify(b *backend) *framework.Path { Fields: map[string]*framework.FieldSchema{ "otp": &framework.FieldSchema{ Type: framework.TypeString, - Description: "One-time-key for SSH session", + Description: "[Required] One-Time-Key that needs to be validated", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ diff --git a/command/ssh.go b/command/ssh.go index 559d453265..2983a591f8 100644 --- a/command/ssh.go +++ b/command/ssh.go @@ -144,7 +144,7 @@ func (c *SSHCommand) Run(args []string) int { } return 0 } - c.Ui.Output("OTP for the session is" + string(keySecret.Data["key"].(string))) + c.Ui.Output("OTP for the session is " + string(keySecret.Data["key"].(string))) c.Ui.Output("[Note: Install 'sshpass' to automate typing in OTP]") } sshCmdArgs = append(sshCmdArgs, []string{"-p", port}...) diff --git a/website/source/docs/secrets/ssh/index.html.md b/website/source/docs/secrets/ssh/index.html.md index 6aba81d6a9..da21d3bedd 100644 --- a/website/source/docs/secrets/ssh/index.html.md +++ b/website/source/docs/secrets/ssh/index.html.md @@ -10,28 +10,44 @@ description: |- Name: `ssh` -The SSH secret backend for Vault generates SSH credentials dynamically. This solves -the problem of managing private keys of the infrastructure. There are 2 options -available with this backend. -1) Dynamic Type: Registering private keys (having root privileges) with Vault. Vault then issues -leased dynamic credentials to Vault authenticated users. Vault uses the registered -private key to install a new key for the user in the target host. This key will -be a long lived key and gets deleted only after the lease is expired. After the -user receiving the dynamic keys, Vault will have no control on the sessions created -with that key and hence the sessions will not be audited. Which brings us to option 2. +The SSH secret backend for Vault generates SSH credentials dynamically. This backend +increases the security and solves the problem of management and distribution of keys +belonging to remote hosts. This backend provides two ways of credential creation. +Both of them addresses the problem in different ways. Understand both of them and +choose the one which best suits your needs. -2) One-Time-Password (OTP) Type: Installing Vault-SSH agent in the target machines -and enabling challenge response mechanism for client authentication. Vault server -issues a OTP upon user request. During authentication, agent acts as a PAM module -and validates the password with Vault server. Since Vault server is contacted for -every SSH session establishment, they all get audited. +---------------------------------------------------- +## I. Dynamic Type -## Quick Start +Register the shared secret key (having super user privileges) with Vault and let +Vault take care of issuing a dynamic secret key every time a client wants to SSH +into the remote host. + +When a Vault authenticated client requests for a credential, Vault server creates +a key-pair, uses the previously shared secret key to login to the remote host and +appends the newly generated public key to ~/.ssh/authorized_keys file of the desired +username. Vault uses a install script (configurable) to achieve this. + +To run the script without prompts, password requests for sudoers should be disabled at +remote hosts. + +File: `/etc/sudoers` + +```hcl +%sudo ALL=(ALL)NOPASSWD: ALL +``` + +The private key returned to the user will be leased and can be renewed if desired. +Once the key is given to the user, Vault has no control on how and when the keys +will be used. Therefore, Vault **WILL NOT** and cannot audit the SSH session establishments. +OTP type audits every SSH request (see below). + +### Mounting SSH `ssh` backend is not mounted by default. So, the first step in using the SSH backend is to mount it. -```text +```shell $ vault mount ssh Successfully mounted 'ssh' at 'ssh'! ``` @@ -39,22 +55,40 @@ Successfully mounted 'ssh' at 'ssh'! Next, we must register infrastructures with Vault. This is done by writing the role information. The type of credentials created are determined by the key_type option. -### Dynamic key type +### Registering shared secret key -Create a named key, say "dev_key", in Vault which represents a registered shared key. +Create a named key, say `dev_key`, which represents a registered shared private key. -```text +```shell $ vault write ssh/keys/dev_key key=@dev_shared_key.pem ``` -Assuming that the target machine is hosted on Linux, create a script "key-linux-install.sh" -that can install the given public key in the authorized keys file. +### Create a Role -```text +Create a role, say `dynamic_key_role`. All the machines represented by CIDR block +should be accessible through `dev_key` with root privileges. + +```shell +$ vault write ssh/roles/dynamic_key_role key_type=dynamic key=dev_key admin_user=username default_user=username cidr_list=x.x.x.x/y +Success! Data written to: ssh/roles/dynamic_key_role +``` + +Use the `install_script` option to provide an install script if hosts does not +resemble typical Linux machine. The default script is very straight forward and +is shown below. The script takes three arguments which are explained in the comments. + +```shell # This script file installs or uninstalls an RSA public key to/from authoried_keys # file in a typical linux machine. This script should be registered with vault # server while creating a role for key type 'dynamic'. +# $1: "install" or "uninstall" +# +# $2: File name containing public key to be installed. Vault server uses UUID +# as file name to avoid collisions with public keys generated for requests. +# +# $3: Absolute path of the authorized_keys file. + if [ $1 != "install" && $1 != "uninstall" ]; then exit 1 fi @@ -64,85 +98,532 @@ fi grep -vFf $2 $3 > temp_$2 # Contents of temporary file will be the contents of authorized_keys file. -cat temp_$2 > $3 +cat temp_$2 | sudo tee $3 if [ $1 == "install" ]; then # New public key is appended to authorized_keys file -cat $2 >> $3 +cat $2 | sudo tee --append $3 fi # Auxiliary files are deleted rm -f $2 temp_$2 ``` -Create a role "dynamic_key_role". All the machines represented by CIDR block -should be accessible through "dev_key" with root privileges. +### Create a credential -```text -$ vault write ssh/roles/dynamic_key_role key_type=dynamic key=dev_key admin_user=foo default_user=bar cidr=x.x.x.x/y install_script=@key-linux-install.sh -``` +Create a dynamic key for an IP that belongs to `dynamic_key_role`. -Create a dynamic key for an IP that belongs to the "dynamic_key_role". - -```text +```shell $ vault write ssh/creds/dynamic_key_role ip=x.x.x.x Key Value -lease_id ssh/creds/dynamic_key_role/862d55c9-e54e-917c-4c8f-f6e1a54b2e51 +lease_id ssh/creds/dynamic_key_role/8c4d2042-23bc-d6a8-42c2-6ff01cb83cf8 lease_duration 600 lease_renewable true -key_type dynamic +ip x.x.x.x key -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- +key_type dynamic +port 22 +username username ``` -Save the key to a file, say "dyn_key.pem", and then use it to establish an SSH session. +### Establish an SSH session -```text +Save the key to a file, say `dyn_key.pem`, and then use it to establish an SSH session. + +```shell $ ssh -i dyn_key.pem username@ip username@ip:~$ ``` -Creating new keys, saving it in a file and establishing an SSH session will all be done +### Automate it! + +Creation of new key, saving it in a file and establishing an SSH session will all be done via a single Vault CLI. -```text +```shell $ vault ssh -role dynamic_key_role username@ip username@ip:~$ ``` +---------------------------------------------------- +## II. One-Time-Password (OTP) Type -### OTP key type +Install Vault SSH Agent in remote hosts and let Vault server issue an OTP every time +a client wants to SSH into remote hosts. -Create a role "otp_key_role" of key type "otp". All the machines represented by CIDR -block should have Vault SSH agent installed and challenge response mechanism enabled -as detailed in https://github.com/hashicorp/vault-ssh-agent. +Vault authenticated clients request for a credential from Vault server and get an OTP +issued. When clients try to establish SSH connection with the remote host, OTP typed +in at the password prompt will be received by the Vault agent and gets validated +by the Vault server. Vault server deletes the OTP after validating it once (hence one-time). -```text -$ vault write ssh/roles/otp_key_role key_type=otp default_user=bar cidr=x.x.x.x/y +Since Vault server is contacted for every successful connection establishment, unlike +Dynamic type, every login attempt **WILL** be audited. + +Agent in remote hosts act as a client authentication PAM module. See [Vault-SSH-Agent] +(https://github.com/hashicorp/vault-ssh-agent) for configuring agent. + +### Mounting SSH + +`ssh` backend is not mounted by default and needs to be explicitly mounted. This is +a common step for both OTP and Dynamic types. + +```shell +$ vault mount ssh +Successfully mounted 'ssh' at 'ssh'! ``` -Create an OTP +### Creating a Role + +Create a role, say `otp_key_role` for key type `otp`. All the machines represented +by CIDR block should have agent installed in them and have their SSH configuration +modified to support Vault SSH Agent client authentication. + +```shell +$ vault write ssh/roles/otp_key_role key_type=otp default_user=username cidr_list=x.x.x.x/y,m.m.m.m/n +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`. + +```shell +$ vault write ssh/creds/otp_key_role ip=x.x.x.x +Key Value +lease_id ssh/creds/otp_key_role/73bbf513-9606-4bec-816c-5a2f009765a5 +lease_duration 600 +lease_renewable false +port 22 +username username +ip x.x.x.x +key 2f7e25a2-24c9-4b7b-0d35-27d5e5203a5c +key_type otp +``` + +### Establish an SSH session + +```shell +$ ssh username@localhost +Password: +username@ip:~$ +``` + +### Automate it! + +Creation of new OTP and running SSH command can be done via a single CLI. + +```shell +$ vault ssh -role otp_key_role username@x.x.x.x +OTP for the session is `b4d47e1b-4879-5f4e-ce5c-7988d7986f37` +[Note: Install `sshpass` to automate typing in OTP] +Password: +``` + +OTP will be typed in using `sshpass` if it is installed. + +```shell +$ vault ssh -role otp_key_role username@x.x.x.x +username@ip:~$ +``` +---------------------------------------------------- + +## API + +### /ssh/config/lease +#### POST + +
+
Description
+
+ Configures the lease settings for generated credentials. + This is a root protected endpoint. +
+ +
Method
+
POST
+ +
URL
+
`/ssh/config/lease`
+ +
Parameters
+
+
    +
  • + lease + required + (String) The lease value provided as a duration + with time suffix. Hour is the largest suffix. +
  • +
  • + lease_max + required + (String) The maximum lease value provided as a duration + with time suffix. Hour is the largest suffix. +
  • +
+
+ +
Returns
+
+ A `204` response code. +
+
+ +### /ssh/keys/ +#### POST + +
+
Description
+
+ Creates or updates a named key. This is a root protected endpoint. +
+ +
Method
+
POST
+ +
URL
+
`/ssh/keys/`
+ +
Parameters
+
+
    +
  • + key + required + (String) SSH private key with super user privileges in host +
  • +
+
+ +
Returns
+
+ A `204` response code. +
+ +#### GET + +
+
Description
+
+ Queries a named key. This is a root protected endpoint. +
+ +
Method
+
GET
+ +
URL
+
`/ssh/keys/`
+ +
Parameters
+
None
+ +
Returns
+
+ +```javascript +{ + "key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAvYvoRcWRxqOim5VZnuM6wHCbLUeiND0yaM1tvOl+Fsrz55DG\nA0OZp4RGAu1Fgr46E1mzxFz1+zY4UbcEExg+u21fpa8YH8sytSWW1FyuD8ICib0A\n/l8slmDMw4BkkGOtSlEqgscpkpv/TWZD1NxJWkPcULk8z6c7TOETn2/H9mL+v2RE\nmbE6NDEwJKfD3MvlpIqCP7idR+86rNBAODjGOGgyUbtFLT+K01XmDRALkV3V/nh+\nGltyjL4c6RU4zG2iRyV5RHlJtkml+UzUMkzr4IQnkCC32CC/wmtoo/IsAprpcHVe\nnkBn3eFQ7uND70p5n6GhN/KOh2j519JFHJyokwIDAQABAoIBAHX7VOvBC3kCN9/x\n+aPdup84OE7Z7MvpX6w+WlUhXVugnmsAAVDczhKoUc/WktLLx2huCGhsmKvyVuH+\nMioUiE+vx75gm3qGx5xbtmOfALVMRLopjCnJYf6EaFA0ZeQ+NwowNW7Lu0PHmAU8\nZ3JiX8IwxTz14DU82buDyewO7v+cEr97AnERe3PUcSTDoUXNaoNxjNpEJkKREY6h\n4hAY676RT/GsRcQ8tqe/rnCqPHNd7JGqL+207FK4tJw7daoBjQyijWuB7K5chSal\noPInylM6b13ASXuOAOT/2uSUBWmFVCZPDCmnZxy2SdnJGbsJAMl7Ma3MUlaGvVI+\nTfh1aQkCgYEA4JlNOabTb3z42wz6mz+Nz3JRwbawD+PJXOk5JsSnV7DtPtfgkK9y\n6FTQdhnozGWShAvJvc+C4QAihs9AlHXoaBY5bEU7R/8UK/pSqwzam+MmxmhVDV7G\nIMQPV0FteoXTaJSikhZ88mETTegI2mik+zleBpVxvfdhE5TR+lq8Br0CgYEA2AwJ\nCUD5CYUSj09PluR0HHqamWOrJkKPFPwa+5eiTTCzfBBxImYZh7nXnWuoviXC0sg2\nAuvCW+uZ48ygv/D8gcz3j1JfbErKZJuV+TotK9rRtNIF5Ub7qysP7UjyI7zCssVM\nkuDd9LfRXaB/qGAHNkcDA8NxmHW3gpln4CFdSY8CgYANs4xwfercHEWaJ1qKagAe\nrZyrMpffAEhicJ/Z65lB0jtG4CiE6w8ZeUMWUVJQVcnwYD+4YpZbX4S7sJ0B8Ydy\nAhkSr86D/92dKTIt2STk6aCN7gNyQ1vW198PtaAWH1/cO2UHgHOy3ZUt5X/Uwxl9\ncex4flln+1Viumts2GgsCQKBgCJH7psgSyPekK5auFdKEr5+Gc/jB8I/Z3K9+g4X\n5nH3G1PBTCJYLw7hRzw8W/8oALzvddqKzEFHphiGXK94Lqjt/A4q1OdbCrhiE68D\nMy21P/dAKB1UYRSs9Y8CNyHCjuZM9jSMJ8vv6vG/SOJPsnVDWVAckAbQDvlTHC9t\nO98zAoGAcbW6uFDkrv0XMCpB9Su3KaNXOR0wzag+WIFQRXCcoTvxVi9iYfUReQPi\noOyBJU/HMVvBfv4g+OVFLVgSwwm6owwsouZ0+D/LasbuHqYyqYqdyPJQYzWA2Y+F\n+B6f4RoPdSXj24JHPg/ioRxjaj094UXJxua2yfkcecGNEuBQHSs=\n-----END RSA PRIVATE KEY-----\n" +} +``` +
+ + +#### DELETE + +
+
Description
+
+ Deletes a named key. This is a root protected endpoint. +
+ +
Method
+
DELETE
+ +
URL
+
`/ssh/keys/`
+ +
Parameters
+
None
+ +
Returns
+
+ A `204` response code. +
+ +### /ssh/roles/ +#### POST + +
+
Description
+
+ Creates or updates a named role. +
+ +
Method
+
POST
+ +
URL
+
`/ssh/roles/`
+ +
Parameters
+
+
    +
  • + key + required for dynamic type, NA for otp type + Name of the registered key in Vault. Before creating the role, use the `keys/` + endpoint to create a named key. +
  • +
  • + admin_user + required for dynamic type, NA for otp type + Admin user at remote host. The shared key being registered should be + for this user and should have root privileges. Everytime a dynamic + credential is being generated for other users, Vault uses this admin + username to login to remote host and install the generated credential + for the other user. +
  • +
  • + default_user + required for both types + Default username for which a credential will be generated. + When the endpoint 'creds/' is used without a username, this + value will be used as default username. +
  • +
  • + cidr_list + required for both types + Comma separated list of CIDR blocks for which the role is applicable for. + CIDR blocks can belong to more than one role. +
  • +
  • + port + optional for both types + Port number for SSH connection. Default is '22'. Port number does not + play any role in creation of OTP. For 'otp' type, this is just a way + to inform client about the port number to use. Port number will be + returned to client by Vault server along with OTP. +
  • +
  • + key_type + required for both types + Type of key used to login to hosts. It can be either `otp` or `dynamic`. + `otp` type requires agent to be installed in remote hosts. +
  • +
  • + key_bits + optional for dynamic type, NA for otp type + Length of the RSA dynamic key in bits. It can be one of 1024, 2048 or 4096. +
  • +
  • + install_script + optional for dynamic type, NA for otp type + Script used to install and uninstall public keys in the target machine. + The inbuilt default install script will be for Linux hosts. +
  • +
  • + allowed_users + optional for both types + If this option is not specified, client can request for a credential for + any valid user at the remote host, including the admin user. If only certain + usernames are to be allowed, then this list enforces it. If this field is + set, then credentials can only be created for default_user and usernames + present in this list. +
  • +
+
+ +
Returns
+
+ A `204` response code. +
+ +#### GET + +
+
Description
+
+ Queries a named role. +
+ +
Method
+
GET
+ +
URL
+
`/ssh/roles/`
+ +
Parameters
+
None
+ +
Returns
+
For dynamic role: + +```json +{ + "admin_user": "username", + "cidr_list": "x.x.x.x/y", + "default_user": "username", + "key": "", + "key_type": "dynamic", + "port": 22 +} +``` +
+ +
For OTP role: + +```json +{ + "cidr_list": "x.x.x.x/y", + "default_user": "username", + "key_type": "otp", + "port": 22 +} +``` +
+ + +#### DELETE + +
+
Description
+
+ Deletes a named role. +
+ +
Method
+
DELETE
+ +
URL
+
`/ssh/roles/`
+ +
Parameters
+
None
+ +
Returns
+
+ A `204` response code. +
+### /ssh/creds/ +#### POST + +
+
Description
+
+ Creates a credential for a specific username and IP under the given role. +
+ +
Method
+
POST
+ +
URL
+
`/ssh/creds/`
+ +
Parameters
+
+
    +
  • + username + optional + Username in remote host. +
  • +
  • + ip + required + IP of the remote host. +
  • +
+
+ +
Returns
+
+ A `204` response code. +
+ +### /ssh/lookup +#### POST + +
+
Description
+
+ Lists all the roles given IP is associated with. +
+ +
Method
+
POST
+ +
URL
+
`/ssh/lookup`
+ +
Parameters
+
+
    +
  • + ip + required + IP of the remote host. +
  • +
+
+ +
Returns
+
+ A `204` response code. +
+ +### /ssh/verify +#### POST + +
+
Description
+
+ Verifies if the given OTP is valid. This is an unauthenticated endpoint. +
+ +
Method
+
POST
+ +
URL
+
`/ssh/verify`
+ +
Parameters
+
+
    +
  • + otp + required + One-Time-Key that needs to be validated. +
  • +
+
+ +
Returns
+
+ A `204` response code. +
+