Vault SSH: POC Stage 1. Skeleton implementation.

This commit is contained in:
Vishal Nayak 2015-06-16 16:58:54 -04:00
parent 3331950d7e
commit 08c921c75e
7 changed files with 294 additions and 0 deletions

View file

@ -0,0 +1,48 @@
package ssh
import (
"log"
"strings"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
func Factory(map[string]string) (logical.Backend, error) {
return Backend(), nil
}
func Backend() *framework.Backend {
log.Printf("Vishal: ssh.Backend\n")
var b backend
b.Backend = &framework.Backend{
Help: strings.TrimSpace(backendHelp),
PathsSpecial: &logical.Paths{
Root: []string{"config/*"},
},
Paths: []*framework.Path{
pathConfigLease(&b),
pathConfigAddHostKey(&b),
pathConfigRemoveHostKey(&b),
pathRoles(&b),
},
Secrets: []*framework.Secret{
secretOneTimeKey(&b),
},
}
return b.Backend
}
type backend struct {
*framework.Backend
}
const backendHelp = `
The ssh backend enables secure connections to remote hosts.
After mounting this backend, configure it using the endpoints within
the "config/" path.
`

View file

@ -0,0 +1,47 @@
package ssh
import (
"log"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
func pathConfigAddHostKey(b *backend) *framework.Path {
log.Printf("Vishal: ssh.pathConfigAddHostKey\n")
return &framework.Path{
Pattern: "config/addhostkey",
Fields: map[string]*framework.FieldSchema{
"username": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Username in host.",
},
"ip": &framework.FieldSchema{
Type: framework.TypeString,
Description: "IP address of host.",
},
"key": &framework.FieldSchema{
Type: framework.TypeString,
Description: "SSH private key for host.",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.WriteOperation: b.pathAddHostKeyWrite,
},
HelpSynopsis: pathConfigAddHostKeySyn,
HelpDescription: pathConfigAddHostKeyDesc,
}
}
func (b *backend) pathAddHostKeyWrite(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
log.Printf("Vishal: ssh.pathAddHostKeyWrite\n")
return nil, nil
}
const pathConfigAddHostKeySyn = `
pathConfigAddHostKeySyn
`
const pathConfigAddHostKeyDesc = `
pathConfigAddHostKeyDesc
`

View file

@ -0,0 +1,52 @@
package ssh
import (
"log"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
func pathConfigLease(b *backend) *framework.Path {
log.Printf("Vishal: ssh.pathConfigLease\n")
return &framework.Path{
Pattern: "config/lease",
Fields: map[string]*framework.FieldSchema{
"lease": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Default lease for roles.",
},
"lease_max": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Maximum time a credential is valid for.",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.WriteOperation: b.pathLeaseWrite,
},
HelpSynopsis: pathConfigLeaseHelpSyn,
HelpDescription: pathConfigLeaseHelpDesc,
}
}
func (b *backend) pathLeaseWrite(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
log.Printf("Vishal: ssh.pathLeaseWrite\n")
return nil, nil
}
const pathConfigLeaseHelpSyn = `
Configure the default lease information for SSH one time keys.
`
const pathConfigLeaseHelpDesc = `
This configures the default lease information used for SSH one time keys
generated by this backend. The lease specifies the duration that a
credential will be valid for, as well as the maximum session for
a set of credentials.
The format for the lease is "1h" or integer and then unit. The longest
unit is hour.
`

View file

@ -0,0 +1,47 @@
package ssh
import (
"log"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
func pathConfigRemoveHostKey(b *backend) *framework.Path {
log.Printf("Vishal: ssh.pathConfigRemoveHostKey\n")
return &framework.Path{
Pattern: "config/removehostkey",
Fields: map[string]*framework.FieldSchema{
"username": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Username in host.",
},
"ip": &framework.FieldSchema{
Type: framework.TypeString,
Description: "IP address of host.",
},
"key": &framework.FieldSchema{
Type: framework.TypeString,
Description: "SSH private key for host.",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.WriteOperation: b.pathRemoveHostKeyWrite,
},
HelpSynopsis: pathConfigRemoveHostKeySyn,
HelpDescription: pathConfigRemoveHostKeyDesc,
}
}
func (b *backend) pathRemoveHostKeyWrite(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
log.Printf("Vishal: ssh.pathRemoveHostKeyWrite\n")
return nil, nil
}
const pathConfigRemoveHostKeySyn = `
pathConfigRemoveHostKeySyn
`
const pathConfigRemoveHostKeyDesc = `
pathConfigRemoveHostKeyDesc
`

View file

@ -0,0 +1,57 @@
package ssh
import (
"log"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
func pathRoles(b *backend) *framework.Path {
log.Printf("Vishal: ssh.pathRoles\n")
return &framework.Path{
Pattern: "roles/(?P<name>\\w+)",
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Name of the role",
},
"policy": &framework.FieldSchema{
Type: framework.TypeString,
Description: "String representing the policy for the role. See help for more info.",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.pathRoleRead,
logical.WriteOperation: b.pathRoleWrite,
logical.DeleteOperation: b.pathRoleDelete,
},
HelpSynopsis: pathRoleHelpSyn,
HelpDescription: pathRoleHelpDesc,
}
}
func (b *backend) pathRoleRead(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
log.Printf("Vishal: ssh.pathRoleRead\n")
return nil, nil
}
func (b *backend) pathRoleWrite(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
log.Printf("Vishal: ssh.pathRoleWrite\n")
return nil, nil
}
func (b *backend) pathRoleDelete(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
log.Printf("Vishal: ssh.pathRoleDelete\n")
return nil, nil
}
const pathRoleHelpSyn = `
Manage the roles that can be created with this backend.
`
const pathRoleHelpDesc = `
This path lets you manage the roles that can be created with this backend.
`

View file

@ -0,0 +1,41 @@
package ssh
import (
"log"
"time"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
const SecretOneTimeKeyType = "one_time_key"
func secretOneTimeKey(b *backend) *framework.Secret {
log.Printf("Vishal: ssh.secretPrivateKey\n")
return &framework.Secret{
Type: SecretOneTimeKeyType,
Fields: map[string]*framework.FieldSchema{
"username": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Username in host",
},
"ip": &framework.FieldSchema{
Type: framework.TypeString,
Description: "ip address of host",
},
"one_time_key": &framework.FieldSchema{
Type: framework.TypeString,
Description: "SSH one-time-key for host",
},
},
DefaultDuration: 1 * time.Hour,
DefaultGracePeriod: 10 * time.Minute,
Renew: framework.LeaseExtend(1*time.Hour, 0),
Revoke: b.secretPrivateKeyRevoke,
}
}
func (b *backend) secretPrivateKeyRevoke(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
log.Printf("Vishal: ssh.secretPrivateKeyRevoke\n")
return nil, nil
}

View file

@ -16,6 +16,7 @@ import (
"github.com/hashicorp/vault/builtin/logical/consul"
"github.com/hashicorp/vault/builtin/logical/mysql"
"github.com/hashicorp/vault/builtin/logical/postgresql"
"github.com/hashicorp/vault/builtin/logical/ssh"
"github.com/hashicorp/vault/builtin/logical/transit"
"github.com/hashicorp/vault/audit"
@ -67,6 +68,7 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
"postgresql": postgresql.Factory,
"transit": transit.Factory,
"mysql": mysql.Factory,
"ssh": ssh.Factory,
},
}, nil
},