@@ -58,7 +58,6 @@ type SessionConfig struct {
|
||||
|
||||
// OsqueryConfig defines configs related to osquery
|
||||
type OsqueryConfig struct {
|
||||
EnrollSecret string
|
||||
NodeKeySize int
|
||||
StatusLogFile string
|
||||
ResultLogFile string
|
||||
@@ -122,7 +121,6 @@ func (man Manager) addConfigs() {
|
||||
man.addConfigDuration("session.duration", 24*90*time.Hour)
|
||||
|
||||
// Osquery
|
||||
man.addConfigString("osquery.enroll_secret", "")
|
||||
man.addConfigInt("osquery.node_key_size", 24)
|
||||
man.addConfigString("osquery.status_log_file", "/tmp/osquery_status")
|
||||
man.addConfigString("osquery.result_log_file", "/tmp/osquery_result")
|
||||
@@ -171,7 +169,6 @@ func (man Manager) LoadConfig() KolideConfig {
|
||||
Duration: man.getConfigDuration("session.duration"),
|
||||
},
|
||||
Osquery: OsqueryConfig{
|
||||
EnrollSecret: man.getConfigString("osquery.enroll_secret"),
|
||||
NodeKeySize: man.getConfigInt("osquery.node_key_size"),
|
||||
StatusLogFile: man.getConfigString("osquery.status_log_file"),
|
||||
ResultLogFile: man.getConfigString("osquery.result_log_file"),
|
||||
@@ -374,7 +371,6 @@ func TestConfig() KolideConfig {
|
||||
Duration: 24 * 90 * time.Hour,
|
||||
},
|
||||
Osquery: OsqueryConfig{
|
||||
EnrollSecret: "",
|
||||
NodeKeySize: 24,
|
||||
StatusLogFile: "",
|
||||
ResultLogFile: "",
|
||||
|
||||
@@ -33,6 +33,7 @@ func (d *Datastore) SaveAppConfig(info *kolide.AppConfig) error {
|
||||
org_name,
|
||||
org_logo_url,
|
||||
kolide_server_url,
|
||||
osquery_enroll_secret,
|
||||
smtp_configured,
|
||||
smtp_sender_address,
|
||||
smtp_server,
|
||||
@@ -46,11 +47,12 @@ func (d *Datastore) SaveAppConfig(info *kolide.AppConfig) error {
|
||||
smtp_verify_ssl_certs,
|
||||
smtp_enable_start_tls
|
||||
)
|
||||
VALUES( 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
VALUES( 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
ON DUPLICATE KEY UPDATE
|
||||
org_name = VALUES(org_name),
|
||||
org_logo_url = VALUES(org_logo_url),
|
||||
kolide_server_url = VALUES(kolide_server_url),
|
||||
osquery_enroll_secret = VALUES(osquery_enroll_secret),
|
||||
smtp_configured = VALUES(smtp_configured),
|
||||
smtp_sender_address = VALUES(smtp_sender_address),
|
||||
smtp_server = VALUES(smtp_server),
|
||||
@@ -69,6 +71,7 @@ func (d *Datastore) SaveAppConfig(info *kolide.AppConfig) error {
|
||||
info.OrgName,
|
||||
info.OrgLogoURL,
|
||||
info.KolideServerURL,
|
||||
info.EnrollSecret,
|
||||
info.SMTPConfigured,
|
||||
info.SMTPSenderAddress,
|
||||
info.SMTPServer,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package tables
|
||||
|
||||
import "database/sql"
|
||||
|
||||
func init() {
|
||||
MigrationClient.AddMigration(Up_20170118191001, Down_20170118191001)
|
||||
}
|
||||
|
||||
func Up_20170118191001(tx *sql.Tx) error {
|
||||
_, err := tx.Exec(
|
||||
"ALTER TABLE `app_configs` " +
|
||||
"ADD COLUMN `osquery_enroll_secret` VARCHAR(255) NOT NULL DEFAULT '';",
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func Down_20170118191001(tx *sql.Tx) error {
|
||||
_, err := tx.Exec(
|
||||
"ALTER TABLE `app_configs` " +
|
||||
"DROP COLUMN `osquery_enroll_secret`;",
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -78,6 +78,12 @@ type AppConfig struct {
|
||||
OrgName string `db:"org_name"`
|
||||
OrgLogoURL string `db:"org_logo_url"`
|
||||
KolideServerURL string `db:"kolide_server_url"`
|
||||
|
||||
// EnrollSecret is the config value that must be given by osqueryd hosts
|
||||
// on enrollment.
|
||||
// See https://osquery.readthedocs.io/en/stable/deployment/remote/#remote-authentication
|
||||
EnrollSecret string `db:"osquery_enroll_secret"`
|
||||
|
||||
// SMTPConfigured is a flag that indicates if smtp has been successfully
|
||||
// tested with the settings provided by an admin user.
|
||||
SMTPConfigured bool `db:"smtp_configured"`
|
||||
@@ -170,6 +176,7 @@ type OrgInfo struct {
|
||||
// ServerSettings contains general settings about the kolide App.
|
||||
type ServerSettings struct {
|
||||
KolideServerURL *string `json:"kolide_server_url"`
|
||||
EnrollSecret *string `json:"osquery_enroll_secret"`
|
||||
}
|
||||
|
||||
type OrderDirection int
|
||||
|
||||
@@ -199,6 +199,8 @@ func TestGetNodeKey(t *testing.T) {
|
||||
func TestAuthenticatedHost(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
require.Nil(t, err)
|
||||
_, err = ds.NewAppConfig(&kolide.AppConfig{EnrollSecret: "foobarbaz"})
|
||||
require.Nil(t, err)
|
||||
svc, err := newTestService(ds, nil)
|
||||
require.Nil(t, err)
|
||||
|
||||
@@ -210,7 +212,7 @@ func TestAuthenticatedHost(t *testing.T) {
|
||||
)
|
||||
|
||||
ctx := context.Background()
|
||||
goodNodeKey, err := svc.EnrollAgent(ctx, "", "host123")
|
||||
goodNodeKey, err := svc.EnrollAgent(ctx, "foobarbaz", "host123")
|
||||
assert.Nil(t, err)
|
||||
require.NotEmpty(t, goodNodeKey)
|
||||
|
||||
|
||||
@@ -11,12 +11,14 @@ type setupRequest struct {
|
||||
Admin *kolide.UserPayload `json:"admin"`
|
||||
OrgInfo *kolide.OrgInfo `json:"org_info"`
|
||||
KolideServerURL *string `json:"kolide_server_url"`
|
||||
EnrollSecret *string `json:"osquery_enroll_secret"`
|
||||
}
|
||||
|
||||
type setupResponse struct {
|
||||
Admin *kolide.User `json:"admin,omitempty"`
|
||||
OrgInfo *kolide.OrgInfo `json:"org_info,omitempty"`
|
||||
KolideServerURL *string `json:"kolide_server_url"`
|
||||
EnrollSecret *string `json:"osquery_enroll_secret"`
|
||||
Token *string `json:"token,omitempty"`
|
||||
Err error `json:"error,omitempty"`
|
||||
}
|
||||
@@ -32,22 +34,29 @@ func makeSetupEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||
err error
|
||||
)
|
||||
req := request.(setupRequest)
|
||||
if req.OrgInfo != nil {
|
||||
configPayload.OrgInfo = req.OrgInfo
|
||||
}
|
||||
configPayload.ServerSettings = &kolide.ServerSettings{}
|
||||
if req.KolideServerURL != nil {
|
||||
configPayload.ServerSettings.KolideServerURL = req.KolideServerURL
|
||||
}
|
||||
if req.EnrollSecret != nil {
|
||||
configPayload.ServerSettings.EnrollSecret = req.EnrollSecret
|
||||
}
|
||||
config, err = svc.NewAppConfig(ctx, configPayload)
|
||||
if err != nil {
|
||||
return setupResponse{Err: err}, nil
|
||||
}
|
||||
// creating the user should be the last action. If there's a user
|
||||
// present and other errors occur, the setup endpoint closes.
|
||||
if req.Admin != nil {
|
||||
admin, err = svc.NewAdminCreatedUser(ctx, *req.Admin)
|
||||
if err != nil {
|
||||
return setupResponse{Err: err}, nil
|
||||
}
|
||||
}
|
||||
if req.OrgInfo != nil {
|
||||
configPayload.OrgInfo = req.OrgInfo
|
||||
}
|
||||
if req.KolideServerURL != nil {
|
||||
configPayload.ServerSettings = &kolide.ServerSettings{KolideServerURL: req.KolideServerURL}
|
||||
}
|
||||
config, err = svc.NewAppConfig(ctx, configPayload)
|
||||
if err != nil {
|
||||
return setupResponse{Err: err}, nil
|
||||
}
|
||||
|
||||
// If everything works to this point, log the user in and return token. If
|
||||
// the login fails for some reason, ignore the error and don't return
|
||||
// a token, forcing the user to log in manually
|
||||
@@ -63,6 +72,7 @@ func makeSetupEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||
OrgLogoURL: &config.OrgLogoURL,
|
||||
},
|
||||
KolideServerURL: &config.KolideServerURL,
|
||||
EnrollSecret: &config.EnrollSecret,
|
||||
Token: token,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -32,7 +32,16 @@ func (svc service) NewAppConfig(ctx context.Context, p kolide.AppConfigPayload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newConfig, err := svc.ds.NewAppConfig(appConfigFromAppConfigPayload(p, *config))
|
||||
fromPayload := appConfigFromAppConfigPayload(p, *config)
|
||||
if fromPayload.EnrollSecret == "" {
|
||||
// generate a random string if the user hasn't set one in the form
|
||||
// TODO: actually generate the string. Until there's a UI to
|
||||
// set/view the secret, we need to be ablet o enroll hosts so this value
|
||||
// is hardcoded.
|
||||
rand := "qrsvavgrylfrpher"
|
||||
fromPayload.EnrollSecret = rand
|
||||
}
|
||||
newConfig, err := svc.ds.NewAppConfig(fromPayload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -95,6 +104,9 @@ func appConfigFromAppConfigPayload(p kolide.AppConfigPayload, config kolide.AppC
|
||||
if p.ServerSettings != nil && p.ServerSettings.KolideServerURL != nil {
|
||||
config.KolideServerURL = *p.ServerSettings.KolideServerURL
|
||||
}
|
||||
if p.ServerSettings != nil && p.ServerSettings.EnrollSecret != nil {
|
||||
config.EnrollSecret = *p.ServerSettings.EnrollSecret
|
||||
}
|
||||
|
||||
populateSMTP := func(p *kolide.SMTPSettingsPayload) {
|
||||
if p.SMTPAuthenticationMethod != nil {
|
||||
|
||||
@@ -50,7 +50,12 @@ func (svc service) AuthenticateHost(ctx context.Context, nodeKey string) (*kolid
|
||||
}
|
||||
|
||||
func (svc service) EnrollAgent(ctx context.Context, enrollSecret, hostIdentifier string) (string, error) {
|
||||
if enrollSecret != svc.config.Osquery.EnrollSecret {
|
||||
config, err := svc.ds.AppConfig()
|
||||
if err != nil {
|
||||
return "", osqueryError{message: "getting enroll secret: " + err.Error(), nodeInvalid: true}
|
||||
}
|
||||
|
||||
if enrollSecret != config.EnrollSecret {
|
||||
return "", osqueryError{message: "invalid enroll secret", nodeInvalid: true}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,7 @@ import (
|
||||
)
|
||||
|
||||
func TestEnrollAgent(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
svc, err := newTestService(ds, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ds, svc, _ := setupOsqueryTests(t)
|
||||
ctx := context.Background()
|
||||
|
||||
hosts, err := ds.ListHosts(kolide.ListOptions{})
|
||||
@@ -37,7 +32,7 @@ func TestEnrollAgent(t *testing.T) {
|
||||
assert.Len(t, hosts, 0)
|
||||
|
||||
nodeKey, err := svc.EnrollAgent(ctx, "", "host123")
|
||||
assert.Nil(t, err)
|
||||
require.Nil(t, err)
|
||||
assert.NotEmpty(t, nodeKey)
|
||||
|
||||
hosts, err = ds.ListHosts(kolide.ListOptions{})
|
||||
@@ -46,12 +41,7 @@ func TestEnrollAgent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEnrollAgentIncorrectEnrollSecret(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
svc, err := newTestService(ds, nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ds, svc, _ := setupOsqueryTests(t)
|
||||
ctx := context.Background()
|
||||
|
||||
hosts, err := ds.ListHosts(kolide.ListOptions{})
|
||||
@@ -68,18 +58,11 @@ func TestEnrollAgentIncorrectEnrollSecret(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSubmitStatusLogs(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ds, svc, mockClock := setupOsqueryTests(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, err = svc.EnrollAgent(ctx, "", "host123")
|
||||
assert.Nil(t, err)
|
||||
_, err := svc.EnrollAgent(ctx, "", "host123")
|
||||
require.Nil(t, err)
|
||||
|
||||
hosts, err := ds.ListHosts(kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
@@ -140,18 +123,11 @@ func TestSubmitStatusLogs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSubmitResultLogs(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ds, svc, mockClock := setupOsqueryTests(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, err = svc.EnrollAgent(ctx, "", "host123")
|
||||
assert.Nil(t, err)
|
||||
_, err := svc.EnrollAgent(ctx, "", "host123")
|
||||
require.Nil(t, err)
|
||||
|
||||
hosts, err := ds.ListHosts(kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
@@ -249,18 +225,12 @@ func TestHostDetailQueries(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLabelQueries(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ds, svc, mockClock := setupOsqueryTests(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, err = svc.EnrollAgent(ctx, "", "host123")
|
||||
assert.Nil(t, err)
|
||||
_, err := svc.EnrollAgent(ctx, "", "host123")
|
||||
require.Nil(t, err)
|
||||
|
||||
hosts, err := ds.ListHosts(kolide.ListOptions{})
|
||||
require.Nil(t, err)
|
||||
@@ -467,14 +437,7 @@ func TestGetClientConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDetailQueries(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
||||
assert.Nil(t, err)
|
||||
|
||||
ds, svc, mockClock := setupOsqueryTests(t)
|
||||
ctx := context.Background()
|
||||
|
||||
nodeKey, err := svc.EnrollAgent(ctx, "", "host123")
|
||||
@@ -617,6 +580,9 @@ func TestDistributedQueries(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ds.NewAppConfig(&kolide.AppConfig{EnrollSecret: ""})
|
||||
require.Nil(t, err)
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
|
||||
rs := pubsub.NewInmemQueryResults()
|
||||
@@ -740,6 +706,9 @@ func TestOrphanedQueryCampaign(t *testing.T) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ds.NewAppConfig(&kolide.AppConfig{EnrollSecret: ""})
|
||||
require.Nil(t, err)
|
||||
|
||||
rs := pubsub.NewInmemQueryResults()
|
||||
|
||||
svc, err := newTestService(ds, rs)
|
||||
@@ -792,3 +761,17 @@ func TestOrphanedQueryCampaign(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, kolide.QueryComplete, campaign.Status)
|
||||
}
|
||||
|
||||
func setupOsqueryTests(t *testing.T) (kolide.Datastore, kolide.Service, *clock.MockClock) {
|
||||
ds, err := inmem.New(config.TestConfig())
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = ds.NewAppConfig(&kolide.AppConfig{EnrollSecret: ""})
|
||||
require.Nil(t, err)
|
||||
|
||||
mockClock := clock.NewMockClock()
|
||||
svc, err := newTestServiceWithClock(ds, nil, mockClock)
|
||||
require.Nil(t, err)
|
||||
|
||||
return ds, svc, mockClock
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ Before using the following commands, set the environment variable `LOCALHOST` to
|
||||
set `KOLIDE_OSQUERY_VERSION` to either `1.8.2` or `latest` (currently 2.1.2) to indicate which version of osquery that you want to run on your
|
||||
containers.
|
||||
|
||||
You will also need to set the environment variable `ENROLL_SECRET` to the value of your kolide enroll secret(configured during the app setup or in the app config UI).
|
||||
|
||||
### Running osqueryd
|
||||
|
||||
The osqueryd instances are configured to use the TLS plugins at `$LOCALHOST:8080`. Using the `example_config.json` in this directory should configure Kolide with the appropriate settings for these `osqueryd` containers to connect.
|
||||
|
||||
@@ -10,7 +10,7 @@ services:
|
||||
extra_hosts:
|
||||
- "dockerhost:${LOCALHOST}"
|
||||
environment:
|
||||
ENROLL_SECRET: ''
|
||||
ENROLL_SECRET: "${ENROLL_SECRET}"
|
||||
command: osqueryd --flagfile=/etc/osquery/osquery.flags
|
||||
ulimits:
|
||||
core:
|
||||
@@ -25,7 +25,7 @@ services:
|
||||
extra_hosts:
|
||||
- "dockerhost:${LOCALHOST}"
|
||||
environment:
|
||||
ENROLL_SECRET: ''
|
||||
ENROLL_SECRET: "${ENROLL_SECRET}"
|
||||
command: osqueryd --flagfile=/etc/osquery/osquery.flags
|
||||
ulimits:
|
||||
core:
|
||||
|
||||
Reference in New Issue
Block a user