Implemented a new Teleport option: "no recording"

Teleport configuration now has a new field: NoAudit (false by default,
which means audit is always on).

When this option is set, Teleport will not record events and will not
record sessions.

It's implemented by adding "DiscardLogger" which implements the same
interface as teh real logger, and it's plugged into the system instead.

NOTE: this option is not exposed in teleport in any way: no config file,
no switch, etc. I quickly needed it for Telecast.
This commit is contained in:
Ev Kontsevoy 2016-09-05 22:12:57 -07:00
parent c1efa712a1
commit c7b4934553
10 changed files with 85 additions and 18 deletions

View file

@ -188,14 +188,27 @@ func (i *TeleInstance) GetSiteAPI(siteName string) auth.ClientI {
// Create creates a new instance of Teleport which trusts a lsit of other clusters (other
// instances)
func (i *TeleInstance) Create(trustedSecrets []*InstanceSecrets, enableSSH bool, console io.Writer) error {
tconf := service.MakeDefaultConfig()
tconf.SSH.Enabled = enableSSH
tconf.Console = console
return i.CreateEx(trustedSecrets, tconf)
}
// CreateEx creates a new instance of Teleport which trusts a lsit of other clusters (other
// instances)
//
// Unlike Create() it allows for greater customization because it accepts
// a full Teleport config structure
func (i *TeleInstance) CreateEx(trustedSecrets []*InstanceSecrets, tconf *service.Config) error {
dataDir, err := ioutil.TempDir("", "cluster-"+i.Secrets.SiteName)
if err != nil {
return trace.Wrap(err)
}
tconf := service.MakeDefaultConfig()
if tconf == nil {
tconf = service.MakeDefaultConfig()
}
tconf.SeedConfig = true
tconf.DataDir = dataDir
tconf.Console = console
tconf.Auth.DomainName = i.Secrets.SiteName
tconf.Auth.Authorities = append(tconf.Auth.Authorities, i.Secrets.GetCAs()...)
tconf.Identities = append(tconf.Identities, i.Secrets.GetIdentity())
@ -213,7 +226,6 @@ func (i *TeleInstance) Create(trustedSecrets []*InstanceSecrets, enableSSH bool,
}
tconf.Proxy.ReverseTunnelListenAddr.Addr = i.Secrets.ListenAddr
tconf.HostUUID = i.Secrets.GetIdentity().ID.HostUUID
tconf.SSH.Enabled = enableSSH
tconf.SSH.Addr.Addr = net.JoinHostPort(i.Hostname, i.GetPortSSH())
tconf.Auth.SSHAddr.Addr = net.JoinHostPort(i.Hostname, i.GetPortAuth())
tconf.Proxy.SSHAddr.Addr = net.JoinHostPort(i.Hostname, i.GetPortProxy())

View file

@ -46,7 +46,7 @@ type APISuite struct {
bk backend.Backend
a *AuthServer
dir string
alog *events.AuditLog
alog events.IAuditLog
sessions session.Service
CAS services.Trust
@ -101,8 +101,12 @@ func (s *APISuite) SetUpTest(c *C) {
}
func (s *APISuite) TearDownTest(c *C) {
fileBasedLog, ok := s.alog.(*events.AuditLog)
c.Assert(ok, Equals, true)
if ok {
fileBasedLog.Close()
}
s.srv.Close()
s.alog.Close()
os.RemoveAll(s.dir)
}

View file

@ -45,7 +45,7 @@ type TunSuite struct {
a *AuthServer
signer ssh.Signer
dir string
alog *events.AuditLog
alog events.IAuditLog
conf *APIConfig
sessionServer session.Service
}

View file

@ -90,9 +90,7 @@ const (
type TimeSourceFunc func() time.Time
// AuditLog is a new combined facility to record Teleport events and
// sessions. It implements these interfaces:
// - events.Log
// - recorder.Recorder
// sessions. It implements IAuditLog
type AuditLog struct {
sync.Mutex
loggers map[session.ID]*SessionLogger
@ -206,7 +204,7 @@ func (sl *SessionLogger) Write(bytes []byte) (written int, err error) {
// Creates and returns a new Audit Log oboject whish will store its logfiles
// in a given directory>
func NewAuditLog(dataDir string) (*AuditLog, error) {
func NewAuditLog(dataDir string) (IAuditLog, error) {
// create a directory for session logs:
if err := os.MkdirAll(dataDir, 0770); err != nil {
return nil, trace.Wrap(err)

View file

@ -11,6 +11,7 @@ import (
"gopkg.in/check.v1"
"github.com/gravitational/teleport/lib/utils"
"github.com/gravitational/trace"
)
type AuditTestSuite struct {
@ -26,13 +27,27 @@ func (a *AuditTestSuite) TearDownSuite(c *check.C) {
os.RemoveAll(a.dataDir)
}
// creates a file-based audit log and returns a proper *AuditLog pointer
// instead of the usual IAuditLog interface
func (a *AuditTestSuite) makeLog(c *check.C, dataDir string) (*AuditLog, error) {
alog, err := NewAuditLog(dataDir)
if err != nil {
return nil, trace.Wrap(err)
}
retval, ok := alog.(*AuditLog)
if !ok {
c.FailNow()
}
return retval, nil
}
func (a *AuditTestSuite) SetUpSuite(c *check.C) {
utils.InitLoggerForTests()
a.dataDir = c.MkDir()
}
func (a *AuditTestSuite) TestNew(c *check.C) {
alog, err := NewAuditLog(a.dataDir)
alog, err := a.makeLog(c, a.dataDir)
c.Assert(err, check.IsNil)
// close twice:
c.Assert(alog.Close(), check.IsNil)
@ -44,7 +59,7 @@ func (a *AuditTestSuite) TestComplexLogging(c *check.C) {
os.RemoveAll(a.dataDir)
// create audit log, write a couple of events into it, close it
alog, err := NewAuditLog(a.dataDir)
alog, err := a.makeLog(c, a.dataDir)
c.Assert(err, check.IsNil)
alog.TimeSource = func() time.Time { return now }
@ -122,7 +137,7 @@ func (a *AuditTestSuite) TestComplexLogging(c *check.C) {
func (a *AuditTestSuite) TestBasicLogging(c *check.C) {
now := time.Now().In(time.UTC).Round(time.Second)
// create audit log, write a couple of events into it, close it
alog, err := NewAuditLog(a.dataDir)
alog, err := a.makeLog(c, a.dataDir)
c.Assert(err, check.IsNil)
alog.TimeSource = func() time.Time { return now }

29
lib/events/discard.go Normal file
View file

@ -0,0 +1,29 @@
package events
import (
"io"
"time"
"github.com/gravitational/teleport/lib/session"
)
// DiscardAuditLog is do-nothing, discard-everything implementation
// of IAuditLog interface used for cases when audit is turned off
type DiscardAuditLog struct {
}
func (d *DiscardAuditLog) EmitAuditEvent(eventType string, fields EventFields) error {
return nil
}
func (d *DiscardAuditLog) PostSessionChunk(sid session.ID, reader io.Reader) error {
return nil
}
func (d *DiscardAuditLog) GetSessionChunk(sid session.ID, offsetBytes, maxBytes int) ([]byte, error) {
return make([]byte, 0), nil
}
func (d *DiscardAuditLog) GetSessionEvents(sid session.ID, after int) ([]EventFields, error) {
return make([]EventFields, 0), nil
}
func (d *DiscardAuditLog) SearchEvents(fromUTC, toUTC time.Time, query string) ([]EventFields, error) {
return make([]EventFields, 0), nil
}

View file

@ -262,6 +262,9 @@ type AuthConfig struct {
}
Limiter limiter.LimiterConfig
// NoAudit, when set to true, disables session recording and event audit
NoAudit bool
}
// SSHConfig configures SSH server node role

View file

@ -273,9 +273,15 @@ func (process *TeleportProcess) initAuthService(authority auth.Authority) error
// create the audit log, which will be consuming (and recording) all events
// and record sessions
auditLog, err := events.NewAuditLog(filepath.Join(cfg.DataDir, "log"))
if err != nil {
return trace.Wrap(err)
var auditLog events.IAuditLog
if cfg.Auth.NoAudit {
auditLog = &events.DiscardAuditLog{}
log.Warn("the audit and session recording are turned off")
} else {
auditLog, err = events.NewAuditLog(filepath.Join(cfg.DataDir, "log"))
if err != nil {
return trace.Wrap(err)
}
}
// first, create the AuthServer

View file

@ -62,7 +62,7 @@ type SrvSuite struct {
bk backend.Backend
a *auth.AuthServer
roleAuth *auth.AuthWithRoles
alog *events.AuditLog
alog events.IAuditLog
up *upack
signer ssh.Signer
dir string

View file

@ -76,7 +76,7 @@ type WebSuite struct {
freePorts []string
// audit log and its dir:
auditLog *events.AuditLog
auditLog events.IAuditLog
logDir string
}