mirror of
https://github.com/gravitational/teleport
synced 2024-10-19 16:53:57 +00:00
small fixes, refs #290
* do not populate auth servers advertising local ips * fix annoying resize on session create * decrease TTLs for active sessions and parties
This commit is contained in:
parent
9e98bde9ef
commit
d42e122ef1
29
Makefile
29
Makefile
|
@ -10,11 +10,8 @@ PWD ?= $(shell pwd)
|
|||
ETCD_CERTS := $(realpath fixtures/certs)
|
||||
ETCD_FLAGS := TELEPORT_TEST_ETCD_CONFIG='{"nodes": ["https://localhost:4001"], "key":"/teleport/test", "tls_key_file": "$(ETCD_CERTS)/proxy1-key.pem", "tls_cert_file": "$(ETCD_CERTS)/proxy1.pem", "tls_ca_file": "$(ETCD_CERTS)/ca.pem"}'
|
||||
TELEPORT_DEBUG_TESTS ?= no
|
||||
GO15VENDOREXPERIMENT := 1
|
||||
export
|
||||
|
||||
.PHONY: install test test-with-etcd remove-temp files test-package update test-grep-package cover-package cover-package-with-etcd run profile sloccount set-etcd
|
||||
|
||||
#
|
||||
# Default target: builds all 3 executables and plaaces them in a current directory
|
||||
#
|
||||
|
@ -71,6 +68,7 @@ docs:
|
|||
#
|
||||
# tests everything: called by Jenkins
|
||||
#
|
||||
.PHONY: test
|
||||
test: FLAGS ?= -cover
|
||||
test:
|
||||
go test -v $(PKGPATH)/tool/tsh/... \
|
||||
|
@ -110,42 +108,55 @@ binary-release: build
|
|||
cp -af $(BUILDDIR)/tctl $(BUILDDIR)/tsh $(BUILDDIR)/teleport $(BUILDDIR)/$(RELEASE)/teleport/build
|
||||
tar -czf $(BUILDDIR)/$(RELEASE).tar.gz -C $(BUILDDIR)/$(RELEASE) teleport
|
||||
|
||||
.PHONY: flags
|
||||
flags:
|
||||
$(shell go install $(PKGPATH)/vendor/github.com/gravitational/version/cmd/linkflags)
|
||||
$(eval BUILDFLAGS := $(ADDFLAGS) -ldflags "$(shell linkflags -pkg=$(GOPATH)/src/$(PKGPATH) -verpkg=$(PKGPATH)/vendor/github.com/gravitational/version)")
|
||||
|
||||
|
||||
test-with-etcd: install
|
||||
.PHONY: test-with-etcd
|
||||
test-with-etcd: remove-temp-files
|
||||
${ETCD_FLAGS} go test -v -test.parallel=0 $(shell go list ./... | grep -v /vendor/) -cover
|
||||
|
||||
test-package: remove-temp-files install
|
||||
.PHONY: test-package
|
||||
test-package: remove-temp-files
|
||||
go test -v -test.parallel=0 ./$(p)
|
||||
|
||||
test-package-with-etcd: remove-temp-files install
|
||||
.PHONY: tets-package-with-etcd
|
||||
test-package-with-etcd: remove-temp-files
|
||||
${ETCD_FLAGS} go test -v -test.parallel=0 ./$(p)
|
||||
|
||||
test-grep-package-with-etcd: remove-temp-files install
|
||||
.PHONY: test-grep-package-with-etcd
|
||||
test-grep-package-with-etcd: remove-temp-files
|
||||
${ETCD_FLAGS} go test -v -test.parallel=0 ./$(p) -check.f=$(e)
|
||||
|
||||
|
||||
test-grep-package: remove-temp-files install
|
||||
.PHONY: test-grep-package
|
||||
test-grep-package: remove-temp-files
|
||||
go test -v ./$(p) -check.f=$(e)
|
||||
|
||||
.PHONY: cover-package
|
||||
cover-package: remove-temp-files
|
||||
go test -v ./$(p) -coverprofile=/tmp/coverage.out
|
||||
go tool cover -html=/tmp/coverage.out
|
||||
|
||||
.PHONY: cover-package-with-etcd
|
||||
cover-package-with-etcd: remove-temp-files
|
||||
${ETCD_FLAGS} go test -v ./$(p) -coverprofile=/tmp/coverage.out
|
||||
go tool cover -html=/tmp/coverage.out
|
||||
|
||||
.PHONY: profile
|
||||
profile:
|
||||
go tool pprof http://localhost:6060/debug/pprof/profile
|
||||
|
||||
.PHONY: sloccount
|
||||
sloccount:
|
||||
find . -path ./vendor -prune -o -name "*.go" -print0 | xargs -0 wc -l
|
||||
|
||||
# start-test-etcd starts test etcd node using tls certificates
|
||||
.PHONY: start-test-etcd
|
||||
start-test-etcd:
|
||||
docker run -d -p 4001:4001 -p 2380:2380 -p 2379:2379 -v $(ETCD_CERTS):/certs quay.io/coreos/etcd:v2.2.5 -name etcd0 -advertise-client-urls https://localhost:2379,https://localhost:4001 -listen-client-urls https://0.0.0.0:2379,https://0.0.0.0:4001 -initial-advertise-peer-urls https://localhost:2380 -listen-peer-urls https://0.0.0.0:2380 -initial-cluster-token etcd-cluster-1 -initial-cluster etcd0=https://localhost:2380 -initial-cluster-state new --cert-file=/certs/etcd1.pem --key-file=/certs/etcd1-key.pem --peer-cert-file=/certs/etcd1.pem --peer-key-file=/certs/etcd1-key.pem --peer-client-cert-auth --peer-trusted-ca-file=/certs/ca.pem -client-cert-auth
|
||||
|
||||
.PHONY: remove-temp-files
|
||||
remove-temp-files:
|
||||
find . -name flymake_* -delete
|
||||
|
|
|
@ -613,12 +613,10 @@ func (c *TunClient) Dial(network, address string) (net.Conn, error) {
|
|||
func (c *TunClient) fetchAndSync() error {
|
||||
authServers, err := c.fetchAuthServers()
|
||||
if err != nil {
|
||||
log.Infof("failed to fetch auth servers")
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
if len(authServers) == 0 {
|
||||
log.Warningf("no auth servers received")
|
||||
return trace.Wrap(teleport.NotFound("no auth servers"))
|
||||
return trace.Wrap(teleport.NotFound("no auth servers with remote ips advertised"))
|
||||
}
|
||||
// set runtime information about auth servers
|
||||
c.setAuthServers(authServers)
|
||||
|
@ -637,7 +635,7 @@ func (c *TunClient) syncAuthServers() {
|
|||
case <-c.refreshTicker.C:
|
||||
err := c.fetchAndSync()
|
||||
if err != nil {
|
||||
log.Infof("failed to fetch and sync servers: %v", err)
|
||||
log.Infof("fetch and sync servers: %v", err)
|
||||
continue
|
||||
}
|
||||
case <-c.closeC:
|
||||
|
@ -657,7 +655,9 @@ func (c *TunClient) fetchAuthServers() ([]utils.NetAddr, error) {
|
|||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
authServers = append(authServers, *serverAddr)
|
||||
if !serverAddr.IsLocal() {
|
||||
authServers = append(authServers, *serverAddr)
|
||||
}
|
||||
}
|
||||
return authServers, nil
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ const (
|
|||
|
||||
// SessionRefreshPeriod is how often tsh polls information about session
|
||||
// TODO(klizhentas) all polling periods should go away once backend
|
||||
// releases
|
||||
// releases events
|
||||
SessionRefreshPeriod = 2 * time.Second
|
||||
|
||||
// DefaultDialTimeout is a default TCP dial timeout we set for our
|
||||
|
@ -125,6 +125,18 @@ const (
|
|||
|
||||
// MaxPasswordLength is maximum password length (for sanity)
|
||||
MaxPasswordLength = 128
|
||||
|
||||
// IterationLimit is a default limit if it's not set
|
||||
IterationLimit = 100
|
||||
|
||||
// MaxIterationLimit is max iteration limit
|
||||
MaxIterationLimit = 1000
|
||||
|
||||
// ActiveSessionTTL is a TTL when session is marked as inactive
|
||||
ActiveSessionTTL = 30 * time.Second
|
||||
|
||||
// ActivePartyTTL is a TTL when party is marked as inactive
|
||||
ActivePartyTTL = 30 * time.Second
|
||||
)
|
||||
|
||||
// Default connection limits, they can be applied separately on any of the Teleport
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
|
||||
"github.com/gravitational/teleport"
|
||||
"github.com/gravitational/teleport/lib/backend"
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
|
||||
"github.com/docker/docker/pkg/term"
|
||||
"github.com/gravitational/trace"
|
||||
|
@ -137,15 +138,13 @@ func (p *Party) String() string {
|
|||
)
|
||||
}
|
||||
|
||||
// DefaultLimit is a default limit if it's not set
|
||||
const DefaultLimit = 100
|
||||
|
||||
// TerminalParams holds parameters of the terminal used in session
|
||||
type TerminalParams struct {
|
||||
W int `json:"w"`
|
||||
H int `json:"h"`
|
||||
}
|
||||
|
||||
// String returns debug friendly representation of terminal
|
||||
func (p *TerminalParams) String() string {
|
||||
return fmt.Sprintf("TerminalParams(w=%v, h=%v)", p.W, p.H)
|
||||
}
|
||||
|
@ -245,14 +244,11 @@ func New(bk backend.Backend, opts ...Option) (Service, error) {
|
|||
s.clock = &timetools.RealTime{}
|
||||
}
|
||||
if s.activeSessionTTL == 0 {
|
||||
s.activeSessionTTL = DefaultActiveSessionTTL
|
||||
s.activeSessionTTL = defaults.ActiveSessionTTL
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// MaxLimit is max iteration limit
|
||||
const MaxLimit = 1000
|
||||
|
||||
func activeBucket() []string {
|
||||
return []string{"sessions", "active"}
|
||||
}
|
||||
|
@ -318,13 +314,6 @@ func (s *server) GetSession(id ID) (*Session, error) {
|
|||
return sess, nil
|
||||
}
|
||||
|
||||
const (
|
||||
// DefaultActiveSessionTTL is a TTL when session is marked as inactive
|
||||
DefaultActiveSessionTTL = 10 * time.Minute
|
||||
// DefaultActivePartyTTL is a TTL when party is marked as inactive
|
||||
DefaultActivePartyTTL = 10 * time.Second
|
||||
)
|
||||
|
||||
// CreateSession creates a new session if it does not exist, if the session
|
||||
// exists the function will return AlreadyExists error
|
||||
// The session will be marked as active for TTL period of time
|
||||
|
|
|
@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package session
|
||||
|
||||
import (
|
||||
|
@ -20,8 +21,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
// "github.com/gravitational/teleport"
|
||||
"github.com/gravitational/teleport/lib/backend/boltbk"
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
|
||||
"github.com/mailgun/timetools"
|
||||
|
@ -136,7 +137,7 @@ func (s *BoltSuite) TestSessionsInactivity(c *C) {
|
|||
}
|
||||
c.Assert(s.srv.CreateSession(sess), IsNil)
|
||||
|
||||
s.clock.Sleep(DefaultActiveSessionTTL + time.Second)
|
||||
s.clock.Sleep(defaults.ActiveSessionTTL + time.Second)
|
||||
|
||||
sess.Active = false
|
||||
s2, err := s.srv.GetSession(sess.ID)
|
||||
|
@ -162,7 +163,7 @@ func (s *BoltSuite) TestPartiesCRUD(c *C) {
|
|||
ServerID: "id-1",
|
||||
LastActive: s.clock.UtcNow(),
|
||||
}
|
||||
c.Assert(s.srv.UpsertParty(sess.ID, p1, DefaultActivePartyTTL), IsNil)
|
||||
c.Assert(s.srv.UpsertParty(sess.ID, p1, defaults.ActivePartyTTL), IsNil)
|
||||
|
||||
out, err := s.srv.GetSession(sess.ID)
|
||||
c.Assert(err, IsNil)
|
||||
|
@ -177,7 +178,7 @@ func (s *BoltSuite) TestPartiesCRUD(c *C) {
|
|||
ServerID: "id-2",
|
||||
LastActive: s.clock.UtcNow(),
|
||||
}
|
||||
c.Assert(s.srv.UpsertParty(sess.ID, p2, DefaultActivePartyTTL), IsNil)
|
||||
c.Assert(s.srv.UpsertParty(sess.ID, p2, defaults.ActivePartyTTL), IsNil)
|
||||
|
||||
out, err = s.srv.GetSession(sess.ID)
|
||||
c.Assert(err, IsNil)
|
||||
|
@ -187,7 +188,7 @@ func (s *BoltSuite) TestPartiesCRUD(c *C) {
|
|||
// Update session party
|
||||
s.clock.Sleep(time.Second)
|
||||
p1.LastActive = s.clock.UtcNow()
|
||||
c.Assert(s.srv.UpsertParty(sess.ID, p1, DefaultActivePartyTTL), IsNil)
|
||||
c.Assert(s.srv.UpsertParty(sess.ID, p1, defaults.ActivePartyTTL), IsNil)
|
||||
|
||||
out, err = s.srv.GetSession(sess.ID)
|
||||
c.Assert(err, IsNil)
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gravitational/teleport"
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
"github.com/gravitational/teleport/lib/events"
|
||||
"github.com/gravitational/teleport/lib/recorder"
|
||||
rsession "github.com/gravitational/teleport/lib/session"
|
||||
|
@ -245,7 +246,7 @@ func (s *session) upsertSessionParty(sid rsession.ID, p *party) error {
|
|||
ServerID: p.serverID,
|
||||
RemoteAddr: p.site,
|
||||
LastActive: p.getLastActive(),
|
||||
}, rsession.DefaultActivePartyTTL)
|
||||
}, defaults.ActivePartyTTL)
|
||||
}
|
||||
|
||||
// startShell starts a new shell process in the current session
|
||||
|
|
|
@ -39,6 +39,15 @@ type NetAddr struct {
|
|||
Path string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// IsLocal returns true if this is a local address
|
||||
func (a *NetAddr) IsLocal() bool {
|
||||
host, _, err := net.SplitHostPort(a.Addr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return IsLocalHost(host)
|
||||
}
|
||||
|
||||
// IsEmpty returns true if address is empty
|
||||
func (a *NetAddr) IsEmpty() bool {
|
||||
return a.Addr == "" && a.AddrNetwork == "" && a.Path == ""
|
||||
|
@ -190,8 +199,7 @@ func ReplaceLocalhost(addr, replaceWith string) string {
|
|||
if err != nil {
|
||||
return addr
|
||||
}
|
||||
ip := net.ParseIP(host)
|
||||
if ip.IsLoopback() || ip.IsUnspecified() {
|
||||
if IsLocalHost(host) {
|
||||
host, _, err = net.SplitHostPort(replaceWith)
|
||||
if err != nil {
|
||||
return addr
|
||||
|
@ -200,3 +208,12 @@ func ReplaceLocalhost(addr, replaceWith string) string {
|
|||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
// IsLocalHost returns true if this is a local hostname or ip
|
||||
func IsLocalHost(host string) bool {
|
||||
if host == "localhost" {
|
||||
return true
|
||||
}
|
||||
ip := net.ParseIP(host)
|
||||
return ip.IsLoopback() || ip.IsUnspecified()
|
||||
}
|
||||
|
|
|
@ -82,3 +82,23 @@ func (s *AddrTestSuite) TestReplaceLocalhost(c *C) {
|
|||
result = ReplaceLocalhost("0.0.0.0:22", "192.168.1.100:399")
|
||||
c.Assert(result, Equals, "192.168.1.100:22")
|
||||
}
|
||||
|
||||
func (s *AddrTestSuite) TestLocalAddrs(c *C) {
|
||||
testCases := []struct {
|
||||
in string
|
||||
expected bool
|
||||
}{
|
||||
{in: "127.0.0.1:5000", expected: true},
|
||||
{in: "localhost:5000", expected: true},
|
||||
{in: "127.0.0.2:5000", expected: true},
|
||||
{in: "tcp://127.0.0.2:5000", expected: true},
|
||||
{in: "tcp://10.0.0.3:5000", expected: false},
|
||||
{in: "tcp://hostname:5000", expected: false},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
addr, err := ParseAddr(testCase.in)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(addr.IsLocal(), Equals, testCase.expected,
|
||||
Commentf("test case %v, %v should be local(%v)", i, testCase.in, testCase.expected))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,8 +142,8 @@ func NewHandler(cfg Config, opts ...HandlerOption) (http.Handler, error) {
|
|||
h.GET("/webapi/sites/:site/connect", h.withSiteAuth(h.siteNodeConnect))
|
||||
// get session event stream
|
||||
h.GET("/webapi/sites/:site/sessions/:sid/events/stream", h.withSiteAuth(h.siteSessionStream))
|
||||
// create a new session
|
||||
h.POST("/webapi/sites/:site/sessions", h.withSiteAuth(h.siteSessionCreate))
|
||||
// generate a new session
|
||||
h.POST("/webapi/sites/:site/sessions", h.withSiteAuth(h.siteSessionGenerate))
|
||||
// update session parameters
|
||||
h.PUT("/webapi/sites/:site/sessions/:sid", h.withSiteAuth(h.siteSessionUpdate))
|
||||
// get session
|
||||
|
@ -533,15 +533,15 @@ func (m *Handler) siteSessionStream(w http.ResponseWriter, r *http.Request, p ht
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
type siteSessionCreateReq struct {
|
||||
type siteSessionGenerateReq struct {
|
||||
Session session.Session `json:"session"`
|
||||
}
|
||||
|
||||
type siteSessionCreateResponse struct {
|
||||
type siteSessionGenerateResponse struct {
|
||||
Session session.Session `json:"session"`
|
||||
}
|
||||
|
||||
// siteSessionCreate creates a new site session
|
||||
// siteSessionCreate generates a new site session that can be used by UI
|
||||
//
|
||||
// POST /v1/webapi/sites/:site/sessions
|
||||
//
|
||||
|
@ -553,24 +553,16 @@ type siteSessionCreateResponse struct {
|
|||
//
|
||||
// {"session": {"id": "session-id", "terminal_params": {"w": 100, "h": 100}, "login": "centos"}}
|
||||
//
|
||||
func (m *Handler) siteSessionCreate(w http.ResponseWriter, r *http.Request, p httprouter.Params, ctx *sessionContext, site reversetunnel.RemoteSite) (interface{}, error) {
|
||||
var req *siteSessionCreateReq
|
||||
func (m *Handler) siteSessionGenerate(w http.ResponseWriter, r *http.Request, p httprouter.Params, ctx *sessionContext, site reversetunnel.RemoteSite) (interface{}, error) {
|
||||
var req *siteSessionGenerateReq
|
||||
if err := httplib.ReadJSON(r, &req); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
client, err := ctx.GetClient()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
req.Session.ID = session.NewID()
|
||||
req.Session.Created = time.Now().UTC()
|
||||
req.Session.LastActive = time.Now().UTC()
|
||||
err = client.CreateSession(req.Session)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
log.Infof("Created session: %#v", req.Session)
|
||||
return siteSessionCreateResponse{Session: req.Session}, nil
|
||||
log.Infof("Generated session: %#v", req.Session)
|
||||
return siteSessionGenerateResponse{Session: req.Session}, nil
|
||||
}
|
||||
|
||||
type siteSessionUpdateReq struct {
|
||||
|
|
|
@ -687,11 +687,11 @@ func (s *WebSuite) TestCreateSession(c *C) {
|
|||
|
||||
re, err := pack.clt.PostJSON(
|
||||
pack.clt.Endpoint("webapi", "sites", s.domainName, "sessions"),
|
||||
siteSessionCreateReq{Session: sess},
|
||||
siteSessionGenerateReq{Session: sess},
|
||||
)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
var created *siteSessionCreateResponse
|
||||
var created *siteSessionGenerateResponse
|
||||
c.Assert(json.Unmarshal(re.Bytes(), &created), IsNil)
|
||||
c.Assert(created.Session.ID, Not(Equals), "")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue