Skip to content

Commit

Permalink
Merge pull request #54 from jmpsec/test-handlers-tls
Browse files Browse the repository at this point in the history
Refactor for TLS handlers
  • Loading branch information
javuto authored Mar 26, 2020
2 parents c21be72 + 8112ce9 commit cb8ff04
Show file tree
Hide file tree
Showing 31 changed files with 1,253 additions and 541 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ script:
- go build -o bin/osctrl-tls tls/*.go
- go build -o bin/osctrl-admin admin/*.go
- go build -o bin/osctrl-cli cli/*.go
- go test ./utils -v
- go test ./tls/handlers -v
25 changes: 3 additions & 22 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -182,27 +182,8 @@ gofmt-api:
gofmt-cli:
gofmt $(GOFMT_ARGS) ./$(CLI_CODE)

# Run tests for modules
modules-test:
cd utils && go test -i . -v
cd utils && go test . -v

# Run all tests
test:
make modules-test
# Install dependencies for TLS
cd $(TLS_DIR) && go test -i . -v
# Run TLS tests
cd $(TLS_DIR) && go test . -v
# Install dependencies for Admin
cd $(ADMIN_DIR) && go test -i . -v
# Run Admin tests
cd $(ADMIN_DIR) && go test . -v
# Install dependencies for API
cd $(API_DIR) && go test -i . -v
# Run API tests
cd $(API_DIR) && go test . -v
# Install dependencies for CLI
cd $(CLI_DIR) && go test -i . -v
# Run CLI tests
cd $(CLI_DIR) && go test . -v
go clean -testcache ./...
go test ./utils -v
go test ./tls/handlers -v
3 changes: 3 additions & 0 deletions admin/handlers/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/javuto/osctrl/admin/handlers

go 1.12
10 changes: 10 additions & 0 deletions admin/handlers/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package handlers

const (
metricJSONReq = "admin-json-req"
metricJSONErr = "admin-json-err"
metricJSONOK = "admin-json-ok"
metricHealthReq = "health-req"
metricHealthOK = "health-ok"
)

5 changes: 3 additions & 2 deletions admin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,6 @@ func main() {
// Initialize service settings
log.Println("Loading service settings")
loadingSettings()
// multiple listeners channel
finish := make(chan bool)

// Start SAML Middleware if we are using SAML
if adminConfig.Auth == settings.AuthSAML {
Expand Down Expand Up @@ -416,6 +414,9 @@ func main() {
}
}()

// multiple listeners channel
finish := make(chan bool)

// Launch HTTP server for admin
go func() {
serviceAdmin := adminConfig.Listener + ":" + adminConfig.Port
Expand Down
13 changes: 8 additions & 5 deletions deploy/provision.sh
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,14 @@ DEST="$DEST_PATH" make install_cli

# If we are in dev, create environment and enroll host
if [[ "$MODE" == "dev" ]]; then
log "Creating environment for dev"
__db_conf="$DEST_PATH/config/$DB_CONF"

# Create admin user
log "Creating admin user"
"$DEST_PATH"/osctrl-cli -D "$__db_conf" user add -u "$_ADMIN_USER" -p "$_ADMIN_PASS" -a -n Admin

# Create environment for dev
log "Creating environment for dev"
__osquery_dev="$SOURCE_PATH/deploy/osquery/osquery-dev.json"
__osctrl_crt="/etc/nginx/certs/osctrl.crt"
"$DEST_PATH"/osctrl-cli -D "$__db_conf" environment add -n "dev" -host "$_T_HOST" -conf "$__osquery_dev" -crt "$__osctrl_crt"
Expand All @@ -649,16 +655,13 @@ if [[ "$MODE" == "dev" ]]; then
sleep 1
done

# Enroll host in environment
if [[ "$ENROLL" == true ]]; then
log "Adding host in dev environment"
eval $( "$DEST_PATH"/osctrl-cli -D "$__db_conf" environment quick-add -n "dev" )
fi
fi

# Create admin user
log "Creating admin user"
"$DEST_PATH"/osctrl-cli -D "$__db_conf" user add -u "$_ADMIN_USER" -p "$_ADMIN_PASS" -a -n Admin

# Ascii art is always appreciated
if [[ "$DISTRO" == "ubuntu" ]]; then
set_motd_ubuntu "$SOURCE_PATH/deploy/motd-osctrl.sh"
Expand Down
2 changes: 1 addition & 1 deletion environments/environments.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (environment *Environment) Names() ([]string, error) {
func (environment *Environment) GetMap() (MapEnvironments, error) {
all, err := environment.All()
if err != nil {
return MapEnvironments{}, fmt.Errorf("error getting environments %v", err)
return nil, fmt.Errorf("error getting environments %v", err)
}
_map := make(MapEnvironments)
for _, e := range all {
Expand Down
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ require (
github.com/jmpsec/osctrl/environments v0.2.1
github.com/jmpsec/osctrl/logging v0.2.1
github.com/jmpsec/osctrl/metrics v0.2.1
github.com/jmpsec/osctrl/nodes v0.2.1
github.com/jmpsec/osctrl/queries v0.2.1
github.com/jmpsec/osctrl/nodes v0.0.0-20200321003619-c21be7214ee4
github.com/jmpsec/osctrl/queries v0.0.0-20200321003619-c21be7214ee4
github.com/jmpsec/osctrl/settings v0.2.1
github.com/jmpsec/osctrl/tls/handlers v0.2.1
github.com/jmpsec/osctrl/types v0.2.1
github.com/jmpsec/osctrl/users v0.2.1
github.com/jmpsec/osctrl/utils v0.2.1
github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/olekukonko/tablewriter v0.0.1
github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7 // indirect
github.com/segmentio/ksuid v1.0.2
github.com/spf13/viper v1.6.2
github.com/urfave/cli v1.20.0
)
Expand All @@ -51,3 +51,5 @@ replace github.com/jmpsec/osctrl/users => ./users
replace github.com/jmpsec/osctrl/utils => ./utils

replace github.com/jmpsec/osctrl/logging => ./logging

replace github.com/jmpsec/osctrl/tls/handlers => ./tls/handlers
1 change: 0 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
Expand Down
29 changes: 19 additions & 10 deletions logging/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"github.com/jinzhu/gorm"

"github.com/jmpsec/osctrl/backend"
"github.com/jmpsec/osctrl/types"
"github.com/jmpsec/osctrl/settings"
"github.com/jmpsec/osctrl/types"
)

const (
Expand Down Expand Up @@ -82,19 +82,28 @@ func CreateLoggerDB() (*LoggerDB, error) {
func (logDB *LoggerDB) Settings(mgr *settings.Settings) {
log.Printf("Setting DB logging settings\n")
// Setting link for on-demand queries
v := settings.QueryLink
if err := mgr.SetString(v, settings.ServiceAdmin, settings.QueryResultLink, false); err != nil {
log.Printf("Error setting %s with %s - %v", v, settings.QueryResultLink, err)
if !mgr.IsValue(settings.ServiceAdmin, settings.QueryResultLink) {
if err := mgr.NewStringValue(settings.ServiceAdmin, settings.QueryResultLink, settings.QueryLink); err != nil {
log.Fatalf("Failed to add %s to settings: %v", settings.QueryResultLink, err)
}
} else if err := mgr.SetString(settings.QueryLink, settings.ServiceAdmin, settings.QueryResultLink, false); err != nil {
log.Printf("Error setting %s with %s - %v", settings.QueryResultLink, settings.QueryLink, err)
}
v = settings.StatusLink
// Setting link for status logs
if err := mgr.SetString(v, settings.ServiceAdmin, settings.StatusLogsLink, false); err != nil {
log.Printf("Error setting %s with %s - %v", v, settings.StatusLogsLink, err)
if !mgr.IsValue(settings.ServiceAdmin, settings.StatusLogsLink) {
if err := mgr.NewStringValue(settings.ServiceAdmin, settings.StatusLogsLink, settings.StatusLink); err != nil {
log.Fatalf("Failed to add %s to settings: %v", settings.DebugHTTP, err)
}
} else if err := mgr.SetString(settings.StatusLink, settings.ServiceAdmin, settings.StatusLogsLink, false); err != nil {
log.Printf("Error setting %s with %s - %v", settings.StatusLogsLink, settings.StatusLink, err)
}
v = settings.ResultsLink
// Setting link for result logs
if err := mgr.SetString(v, settings.ServiceAdmin, settings.ResultLogsLink, false); err != nil {
log.Printf("Error setting %s with %s - %v", v, settings.ResultLogsLink, err)
if !mgr.IsValue(settings.ServiceAdmin, settings.ResultLogsLink) {
if err := mgr.NewStringValue(settings.ServiceAdmin, settings.ResultLogsLink, settings.ResultsLink); err != nil {
log.Fatalf("Failed to add %s to settings: %v", settings.DebugHTTP, err)
}
} else if err := mgr.SetString(settings.ResultsLink, settings.ServiceAdmin, settings.ResultLogsLink, false); err != nil {
log.Printf("Error setting %s with %s - %v", settings.ResultLogsLink, settings.ResultsLink, err)
}
}

Expand Down
66 changes: 66 additions & 0 deletions logging/dispatch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package logging

import (
"encoding/json"
"log"

"github.com/jmpsec/osctrl/nodes"
"github.com/jmpsec/osctrl/types"
)

// DispatchLogs - Helper to dispatch logs
func (l *LoggerTLS) DispatchLogs(data []byte, uuid, logType, environment string, metadata nodes.NodeMetadata, debug bool) {
// Use metadata to update record
if err := l.Nodes.UpdateMetadataByUUID(uuid, metadata); err != nil {
log.Printf("error updating metadata %s", err)
}
// Send data to storage
// FIXME allow multiple types of logging
if debug {
log.Printf("dispatching logs to %s", l.Logging)
}
l.Log(
logType,
data,
environment,
uuid,
debug)
// Refresh last logging request
if logType == types.StatusLog {
err := l.Nodes.RefreshLastStatus(uuid)
if err != nil {
log.Printf("error refreshing last status %v", err)
}
}
if logType == types.ResultLog {
if err := l.Nodes.RefreshLastResult(uuid); err != nil {
log.Printf("error refreshing last result %v", err)
}
}
}

// DispatchQueries - Helper to dispatch queries
func (l *LoggerTLS) DispatchQueries(queryData types.QueryWriteData, node nodes.OsqueryNode, debug bool) {
// Prepare data to send
data, err := json.Marshal(queryData)
if err != nil {
log.Printf("error preparing data %v", err)
}
// Refresh last query write request
if err := l.Nodes.RefreshLastQueryWrite(node.UUID); err != nil {
log.Printf("error refreshing last query write %v", err)
}
// Send data to storage
// FIXME allow multiple types of logging
if debug {
log.Printf("dispatching queries to %s", l.Logging)
}
l.QueryLog(
types.QueryLog,
data,
node.Environment,
node.UUID,
queryData.Name,
queryData.Status,
debug)
}
1 change: 0 additions & 1 deletion logging/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZ
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmpsec/osctrl v0.1.9 h1:AyxqZs+XfTaqlsG/b54e2Rlh4mu2+oGd5cUUb1+K97k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
Expand Down
8 changes: 7 additions & 1 deletion logging/logging.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package logging

import (
"github.com/jmpsec/osctrl/nodes"
"github.com/jmpsec/osctrl/queries"
"github.com/jmpsec/osctrl/settings"
)

Expand All @@ -10,15 +12,19 @@ type LoggerTLS struct {
Graylog *LoggerGraylog
Splunk *LoggerSplunk
Logging string
Nodes *nodes.NodeManager
Queries *queries.Queries
}

// CreateLoggerTLS to instantiate a new logger for the TLS endpoint
func CreateLoggerTLS(logging string, mgr *settings.Settings) (*LoggerTLS, error) {
func CreateLoggerTLS(logging string, mgr *settings.Settings, nodes *nodes.NodeManager, queries *queries.Queries) (*LoggerTLS, error) {
l := &LoggerTLS{
DB: &LoggerDB{},
Splunk: &LoggerSplunk{},
Logging: logging,
Graylog: &LoggerGraylog{},
Nodes: nodes,
Queries: queries,
}
switch logging {
case settings.LoggingSplunk:
Expand Down
88 changes: 88 additions & 0 deletions logging/process.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package logging

import (
"encoding/json"
"log"

"github.com/jmpsec/osctrl/nodes"
"github.com/jmpsec/osctrl/types"
)

// ProcessLogs - Helper to process logs
func (l *LoggerTLS) ProcessLogs(data json.RawMessage, logType, environment, ipaddress string, debug bool) {
// Parse log to extract metadata
var logs []types.LogGenericData
err := json.Unmarshal(data, &logs)
if err != nil {
// FIXME metrics for this
log.Printf("error parsing log %s %v", string(data), err)
}
if debug {
log.Printf("parsing logs for metadata in %s:%s", logType, environment)
}
// Iterate through received messages to extract metadata
var uuids, hosts, names, users, osqueryusers, hashes, dhashes, osqueryversions []string
for _, l := range logs {
uuids = append(uuids, l.HostIdentifier)
hosts = append(hosts, l.Decorations.Hostname)
names = append(names, l.Decorations.LocalHostname)
users = append(users, l.Decorations.Username)
osqueryusers = append(osqueryusers, l.Decorations.OsqueryUser)
hashes = append(hashes, l.Decorations.ConfigHash)
dhashes = append(dhashes, l.Decorations.DaemonHash)
osqueryversions = append(osqueryversions, l.Version)
}
if debug {
log.Printf("metadata and dispatch for %s", uniq(uuids)[0])
}
// FIXME it only uses the first element from the []string that uniq returns
metadata := nodes.NodeMetadata{
IPAddress: ipaddress,
Username: uniq(users)[0],
OsqueryUser: uniq(osqueryusers)[0],
Hostname: uniq(hosts)[0],
Localname: uniq(names)[0],
ConfigHash: uniq(hashes)[0],
DaemonHash: uniq(dhashes)[0],
OsqueryVersion: uniq(osqueryversions)[0],
}
// Dispatch logs and update metadata
l.DispatchLogs(data, uniq(uuids)[0], logType, environment, metadata, debug)
}

// ProcessLogQueryResult - Helper to process on-demand query result logs
func (l *LoggerTLS) ProcessLogQueryResult(queries types.QueryWriteQueries, statuses types.QueryWriteStatuses, nodeKey string, environment string, debug bool) {
// Retrieve node
node, err := l.Nodes.GetByKey(nodeKey)
if err != nil {
log.Printf("error retrieving node %s", err)
}
// Tap into results so we can update internal metrics
for q, r := range queries {
// Dispatch query name, result and status
d := types.QueryWriteData{
Name: q,
Result: r,
Status: statuses[q],
}
go l.DispatchQueries(d, node, debug)
// Update internal metrics per query
var err error
if statuses[q] != 0 {
err = l.Queries.IncError(q)
} else {
err = l.Queries.IncExecution(q)
}
if err != nil {
log.Printf("error updating query %s", err)
}
// Add a record for this query
if err := l.Queries.TrackExecution(q, node.UUID, statuses[q]); err != nil {
log.Printf("error adding query execution %s", err)
}
// Check if query is completed
if err := l.Queries.VerifyComplete(q); err != nil {
log.Printf("error verifying and completing query %s", err)
}
}
}
Loading

0 comments on commit cb8ff04

Please sign in to comment.