mirror of
https://github.com/gravitational/teleport
synced 2024-10-19 16:53:57 +00:00
Finished replicated backend
This commit is contained in:
parent
e3d73ef08b
commit
97021dcf17
71
Makefile
71
Makefile
|
@ -8,6 +8,7 @@ install: remove-temp-files
|
|||
go install github.com/gravitational/teleport/teleport
|
||||
go install github.com/gravitational/teleport/tctl
|
||||
go install github.com/gravitational/teleport/telescope/telescope
|
||||
go install github.com/gravitational/teleport/telescope/telescope/tscopectl
|
||||
|
||||
install-assets:
|
||||
go get github.com/jteeuwen/go-bindata/go-bindata
|
||||
|
@ -53,47 +54,47 @@ run-auth: install
|
|||
--log=console\
|
||||
--log-severity=INFO\
|
||||
--data-dir=/tmp\
|
||||
--fqdn=auth.gravitational.io\
|
||||
--fqdn=auth.vendor.io\
|
||||
auth\
|
||||
--backend=bolt\
|
||||
--backend-config='{"path": "/tmp/teleport.auth.db"}'\
|
||||
--event-backend-config='{"path": "/tmp/teleport.event.db"}'\
|
||||
--record-backend-config='{"path": "/tmp/teleport.records.db"}'\
|
||||
--domain=gravitational.io\
|
||||
--domain=vendor.io\
|
||||
--ssh-addr=tcp://0.0.0.0:33000
|
||||
|
||||
run-ssh: install
|
||||
tctl token generate --output=/tmp/token --fqdn=node1.gravitational.io
|
||||
tctl token generate --output=/tmp/token --fqdn=node1.vendor.io
|
||||
teleport\
|
||||
--log=console\
|
||||
--log-severity=INFO\
|
||||
--data-dir=/tmp\
|
||||
--fqdn=node1.gravitational.io\
|
||||
--auth-server=tcp://0.0.0.0:33000\
|
||||
--fqdn=node1.vendor.io\
|
||||
--auth-server=tcp://auth.vendor.io:33000\
|
||||
ssh\
|
||||
--token=/tmp/token\
|
||||
|
||||
run-cp: install #install-assets
|
||||
run-cp: install
|
||||
teleport\
|
||||
--log=console\
|
||||
--log-severity=INFO\
|
||||
--data-dir=/tmp\
|
||||
--fqdn=node2.gravitational.io\
|
||||
--auth-server=tcp://127.0.0.1:33000\
|
||||
--fqdn=cp.vendor.io\
|
||||
--auth-server=tcp://auth.vendor.io:33000\
|
||||
cp\
|
||||
--domain=gravitational.io
|
||||
--domain=vendor.io
|
||||
|
||||
run-tun: install
|
||||
tctl token generate --output=/tmp/token --fqdn=node1.gravitational.io
|
||||
tctl token generate --output=/tmp/token --fqdn=tun.vendor.io
|
||||
teleport\
|
||||
--log=console\
|
||||
--log-severity=INFO\
|
||||
--data-dir=/var/lib/teleport\
|
||||
--fqdn=node1.gravitational.io\
|
||||
--auth-server=tcp://0.0.0.0:33000\
|
||||
--fqdn=auth.vendor.io\
|
||||
--auth-server=tcp://auth.vendor.io:33000\
|
||||
tun\
|
||||
--tun-token=/tmp/token\
|
||||
--tun-srv-addr=tcp://0.0.0.0:34000\
|
||||
--tun-srv-addr=tcp://telescope.vendor.io:34000\
|
||||
|
||||
|
||||
|
||||
|
@ -103,11 +104,11 @@ run-embedded: install
|
|||
--log=console\
|
||||
--log-severity=WARN\
|
||||
--data-dir=/var/lib/teleport\
|
||||
--fqdn=auth.gravitational.io\
|
||||
--fqdn=auth.vendor.io\
|
||||
auth\
|
||||
--backend=bolt\
|
||||
--backend-config='{"path": "/var/lib/teleport/teleport.auth.db"}'\
|
||||
--domain=gravitational.io\
|
||||
--domain=vendor.io\
|
||||
--event-backend=bolt\
|
||||
--event-backend-config='{"path": "/var/lib/teleport/teleport.event.db"}'\
|
||||
--record-backend=bolt\
|
||||
|
@ -117,7 +118,7 @@ run-embedded: install
|
|||
--srv-addr=tcp://telescope.vendor.io:34000\
|
||||
cp\
|
||||
--assets-dir=$(GOPATH)/src/github.com/gravitational/teleport\
|
||||
--domain=gravitational.io
|
||||
--domain=vendor.io
|
||||
|
||||
|
||||
run-simple: install
|
||||
|
@ -127,12 +128,12 @@ run-simple: install
|
|||
--log=console\
|
||||
--log-severity=INFO\
|
||||
--data-dir=/var/lib/teleport\
|
||||
--fqdn=auth.gravitational.io\
|
||||
--auth-server=tcp://127.0.0.1:33000\
|
||||
--fqdn=auth.vendor.io\
|
||||
--auth-server=tcp://0.0.0.0:33000\
|
||||
auth\
|
||||
--backend=bolt\
|
||||
--backend-config='{"path": "/var/lib/teleport/teleport.auth.db"}'\
|
||||
--domain=gravitational.io\
|
||||
--domain=vendor.io\
|
||||
--event-backend=bolt\
|
||||
--event-backend-config='{"path": "/var/lib/teleport/teleport.event.db"}'\
|
||||
--record-backend=bolt\
|
||||
|
@ -140,20 +141,44 @@ run-simple: install
|
|||
ssh\
|
||||
cp\
|
||||
--assets-dir=$(GOPATH)/src/github.com/gravitational/teleport\
|
||||
--domain=gravitational.io
|
||||
--domain=vendor.io
|
||||
|
||||
run-ssh2: install
|
||||
tctl token generate --output=/tmp/token --fqdn=node3.gravitational.io
|
||||
tctl token generate --output=/tmp/token --fqdn=node3.vendor.io
|
||||
teleport\
|
||||
--log=console\
|
||||
--log-severity=INFO\
|
||||
--data-dir=/tmp\
|
||||
--fqdn=node3.gravitational.io\
|
||||
--fqdn=node3.vendor.io\
|
||||
--auth-server=tcp://0.0.0.0:33000\
|
||||
ssh\
|
||||
--addr=tcp://localhost:34001\
|
||||
--addr=tcp://node3.vendor.io:34001\
|
||||
--token=/tmp/token\
|
||||
|
||||
run-telescope: install
|
||||
rm -f /tmp/telescope.auth.sock
|
||||
telescope --log=console\
|
||||
--log-severity=INFO\
|
||||
--data-dir=/var/lib/teleport/telescope\
|
||||
--assets-dir=$(GOPATH)/src/github.com/gravitational/teleport/telescope\
|
||||
--cp-assets-dir=$(GOPATH)/src/github.com/gravitational/teleport\
|
||||
--fqdn=telescope.vendor.io\
|
||||
--domain=vendor.io\
|
||||
--tun-addr=tcp://0.0.0.0:34000\
|
||||
--web-addr=tcp://0.0.0.0:35000\
|
||||
--backend=bolt\
|
||||
--backend-config='{"path": "/var/lib/teleport/telescope.db"}'
|
||||
|
||||
trust-telescope:
|
||||
tscopectl user-ca pub-key > /tmp/user.pubkey
|
||||
tscopectl host-ca pub-key > /tmp/host.pubkey
|
||||
tctl remote-ca upsert --type=user --id=user.telescope.vendor.io --fqdn=telescope.vendor.io --path=/tmp/user.pubkey
|
||||
tctl remote-ca upsert --type=host --id=host.telescope.vendor.io --fqdn=telescope.vendor.io --path=/tmp/host.pubkey
|
||||
tctl remote-ca ls --type=user
|
||||
tctl remote-ca ls --type=host
|
||||
tctl host-ca pub-key > /tmp/tscope-host.pubkey
|
||||
tscopectl remote-ca upsert --type=host --id=host.auth.vendor.io --fqdn=auth.vendor.io --path=/tmp/tscope-host.pubkey
|
||||
tscopectl remote-ca ls --type=host
|
||||
|
||||
profile:
|
||||
go tool pprof http://localhost:6060/debug/pprof/profile
|
||||
|
|
64
auth/init.go
64
auth/init.go
|
@ -19,62 +19,39 @@ import (
|
|||
)
|
||||
|
||||
func Init(b *encryptedbk.ReplicatedBackend, a Authority,
|
||||
fqdn, authDomain, dataDir string) (*AuthServer, ssh.Signer, error) {
|
||||
fqdn, authDomain, dataDir string) (*AuthServer, error) {
|
||||
|
||||
if authDomain == "" {
|
||||
return nil, nil, fmt.Errorf("node name can not be empty")
|
||||
return nil, fmt.Errorf("node name can not be empty")
|
||||
}
|
||||
if dataDir == "" {
|
||||
return nil, nil, fmt.Errorf("path can not be empty")
|
||||
return nil, fmt.Errorf("path can not be empty")
|
||||
}
|
||||
|
||||
err := os.MkdirAll(dataDir, os.ModeDir|0755)
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lockService := services.NewLockService(b)
|
||||
err = lockService.AcquireLock(authDomain, 60*time.Second)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
log.Errorf(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
defer lockService.ReleaseLock(authDomain)
|
||||
|
||||
scrt, err := InitSecret(dataDir)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
log.Errorf(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// check that user CA and host CA are present and set the certs if needed
|
||||
asrv := NewAuthServer(b, a, scrt)
|
||||
|
||||
if _, e := asrv.GetHostCAPub(); e != nil {
|
||||
log.Infof("Host CA error: %v", e)
|
||||
if _, ok := e.(*teleport.NotFoundError); ok {
|
||||
log.Infof("Reseting host CA")
|
||||
if err := asrv.ResetHostCA(""); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, e := asrv.GetUserCAPub(); e != nil {
|
||||
log.Infof("User CA error: %v", e)
|
||||
if _, ok := e.(*teleport.NotFoundError); ok {
|
||||
log.Infof("Reseting host CA")
|
||||
if err := asrv.ResetUserCA(""); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signer, err := InitKeys(asrv, fqdn, dataDir)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return asrv, signer, nil
|
||||
return asrv, nil
|
||||
}
|
||||
|
||||
// initialize this node's host certificate signed by host authority
|
||||
|
@ -83,6 +60,26 @@ func InitKeys(a *AuthServer, fqdn, dataDir string) (ssh.Signer, error) {
|
|||
return nil, fmt.Errorf("fqdn can not be empty")
|
||||
}
|
||||
|
||||
if _, e := a.GetHostCAPub(); e != nil {
|
||||
log.Infof("Host CA error: %v", e)
|
||||
if _, ok := e.(*teleport.NotFoundError); ok {
|
||||
log.Infof("Reseting host CA")
|
||||
if err := a.ResetHostCA(""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, e := a.GetUserCAPub(); e != nil {
|
||||
log.Infof("User CA error: %v", e)
|
||||
if _, ok := e.(*teleport.NotFoundError); ok {
|
||||
log.Infof("Reseting host CA")
|
||||
if err := a.ResetUserCA(""); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kp, cp := keysPath(fqdn, dataDir)
|
||||
|
||||
keyExists, err := pathExists(kp)
|
||||
|
@ -98,13 +95,16 @@ func InitKeys(a *AuthServer, fqdn, dataDir string) (ssh.Signer, error) {
|
|||
if !keyExists || !certExists {
|
||||
k, pub, err := a.GenerateKeyPair("")
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
c, err := a.GenerateHostCert(pub, fqdn, fqdn, 0)
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
if err := writeKeys(fqdn, dataDir, k, c); err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@ func NewReplicatedBackend(backend backend.Backend, keysFile string, readonly boo
|
|||
repBk.mutex = &sync.Mutex{}
|
||||
repBk.baseBk = backend
|
||||
repBk.keyStorage, err = boltbk.New(keysFile)
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
repBk.readonly = readonly
|
||||
|
||||
remoteKeys, _ := backend.GetKeys([]string{rootDir})
|
||||
|
@ -97,7 +101,7 @@ func (b *ReplicatedBackend) initFromExistingBk() error {
|
|||
}
|
||||
|
||||
if !localKeyExists {
|
||||
log.Infof("Remote key %s is not provided in the local keys. Backend will work in readonly mode")
|
||||
log.Infof("Remote key %s is not provided in the local keys. Backend will work in readonly mode", remoteKey)
|
||||
b.readonly = true
|
||||
}
|
||||
}
|
||||
|
@ -136,14 +140,11 @@ func (b *ReplicatedBackend) initFromEmptyBk() error {
|
|||
}
|
||||
|
||||
func (b *ReplicatedBackend) GetKeys(path []string) ([]string, error) {
|
||||
b.checkKeysAreProvided()
|
||||
|
||||
b.mutex.Lock()
|
||||
defer b.mutex.Unlock()
|
||||
|
||||
if len(b.ebk) == 0 {
|
||||
log.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
return nil, trace.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
}
|
||||
|
||||
var err error
|
||||
err = trace.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
|
||||
|
@ -161,14 +162,11 @@ func (b *ReplicatedBackend) GetKeys(path []string) ([]string, error) {
|
|||
}
|
||||
|
||||
func (b *ReplicatedBackend) DeleteKey(path []string, key string) error {
|
||||
b.checkKeysAreProvided()
|
||||
|
||||
b.mutex.Lock()
|
||||
defer b.mutex.Unlock()
|
||||
|
||||
if len(b.ebk) == 0 {
|
||||
log.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
return trace.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
}
|
||||
|
||||
if b.readonly {
|
||||
log.Errorf("Can't modify backend data without all the remote encrypting keys. Backend work in readonly mode")
|
||||
return trace.Errorf("Can't modify backend data without all the remote encrypting keys. Backend work in readonly mode")
|
||||
|
@ -191,14 +189,11 @@ func (b *ReplicatedBackend) DeleteKey(path []string, key string) error {
|
|||
}
|
||||
|
||||
func (b *ReplicatedBackend) DeleteBucket(path []string, bkt string) error {
|
||||
b.checkKeysAreProvided()
|
||||
|
||||
b.mutex.Lock()
|
||||
defer b.mutex.Unlock()
|
||||
|
||||
if len(b.ebk) == 0 {
|
||||
log.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
return trace.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
}
|
||||
|
||||
if b.readonly {
|
||||
log.Errorf("Can't modify backend data without all the remote encrypting keys. Backend work in readonly mode")
|
||||
return trace.Errorf("Can't modify backend data without all the remote encrypting keys. Backend work in readonly mode")
|
||||
|
@ -215,14 +210,11 @@ func (b *ReplicatedBackend) DeleteBucket(path []string, bkt string) error {
|
|||
}
|
||||
|
||||
func (b *ReplicatedBackend) UpsertVal(path []string, key string, val []byte, ttl time.Duration) error {
|
||||
b.checkKeysAreProvided()
|
||||
|
||||
b.mutex.Lock()
|
||||
defer b.mutex.Unlock()
|
||||
|
||||
if len(b.ebk) == 0 {
|
||||
log.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
return trace.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
}
|
||||
|
||||
if b.readonly {
|
||||
log.Errorf("Can't modify backend data without all the remote encrypting keys. Backend work in readonly mode")
|
||||
return trace.Errorf("Can't modify backend data without all the remote encrypting keys. Backend work in readonly mode")
|
||||
|
@ -239,14 +231,11 @@ func (b *ReplicatedBackend) UpsertVal(path []string, key string, val []byte, ttl
|
|||
}
|
||||
|
||||
func (b *ReplicatedBackend) GetVal(path []string, key string) ([]byte, error) {
|
||||
b.checkKeysAreProvided()
|
||||
|
||||
b.mutex.Lock()
|
||||
defer b.mutex.Unlock()
|
||||
|
||||
if len(b.ebk) == 0 {
|
||||
log.Errorf("Backend can't be accessed because there are no valid local encrypting keys")
|
||||
return nil, trace.Errorf("Backend can't be accessed because there are no valid local encrypting keys")
|
||||
}
|
||||
|
||||
var err error
|
||||
for _, bk := range b.ebk {
|
||||
var val []byte
|
||||
|
@ -262,6 +251,8 @@ func (b *ReplicatedBackend) GetVal(path []string, key string) ([]byte, error) {
|
|||
}
|
||||
|
||||
func (b *ReplicatedBackend) GetValAndTTL(path []string, key string) ([]byte, time.Duration, error) {
|
||||
b.checkKeysAreProvided()
|
||||
|
||||
b.mutex.Lock()
|
||||
defer b.mutex.Unlock()
|
||||
|
||||
|
@ -300,8 +291,8 @@ func (b *ReplicatedBackend) GenerateEncryptingKey(id string, copyData bool) erro
|
|||
|
||||
func (b *ReplicatedBackend) generateEncryptingKey(id string, copyData bool) error {
|
||||
if b.readonly {
|
||||
log.Errorf("Can't generate new backend encrypting key without all the encrypting keys used in remote backend. Backend work in readonly mode")
|
||||
return trace.Errorf("Can't generate new backend encrypting key without all the encrypting keys used in remote backend. Backend work in readonly mode")
|
||||
log.Errorf("Can't generate new backend encrypting key without all the encrypting keys used on the remote backend. Backend works in readonly mode")
|
||||
return trace.Errorf("Can't generate new backend encrypting key without all the encrypting keys used on the remote backend. Backend works in readonly mode")
|
||||
}
|
||||
|
||||
keyValue, err := secret.NewKey()
|
||||
|
@ -500,6 +491,20 @@ func (b *ReplicatedBackend) copy(src, dest *EncryptedBackend, path []string) err
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *ReplicatedBackend) checkKeysAreProvided() {
|
||||
if len(b.ebk) == 0 {
|
||||
log.Errorf("Backen can't be accessed because there are no valid local encrypting keys")
|
||||
for {
|
||||
log.Warningf("Please provide valid backend keys. Use tctl (or tscopectl) to add backend keys.")
|
||||
time.Sleep(2 * time.Second)
|
||||
if len(b.ebk) > 0 {
|
||||
log.Infof("Backend started in readonly mode")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Key struct {
|
||||
ID string
|
||||
Value []byte
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/teleport"
|
||||
"github.com/gravitational/teleport/backend/boltbk"
|
||||
|
@ -167,13 +168,15 @@ func (s *ReplicatedBkSuite) TestSeveralAuthServers(c *C) {
|
|||
c.Assert(localIDs, DeepEquals, []string{})
|
||||
c.Assert(remoteIDs, DeepEquals, []string{"key/2", "key0"})
|
||||
|
||||
_, err = bk2.GetVal([]string{"a1"}, "b1")
|
||||
c.Assert(err, NotNil)
|
||||
c.Assert(bk2.UpsertVal([]string{"a2"}, "b2", []byte("val2"), 0), NotNil)
|
||||
|
||||
c.Assert(bk2.AddEncryptingKey(key2, true), IsNil)
|
||||
x := 5
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
x = 7
|
||||
c.Assert(bk2.AddEncryptingKey(key2, true), IsNil)
|
||||
}()
|
||||
|
||||
val, err := bk2.GetVal([]string{"a1"}, "b1")
|
||||
c.Assert(x, Equals, 7)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(string(val), Equals, "val1")
|
||||
|
||||
|
|
|
@ -132,6 +132,8 @@ func (b *bk) AcquireLock(token string, ttl time.Duration) error {
|
|||
default:
|
||||
return e
|
||||
}
|
||||
default:
|
||||
return e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ func initAuth(t *TeleportService, cfg Config) error {
|
|||
return err
|
||||
}
|
||||
|
||||
asrv, signer, err := auth.Init(
|
||||
asrv, err := auth.Init(
|
||||
b, authority.New(), *cfg.FQDN, *cfg.Auth.Domain, *cfg.DataDir)
|
||||
if err != nil {
|
||||
log.Errorf("failed to init auth server: %v", err)
|
||||
|
@ -117,6 +117,12 @@ func initAuth(t *TeleportService, cfg Config) error {
|
|||
|
||||
// register auth SSH-based endpoint
|
||||
t.RegisterFunc(func() error {
|
||||
signer, err := auth.InitKeys(asrv, *cfg.FQDN, *cfg.DataDir)
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
tsrv, err := auth.NewTunServer(
|
||||
cfg.Auth.SSHAddr, []ssh.Signer{signer},
|
||||
cfg.Auth.HTTPAddr,
|
||||
|
@ -131,6 +137,7 @@ func initAuth(t *TeleportService, cfg Config) error {
|
|||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -173,9 +180,15 @@ func initSSH(t *TeleportService, cfg Config) error {
|
|||
// this means the server has not been initialized yet we are starting
|
||||
// the registering client that attempts to connect ot the auth server
|
||||
// and provision the keys
|
||||
return initRegister(t, *cfg.SSH.Token, cfg, initSSHEndpoint)
|
||||
t.RegisterFunc(func() error {
|
||||
return initRegister(t, *cfg.SSH.Token, cfg, initSSHEndpoint)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
return initSSHEndpoint(t, cfg)
|
||||
t.RegisterFunc(func() error {
|
||||
return initSSHEndpoint(t, cfg)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func initSSHEndpoint(t *TeleportService, cfg Config) error {
|
||||
|
@ -204,6 +217,9 @@ func initSSHEndpoint(t *TeleportService, cfg Config) error {
|
|||
}
|
||||
|
||||
t.RegisterFunc(func() error {
|
||||
if cfg.Auth.Enabled {
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
log.Infof("teleport ssh starting on %v", cfg.SSH.Addr)
|
||||
if err := s.Start(); err != nil {
|
||||
log.Fatalf("failed to start: %v", err)
|
||||
|
@ -220,6 +236,7 @@ func initRegister(t *TeleportService, token string, cfg Config,
|
|||
// we are on the same server as the auth endpoint
|
||||
// and there's no token. we can handle this
|
||||
if cfg.Auth.Enabled && token == "" {
|
||||
time.Sleep(2 * time.Second)
|
||||
log.Infof("registering in embedded mode, connecting to local auth server")
|
||||
clt, err := auth.NewClientFromNetAddr(cfg.Auth.HTTPAddr)
|
||||
if err != nil {
|
||||
|
@ -233,6 +250,9 @@ func initRegister(t *TeleportService, token string, cfg Config,
|
|||
return err
|
||||
}
|
||||
t.RegisterFunc(func() error {
|
||||
if cfg.Auth.Enabled {
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
log.Infof("teleport:register connecting to auth servers %v", *cfg.SSH.Token)
|
||||
if err := auth.Register(
|
||||
*cfg.FQDN, *cfg.DataDir, token, cfg.AuthServers); err != nil {
|
||||
|
|
|
@ -3,9 +3,6 @@ package services
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/teleport"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/log"
|
||||
"github.com/gravitational/teleport/Godeps/_workspace/src/github.com/gravitational/trace"
|
||||
"github.com/gravitational/teleport/backend"
|
||||
)
|
||||
|
||||
|
@ -19,27 +16,9 @@ func NewLockService(backend backend.Backend) *LockService {
|
|||
|
||||
// Grab a lock that will be released automatically in ttl time
|
||||
func (s *LockService) AcquireLock(token string, ttl time.Duration) error {
|
||||
_, err := s.backend.GetVal([]string{"locks"}, token)
|
||||
if err == nil {
|
||||
return &teleport.AlreadyAcquiredError{""}
|
||||
} else {
|
||||
switch err.(type) {
|
||||
case *teleport.NotFoundError:
|
||||
default:
|
||||
log.Errorf(err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = s.backend.UpsertVal([]string{"locks"}, token, []byte("lock"), ttl)
|
||||
if err != nil {
|
||||
log.Errorf(err.Error())
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
return err
|
||||
|
||||
return s.backend.AcquireLock(token, ttl)
|
||||
}
|
||||
|
||||
func (s *LockService) ReleaseLock(token string) error {
|
||||
return s.backend.DeleteKey([]string{"locks"}, token)
|
||||
return s.backend.ReleaseLock(token)
|
||||
}
|
||||
|
|
|
@ -223,17 +223,49 @@ func (s *ServicesTestSuite) WebTunCRUD(c *C) {
|
|||
}
|
||||
|
||||
func (s *ServicesTestSuite) Locking(c *C) {
|
||||
tok := randomToken()
|
||||
ttl := 30 * time.Second
|
||||
tok1 := "token1"
|
||||
tok2 := "token2"
|
||||
|
||||
c.Assert(s.LockS.AcquireLock(tok, ttl), IsNil)
|
||||
c.Assert(s.LockS.AcquireLock(tok, ttl),
|
||||
FitsTypeOf, &teleport.AlreadyAcquiredError{})
|
||||
c.Assert(s.LockS.ReleaseLock(tok1), FitsTypeOf, &teleport.NotFoundError{})
|
||||
|
||||
c.Assert(s.LockS.ReleaseLock(tok), IsNil)
|
||||
c.Assert(s.LockS.ReleaseLock(tok), FitsTypeOf, &teleport.NotFoundError{})
|
||||
c.Assert(s.LockS.AcquireLock(tok1, 30*time.Second), IsNil)
|
||||
x := 7
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
x = 9
|
||||
c.Assert(s.LockS.ReleaseLock(tok1), IsNil)
|
||||
}()
|
||||
c.Assert(s.LockS.AcquireLock(tok1, 0), IsNil)
|
||||
x = x * 2
|
||||
c.Assert(x, Equals, 18)
|
||||
c.Assert(s.LockS.ReleaseLock(tok1), IsNil)
|
||||
|
||||
c.Assert(s.LockS.AcquireLock(tok, 30*time.Second), IsNil)
|
||||
c.Assert(s.LockS.AcquireLock(tok1, 0), IsNil)
|
||||
x = 7
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
x = 9
|
||||
c.Assert(s.LockS.ReleaseLock(tok1), IsNil)
|
||||
}()
|
||||
c.Assert(s.LockS.AcquireLock(tok1, 0), IsNil)
|
||||
x = x * 2
|
||||
c.Assert(x, Equals, 18)
|
||||
c.Assert(s.LockS.ReleaseLock(tok1), IsNil)
|
||||
|
||||
y := 0
|
||||
go func() {
|
||||
c.Assert(s.LockS.AcquireLock(tok1, 0), IsNil)
|
||||
c.Assert(s.LockS.AcquireLock(tok2, 0), IsNil)
|
||||
|
||||
c.Assert(s.LockS.ReleaseLock(tok1), IsNil)
|
||||
c.Assert(s.LockS.ReleaseLock(tok2), IsNil)
|
||||
y = 15
|
||||
}()
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
c.Assert(y, Equals, 15)
|
||||
|
||||
c.Assert(s.LockS.ReleaseLock(tok1), FitsTypeOf, &teleport.NotFoundError{})
|
||||
}
|
||||
|
||||
func (s *ServicesTestSuite) TokenCRUD(c *C) {
|
||||
|
|
|
@ -137,14 +137,14 @@ func NewService(cfg Config) (*Service, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
asrv, hostSigner, err := auth.Init(
|
||||
asrv, err := auth.Init(
|
||||
b, authority.New(), *cfg.FQDN, *cfg.Domain, *cfg.DataDir)
|
||||
if err != nil {
|
||||
log.Errorf("failed to init auth server: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &Service{cfg: cfg, b: b, a: asrv, hs: hostSigner}
|
||||
s := &Service{cfg: cfg, b: b, a: asrv}
|
||||
s.Supervisor = *service.New()
|
||||
if err := s.addStart(); err != nil {
|
||||
return nil, err
|
||||
|
@ -154,31 +154,12 @@ func NewService(cfg Config) (*Service, error) {
|
|||
|
||||
type Service struct {
|
||||
service.Supervisor
|
||||
b backend.Backend
|
||||
a *auth.AuthServer
|
||||
hs ssh.Signer
|
||||
|
||||
b backend.Backend
|
||||
a *auth.AuthServer
|
||||
cfg Config
|
||||
}
|
||||
|
||||
func (s *Service) addStart() error {
|
||||
tsrv, err := tun.NewServer(s.cfg.TunAddr, []ssh.Signer{s.hs},
|
||||
auth.NewBackendAccessPoint(s.b))
|
||||
if err != nil {
|
||||
log.Errorf("failed to start server: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
s.RegisterFunc(func() error {
|
||||
log.Infof("telescope tunnel server starting")
|
||||
if err := tsrv.Start(); err != nil {
|
||||
log.Errorf("failed to start: %v", err)
|
||||
return err
|
||||
}
|
||||
tsrv.Wait()
|
||||
return nil
|
||||
})
|
||||
|
||||
asrv := auth.NewAPIServer(s.a, nil, nil, nil)
|
||||
|
||||
// register Auth HTTP API endpoint
|
||||
|
@ -191,56 +172,80 @@ func (s *Service) addStart() error {
|
|||
return nil
|
||||
})
|
||||
|
||||
// register auth SSH-based endpoint
|
||||
s.RegisterFunc(func() error {
|
||||
tsrv, err := auth.NewTunServer(
|
||||
s.cfg.AuthSSHAddr, []ssh.Signer{s.hs},
|
||||
s.cfg.AuthHTTPAddr,
|
||||
s.a)
|
||||
var err error
|
||||
signer, err := auth.InitKeys(s.a, *s.cfg.FQDN, *s.cfg.DataDir)
|
||||
if err != nil {
|
||||
log.Errorf("failed to start teleport ssh tunnel")
|
||||
log.Errorf(err.Error())
|
||||
return err
|
||||
}
|
||||
if err := tsrv.Start(); err != nil {
|
||||
log.Errorf("failed to start teleport ssh endpoint: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// Register control panel web server
|
||||
s.RegisterFunc(func() error {
|
||||
wsrv, err := srv.New(s.cfg.WebAddr,
|
||||
srv.Config{
|
||||
Tun: tsrv,
|
||||
AssetsDir: *s.cfg.AssetsDir,
|
||||
CPAssetsDir: *s.cfg.CPAssetsDir,
|
||||
AuthAddr: s.cfg.AuthSSHAddr,
|
||||
FQDN: *s.cfg.FQDN})
|
||||
tsrv, err := tun.NewServer(s.cfg.TunAddr, []ssh.Signer{signer},
|
||||
auth.NewBackendAccessPoint(s.b))
|
||||
if err != nil {
|
||||
log.Errorf("failed to launch web server: %v", err)
|
||||
log.Errorf("failed to start server: %v", err)
|
||||
return err
|
||||
}
|
||||
log.Infof("telescope web server starting")
|
||||
|
||||
if (*s.cfg.TLSCertFile != "") && (*s.cfg.TLSKeyFile != "") {
|
||||
err := srv.ListenAndServeTLS(
|
||||
wsrv.Server.Addr,
|
||||
wsrv.Handler,
|
||||
*s.cfg.TLSCertFile,
|
||||
*s.cfg.TLSKeyFile,
|
||||
)
|
||||
// register auth SSH-based endpoint
|
||||
s.RegisterFunc(func() error {
|
||||
tun, err := auth.NewTunServer(
|
||||
s.cfg.AuthSSHAddr, []ssh.Signer{signer},
|
||||
s.cfg.AuthHTTPAddr,
|
||||
s.a)
|
||||
if err != nil {
|
||||
log.Errorf("failed to start: %v", err)
|
||||
log.Errorf("failed to start teleport ssh tunnel")
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := tun.Start(); err != nil {
|
||||
log.Errorf("failed to start teleport ssh endpoint: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := wsrv.ListenAndServe(); err != nil {
|
||||
log.Errorf("failed to start: %v", err)
|
||||
// Register control panel web server
|
||||
s.RegisterFunc(func() error {
|
||||
wsrv, err := srv.New(s.cfg.WebAddr,
|
||||
srv.Config{
|
||||
Tun: tsrv,
|
||||
AssetsDir: *s.cfg.AssetsDir,
|
||||
CPAssetsDir: *s.cfg.CPAssetsDir,
|
||||
AuthAddr: s.cfg.AuthSSHAddr,
|
||||
FQDN: *s.cfg.FQDN})
|
||||
if err != nil {
|
||||
log.Errorf("failed to launch web server: %v", err)
|
||||
return err
|
||||
}
|
||||
log.Infof("telescope web server starting")
|
||||
|
||||
if (*s.cfg.TLSCertFile != "") && (*s.cfg.TLSKeyFile != "") {
|
||||
err := srv.ListenAndServeTLS(
|
||||
wsrv.Server.Addr,
|
||||
wsrv.Handler,
|
||||
*s.cfg.TLSCertFile,
|
||||
*s.cfg.TLSKeyFile,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("failed to start: %v", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
||||
if err := wsrv.ListenAndServe(); err != nil {
|
||||
log.Errorf("failed to start: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
log.Infof("telescope tunnel server starting")
|
||||
if err := tsrv.Start(); err != nil {
|
||||
log.Errorf("failed to start: %v", err)
|
||||
return err
|
||||
}
|
||||
tsrv.Wait()
|
||||
return nil
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue