Vault SSH: Made port number configurable

This commit is contained in:
Vishal Nayak
2015-07-06 16:56:45 -04:00
parent 2bc139dfd1
commit 6f86d32089
5 changed files with 33 additions and 13 deletions

View File

@@ -91,13 +91,13 @@ func (b *backend) pathRoleCreateWrite(
dynamicPublicKey, dynamicPrivateKey, _ := generateRSAKeys()
// Transfer the public key to target machine
err = uploadPublicKeyScp(dynamicPublicKey, username, ip, hostKey.Key)
err = uploadPublicKeyScp(dynamicPublicKey, username, ip, role.Port, hostKey.Key)
if err != nil {
return nil, err
}
// Add the public key to authorized_keys file in target machine
err = installPublicKeyInTarget(username, ip, hostKey.Key)
err = installPublicKeyInTarget(username, ip, role.Port, hostKey.Key)
if err != nil {
return nil, fmt.Errorf("error adding public key to authorized_keys file in target")
}
@@ -109,6 +109,7 @@ func (b *backend) pathRoleCreateWrite(
"ip": ip,
"host_key_name": role.KeyName,
"dynamic_public_key": dynamicPublicKey,
"port": role.Port,
})
// Change the lease information to reflect user's choice

View File

@@ -33,6 +33,10 @@ func pathRoles(b *backend) *framework.Path {
Type: framework.TypeString,
Description: "CIDR blocks and IP addresses",
},
"port": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Port number for SSH connection",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
@@ -52,6 +56,7 @@ func (b *backend) pathRoleWrite(req *logical.Request, d *framework.FieldData) (*
adminUser := d.Get("admin_user").(string)
defaultUser := d.Get("default_user").(string)
cidr := d.Get("cidr").(string)
port := d.Get("port").(string)
// Input validations
if roleName == "" {
@@ -66,6 +71,7 @@ func (b *backend) pathRoleWrite(req *logical.Request, d *framework.FieldData) (*
if cidr == "" {
return logical.ErrorResponse("Missing cidr blocks"), nil
}
for _, item := range strings.Split(cidr, ",") {
_, _, err := net.ParseCIDR(item)
if err != nil {
@@ -81,12 +87,16 @@ func (b *backend) pathRoleWrite(req *logical.Request, d *framework.FieldData) (*
if defaultUser == "" {
defaultUser = adminUser
}
if port == "" {
port = "22"
}
entry, err := logical.StorageEntryJSON(fmt.Sprintf("policy/%s", roleName), sshRole{
KeyName: keyName,
AdminUser: adminUser,
DefaultUser: defaultUser,
CIDR: cidr,
Port: port,
})
if err != nil {
@@ -119,6 +129,7 @@ func (b *backend) pathRoleRead(req *logical.Request, d *framework.FieldData) (*l
"admin_user": role.AdminUser,
"default_user": role.DefaultUser,
"cidr": role.CIDR,
"port": role.Port,
},
}, nil
}
@@ -137,6 +148,7 @@ type sshRole struct {
AdminUser string `json:"admin_user"`
DefaultUser string `json:"default_user"`
CIDR string `json: "cidr"`
Port string `json: "port"`
}
const pathRoleHelpSyn = `

View File

@@ -75,6 +75,11 @@ func (b *backend) secretSSHKeyRevoke(req *logical.Request, d *framework.FieldDat
if !ok {
return nil, fmt.Errorf("secret is missing internal data")
}
portRaw, ok := req.Secret.InternalData["port"]
if !ok {
return nil, fmt.Errorf("secret is missing internal data")
}
port := portRaw.(string)
// Fetch the host key using the key name
hostKeyEntry, err := req.Storage.Get(fmt.Sprintf("keys/%s", hostKeyName))
@@ -87,13 +92,13 @@ func (b *backend) secretSSHKeyRevoke(req *logical.Request, d *framework.FieldDat
}
// Transfer the dynamic public key to target machine and use it to remove the entry from authorized_keys file
err = uploadPublicKeyScp(dynamicPublicKey, username, ip, hostKey.Key)
err = uploadPublicKeyScp(dynamicPublicKey, username, ip, port, hostKey.Key)
if err != nil {
return nil, fmt.Errorf("public key transfer failed: %s", err)
}
// Remove the public key from authorized_keys file in target machine
err = uninstallPublicKeyInTarget(username, ip, hostKey.Key)
err = uninstallPublicKeyInTarget(username, ip, port, hostKey.Key)
if err != nil {
return nil, fmt.Errorf("error removing public key from authorized_keys file in target")
}

View File

@@ -19,9 +19,9 @@ import (
// Transfers the file to the target machine by establishing an SSH session with the target.
// Uses the public key authentication method and hence the parameter 'key' takes in the private key.
// The fileName parameter takes an absolute path.
func uploadPublicKeyScp(publicKey, username, ip, key string) error {
func uploadPublicKeyScp(publicKey, username, ip, port, key string) error {
dynamicPublicKeyFileName := fmt.Sprintf("vault_ssh_%s_%s.pub", username, ip)
session, err := createSSHPublicKeysSession(username, ip, key)
session, err := createSSHPublicKeysSession(username, ip, port, key)
if err != nil {
return err
}
@@ -44,7 +44,7 @@ func uploadPublicKeyScp(publicKey, username, ip, key string) error {
// Creates a SSH session object which can be used to run commands in the target machine.
// The session will use public key authentication method with port 22.
func createSSHPublicKeysSession(username, ipAddr, hostKey string) (*ssh.Session, error) {
func createSSHPublicKeysSession(username, ipAddr, port, hostKey string) (*ssh.Session, error) {
if username == "" {
return nil, fmt.Errorf("missing username")
}
@@ -66,7 +66,7 @@ func createSSHPublicKeysSession(username, ipAddr, hostKey string) (*ssh.Session,
},
}
client, err := ssh.Dial("tcp", ipAddr+":22", config)
client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", ipAddr, port), config)
if err != nil {
return nil, err
}
@@ -103,8 +103,8 @@ func generateRSAKeys() (publicKeyRsa string, privateKeyRsa string, err error) {
}
// Concatenates the public present in that target machine's home folder to ~/.ssh/authorized_keys file
func installPublicKeyInTarget(username, ip, hostKey string) error {
session, err := createSSHPublicKeysSession(username, ip, hostKey)
func installPublicKeyInTarget(username, ip, port, hostKey string) error {
session, err := createSSHPublicKeysSession(username, ip, port, hostKey)
if err != nil {
return fmt.Errorf("unable to create SSH Session using public keys: %s", err)
}
@@ -133,8 +133,8 @@ func installPublicKeyInTarget(username, ip, hostKey string) error {
}
// Removes the installed public key from the authorized_keys file in target machine
func uninstallPublicKeyInTarget(username, ip, hostKey string) error {
session, err := createSSHPublicKeysSession(username, ip, hostKey)
func uninstallPublicKeyInTarget(username, ip, port, hostKey string) error {
session, err := createSSHPublicKeysSession(username, ip, port, hostKey)
if err != nil {
return fmt.Errorf("unable to create SSH Session using public keys: %s", err)
}

View File

@@ -18,8 +18,10 @@ type SSHCommand struct {
func (c *SSHCommand) Run(args []string) int {
var role string
var port string
flags := c.Meta.FlagSet("ssh", FlagSetDefault)
flags.StringVar(&role, "role", "", "")
flags.StringVar(&port, "port", "22", "")
flags.Usage = func() { c.Ui.Error(c.Help()) }
if err := flags.Parse(args); err != nil {
return 1
@@ -70,7 +72,7 @@ func (c *SSHCommand) Run(args []string) int {
sshDynamicKeyFileName := fmt.Sprintf("vault_temp_file_%s_%s", username, ip.String())
err = ioutil.WriteFile(sshDynamicKeyFileName, []byte(sshDynamicKey), 0600)
cmd := exec.Command("ssh", "-i", sshDynamicKeyFileName, args[0])
cmd := exec.Command("ssh", "-p", port, "-i", sshDynamicKeyFileName, args[0])
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
err = cmd.Run()