Skip to content

Commit

Permalink
Merge pull request #290 from Security-Onion-Solutions/2.4/dev
Browse files Browse the repository at this point in the history
2.4.20
  • Loading branch information
TOoSmOotH authored Oct 6, 2023
2 parents 50bf234 + cad931a commit e0c759d
Show file tree
Hide file tree
Showing 27 changed files with 252 additions and 99 deletions.
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,5 @@ ENV WAZUH_VERSION=$WAZUH_VERSION

USER socore
EXPOSE 9822/tcp
VOLUME /opt/sensoroni/jobs
VOLUME /opt/sensoroni/logs

ENTRYPOINT ["/opt/sensoroni/sensoroni"]
4 changes: 1 addition & 3 deletions Dockerfile.kratos
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
FROM ghcr.io/security-onion-solutions/golang:alpine AS builder

ARG OWNER=ory
ARG VERSION=v0.13.0
ARG VERSION=v1.0.0

RUN addgroup -S ory; \
adduser -S ory -G ory -D -H -s /bin/nologin
Expand Down Expand Up @@ -56,6 +56,4 @@ USER kratos
EXPOSE 4433
EXPOSE 4434

VOLUME ["/kratos-conf", "/kratos-data", "/kratos-log"]

ENTRYPOINT ["/start-kratos.sh"]
33 changes: 23 additions & 10 deletions html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2987,7 +2987,7 @@ <h4 v-if="metricsEnabled">{{ i18n.gridEps }} {{ gridEps | formatCount }}</h4>
</v-btn>
</td>
<td>
<v-icon v-if="props.item.status == 'fault'" :id="'nodeFaultIcon_' + props.item.id" :color="props.item.status | colorNodeStatus">{{ props.item.status | iconNodeStatus }}</v-icon>
<v-icon v-if="props.item.status == 'fault'" :id="'nodeFaultIcon_' + props.item.id" :color="colorNodeStatus(props.item.status, props.item.nonCriticalNode)">{{ props.item.status | iconNodeStatus }}</v-icon>
</td>
<td :id="'nodeId_' + props.item.id" v-text="props.item.id"></td>
<td :id="'nodeRole_' + props.item.id" v-text="$root.localizeMessage(props.item.role)" class="d-none d-md-table-cell"></td>
Expand All @@ -2996,13 +2996,13 @@ <h4 v-if="metricsEnabled">{{ i18n.gridEps }} {{ gridEps | formatCount }}</h4>
<td :id="'nodeVersion_' + props.item.id" v-text="props.item.version" class="d-none d-lg-table-cell"></td>
<td :id="'nodeModel_' + props.item.id" v-text="props.item.model" class="d-none d-lg-table-cell"></td>
<td v-if="metricsEnabled" class="d-none d-lg-table-cell">
<span v-if="props.item.metricsEnabled" :id="'nodeEps_' + props.item.id">{{ props.item.productionEps | formatCount }} / {{ props.item.consumptionEps | formatCount }}</span>
<span v-if="props.item.metricsEnabled" :id="'nodeEps_' + props.item.id">{{ props.item.consumptionEps | formatCount }}</span>
<span v-if="!props.item.metricsEnabled" :id="'nodeEps_' + props.item.id">{{ i18n.na }}</span>
</td>
<td :id="'nodeUpdateTime_' + props.item.id" class="d-none d-lg-table-cell">{{ props.item.updateTime | toTZ }}</td>
<td :id="'nodeEpochTime_' + props.item.id" class="d-none d-lg-table-cell">{{ props.item.epochTime | toTZ }}</td>
<td :id="'nodeUptimeSeconds_' + props.item.id" class="d-none d-lg-table-cell">{{ props.item.uptimeSeconds | formatDuration }}</td>
<td class="d-none d-lg-table-cell"><v-chip :id="'nodeStatus_' + props.item.id" class="nodeStatus" @click="expand(props.item)" :color="props.item.status | colorNodeStatus">{{ $root.localizeMessage(props.item.status) }}</v-chip></td>
<td><v-chip :id="'nodeStatus_' + props.item.id" class="nodeStatus" @click="expand(props.item)" :color="colorNodeStatus(props.item.status, props.item.nonCriticalNode)">{{ $root.localizeMessage(props.item.status) }}</v-chip></td>
</tr>
</template>
<template v-slot:expanded-item="{ item }">
Expand Down Expand Up @@ -3050,21 +3050,23 @@ <h4 v-if="metricsEnabled">{{ i18n.gridEps }} {{ gridEps | formatCount }}</h4>
<span class="filter label">{{ i18n.uptime }}:</span>
<span class="filter value">{{ item.uptimeSeconds | formatDuration }}</span>
</div>
<div v-if="item.metricsEnabled" class="text-no-wrap">
<span class="filter label">{{ i18n.epsProduction }}</span>
<span class="filter value">{{ item.productionEps | formatCount }}</span>
</div>
<div v-if="item.metricsEnabled" class="text-no-wrap">
<span class="filter label">{{ i18n.epsConsumption }}</span>
<span class="filter value">{{ item.consumptionEps | formatCount }}</span>
</div>
<div v-if="item.metricsEnabled" class="text-no-wrap">
<span class="filter label">{{ i18n.nodeStatusProcess }}</span>
<span :class="colorNodeStatus(item.processStatus) + '--text'" class="filter value">{{ $root.localizeMessage(item.processStatus) }}</span>
<span :class="colorNodeStatus(item.processStatus) + '--text'" class="filter value">
{{ $root.localizeMessage(item.processStatus) }}
<span v-if="item.nonCriticalNode">({{i18n.nonCriticalNode}})</span>
</span>
</div>
<div class="text-no-wrap">
<span class="filter label">{{ i18n.nodeStatusConnection }}</span>
<span :class="colorNodeStatus(item.connectionStatus) + '--text'" class="filter value">{{ $root.localizeMessage(item.connectionStatus) }}</span>
<span :class="colorNodeStatus(item.connectionStatus, item.nonCriticalNode) + '--text'" class="filter value">
{{ $root.localizeMessage(item.connectionStatus) }}
<span v-if="item.nonCriticalNode">({{i18n.nonCriticalNode}})</span>
</span>
</div>
<div v-if="item.metricsEnabled" class="text-no-wrap">
<span class="filter label">{{ i18n.nodeStatusRaid }}</span>
Expand Down Expand Up @@ -3796,13 +3798,24 @@ <h2 v-text="i18n.gridMembers"></h2>
{{ i18n.reject }}
<v-icon right>fa-xmark</v-icon>
</v-btn>
<v-btn id="gridmember-remove" @click.stop="remove(selected)">
<v-btn id="gridmember-remove" @click.stop="confirmRemove()">
{{ i18n.delete }}
<v-icon right>fa-trash</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="confirmDeleteDialog" persistent max-width="575">
<v-card>
<v-card-title class="text-h5" v-text="i18n.gridMemberConfirmDelete" />
<v-card-text v-html="i18n.gridMemberConfirmDeleteHelp" />
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text id="gridmember-confirm-delete-button" @click="remove(selected)" v-text="i18n.yes" />
<v-btn text id="gridmember-confirm-cancel-button" @click="cancelRemove()" v-text="i18n.no" />
</v-card-actions>
</v-card>
</v-dialog>
</v-container>
</script>

Expand Down
2 changes: 1 addition & 1 deletion html/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ $(document).ready(function() {
const redirectCookie = this.getCookie('AUTH_REDIRECT');
if ((response.headers && response.headers['content-type'] == "text/html") ||
(response.status == 401 && response.request.responseURL.indexOf('/api/') == -1) ||
(response.request.responseURL.indexOf("/login/") == -1 && redirectCookie != null && redirectCookie.length > 0)) {
(response.request.responseURL.indexOf("/login/banner.md") == -1 && redirectCookie != null && redirectCookie.length > 0)) {
this.deleteCookie('AUTH_REDIRECT');
this.showLogin();
return null
Expand Down
3 changes: 2 additions & 1 deletion html/js/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,5 +432,6 @@ test('checkForUnauthorized', () => {
testCheckForUnauthorized('/api/', {status: 401}, null, false);
testCheckForUnauthorized('/foo/', {}, '/blah', true);
testCheckForUnauthorized('/foo/', {}, null, false);
testCheckForUnauthorized('/login/', {}, '/blah', false);
testCheckForUnauthorized('/login/banner.md', {}, '/blah', false);
testCheckForUnauthorized('/auth/self-service/login/browser', {}, '/blah', true);
});
5 changes: 5 additions & 0 deletions html/js/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ const i18n = {
grid: 'Grid',
gridEps: 'Grid EPS:',
gridMember: 'Review Grid Member',
gridMemberConfirmDelete: 'Delete Grid Member',
gridMemberConfirmDeleteHelp: 'Deleting a grid member is typically only necessary for re-installing a grid node.<p/>For already-accepted grid members note the following:<ul class="my-2"><li>Deleted members are removed from this Grid Members screen only.</li><li>Deleting <i>already accepted</i> members will only prevent that node from receiving grid configuration updates.</li><li>The Grid status screen will continue displaying the deleted member nodes that were already visible in the grid list prior to deletion.</li><li>The member node should be shutdown before proceeding, or else it could reappear on this Grid Members screen.</li><li>Restart the grid\'s manager node to clear out the old node information from the Grid status screen.</li></ul><p class="my-2"/>Would you like to delete this grid member?',
gridMemberHelp: 'Closely inspect pending grid members to ensure their identities match expected values. Only approve nodes that you confirm are legitimate.',
gridMemberInput: 'Acceptance Inputs',
gridMemberInputDescriptionHelp: 'User defined description of the new member node',
Expand Down Expand Up @@ -465,6 +467,7 @@ const i18n = {
nodeStatusRaid: 'RAID Status:',
nodeTest: 'Replay test data into this sensor node\'s monitoring interface',
noSearchResults: 'No search results were found.',
nonCriticalNode: 'Non-Critical Node',
none: 'None',
note: 'Note',
notFound: 'The selected item no longer exists',
Expand Down Expand Up @@ -584,6 +587,8 @@ const i18n = {
sha256: 'SHA256',
share: 'Clipboard',
showAll: 'Show all...',
'so-desktop': 'Desktop',
'so-desktop-keywords': 'Analyst, Desktop, sod, windows, wireshark, networkminer, miner, gui, workstation',
'so-eval': 'Evaluation',
'so-eval-keywords': 'Elastic, Elasticsearch, Fleet, Forward, Ingest, Manager, Master, Search, Sensor, Sensoroni, Soc, Stenographer, Web',
'so-fleet': 'Fleet',
Expand Down
10 changes: 5 additions & 5 deletions html/js/routes/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ routes.push({ path: '/grid', name: 'grid', component: {
{ text: this.$root.i18n.description, value: 'description', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.version, value: 'version', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.model, value: 'model', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.eps, value: 'productionEps', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.eps, value: 'consumptionEps', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.dateUpdated, value: 'updateTime', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.dateDataEpoch, value: 'epochTime', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.uptime, value: 'uptimeSeconds', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.status, value: 'status', align: ' d-none d-lg-table-cell' },
{ text: this.$root.i18n.status, value: 'status' },
{ text: '', value: 'keywords', align: ' d-none' },
],
expanded: [],
Expand Down Expand Up @@ -109,7 +109,7 @@ routes.push({ path: '/grid', name: 'grid', component: {
if (!this.metricsEnabled) {
epsColumn.align = ' d-none';
} else {
epsColumn.align = '';
epsColumn.align = ' d-none d-lg-table-cell';
}
}
},
Expand Down Expand Up @@ -284,10 +284,10 @@ routes.push({ path: '/grid', name: 'grid', component: {
}
return node;
},
colorNodeStatus(status) {
colorNodeStatus(status, nonCritical) {
var color = "warning";
switch (status) {
case NodeStatusFault: color = "error"; break;
case NodeStatusFault: color = nonCritical ? "warning" : "error"; break;
case NodeStatusOk: color = "success"; break;
}
return color;
Expand Down
6 changes: 4 additions & 2 deletions html/js/routes/grid.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,16 @@ function testUpdateMetricsEnabled(node1MetricsEnabled, node2MetricsEnabled, expe
if (!expectedMetricsEnabled) {
expect(epsColumn.align).toBe(' d-none');
} else {
expect(epsColumn.align).toBe('');
expect(epsColumn.align).toBe(' d-none d-lg-table-cell');
}
}

test('colorNodeStatus', () => {
expect(comp.colorNodeStatus("ok")).toBe("success");
expect(comp.colorNodeStatus("ok")).toBe("success");
expect(comp.colorNodeStatus("fault")).toBe("error");
expect(comp.colorNodeStatus("fault", true)).toBe("warning");
expect(comp.colorNodeStatus("unknown")).toBe("warning");
expect(comp.colorNodeStatus("unknown", true)).toBe("warning");
});

test('iconNodeStatus', () => {
Expand Down
8 changes: 8 additions & 0 deletions html/js/routes/gridmembers.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ routes.push({ path: '/gridmembers', name: 'gridmembers', component: {
accepted: [],
selected: null,
dialog: false,
confirmDeleteDialog: false,
rules: {
required: value => !!value || this.$root.i18n.required,
},
Expand Down Expand Up @@ -66,8 +67,15 @@ routes.push({ path: '/gridmembers', name: 'gridmembers', component: {
isUnaccepted(node) {
return node.status == GridMemberUnaccepted;
},
confirmRemove() {
this.confirmDeleteDialog = true;
},
cancelRemove() {
this.confirmDeleteDialog = false;
},
async remove(node) {
this.hide();
this.cancelRemove();
this.$root.startLoading();
try {
await this.$root.papi.post('gridmembers/' + node.id + "/delete");
Expand Down
23 changes: 17 additions & 6 deletions licensing/license_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,16 @@ func verify(key string) (*LicenseKey, error) {
return license, rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, hash[:], sigBytes)
}

func Init(key string) {
func CreateAvailableFeatureList() []string {
available := make([]string, 0, 0)
available = append(available, FEAT_FIPS)
available = append(available, FEAT_STIG)
available = append(available, FEAT_TIMETRACKING)
return available
}

func Init(key string) {
available := CreateAvailableFeatureList()

status := LICENSE_STATUS_UNPROVISIONED
licenseKey := &LicenseKey{}
Expand Down Expand Up @@ -194,11 +199,17 @@ func Init(key string) {
}

func Test(feat string, users int, nodes int, socUrl string, dataUrl string) {
available := make([]string, 0, 0)
available = append(available, feat)
available := CreateAvailableFeatureList()

licenseKey := &LicenseKey{}
licenseKey.Expiration = time.Now().Add(time.Minute * 1)
licenseKey.Features = available

if len(feat) > 0 {
features := make([]string, 0, 0)
features = append(features, feat)
licenseKey.Features = features
}

licenseKey.Users = users
licenseKey.Nodes = nodes
licenseKey.SocUrl = socUrl
Expand Down Expand Up @@ -314,9 +325,9 @@ func startPillarMonitor() {
# This file is generated by Security Onion and contains a list of license-enabled features.
`
if manager.status == LICENSE_STATUS_ACTIVE && len(manager.licenseKey.Features) > 0 {
if manager.status == LICENSE_STATUS_ACTIVE {
contents += "features:\n"
for _, feature := range manager.licenseKey.Features {
for _, feature := range ListEnabledFeatures() {
contents += "- " + feature + "\n"
}
} else {
Expand Down
20 changes: 20 additions & 0 deletions licensing/license_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,24 @@ func TestPillarMonitor(tester *testing.T) {
assert.Equal(tester, manager.status, LICENSE_STATUS_ACTIVE)
contents, _ := os.ReadFile(manager.pillarFilename)

expected := `
features:
- stig
`

assert.Contains(tester, string(contents), expected)
}

func TestPillarMonitorAllFeatures(tester *testing.T) {
Test("", 0, 0, "", "")

manager.pillarFilename = "/tmp/soc_test_pillar_monitor.sls"

os.Remove(manager.pillarFilename)
startPillarMonitor()
assert.Equal(tester, manager.status, LICENSE_STATUS_ACTIVE)
contents, _ := os.ReadFile(manager.pillarFilename)

expected := `
# Copyright Jason Ertel (github.com/jertel).
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
Expand All @@ -236,7 +254,9 @@ func TestPillarMonitor(tester *testing.T) {
# This file is generated by Security Onion and contains a list of license-enabled features.
features:
- fips
- stig
- timetracking
`

assert.Equal(tester, expected, string(contents))
Expand Down
3 changes: 3 additions & 0 deletions model/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"
)

const NodeRoleDesktop = "so-desktop"
const NodeStatusUnknown = "unknown"
const NodeStatusOk = "ok"
const NodeStatusFault = "fault"
Expand All @@ -36,6 +37,7 @@ type Node struct {
ConsumptionEps int `json:"consumptionEps"`
FailedEvents int `json:"failedEvents"`
MetricsEnabled bool `json:"metricsEnabled"`
NonCriticalNode bool `json:"nonCriticalNode"`
}

func NewNode(id string) *Node {
Expand Down Expand Up @@ -85,6 +87,7 @@ func (node *Node) updateStatusComponent(currentState string, newState string) st
}

func (node *Node) UpdateOverallStatus(enhancedStatusEnabled bool) bool {
node.NonCriticalNode = node.Role == NodeRoleDesktop
newStatus := NodeStatusUnknown
newStatus = node.updateStatusComponent(newStatus, node.ConnectionStatus)
if enhancedStatusEnabled {
Expand Down
12 changes: 6 additions & 6 deletions server/casehandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,18 +493,18 @@ func (caseHandler *CaseHandler) copyArtifactStream(ctx context.Context, writer h
written, err := io.Copy(writer, content)
if err != nil {
log.WithError(err).WithFields(log.Fields{
"name": artifact.Value,
"artifactId": artifactId,
"artifactName": artifact.Value,
"artifactId": artifactId,
}).Error("Failed to copy artifact stream")

return err
}

log.WithFields(log.Fields{
"name": artifact.Value,
"size": written,
"artifactId": artifactId,
"protected": artifact.Protected,
"artifactName": artifact.Value,
"artifactSize": written,
"artifactId": artifactId,
"artifactProtected": artifact.Protected,
}).Info("Copied artifact stream to response")

return nil
Expand Down
14 changes: 10 additions & 4 deletions server/modules/elastic/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,17 @@ func convertFromElasticResults(store *ElasticEventstore, esJson string, results
for _, failureGeneric := range failures {
failure := failureGeneric.(map[string]interface{})
reason := failure["reason"].(map[string]interface{})
reasonType := reason["type"].(string)
reasonDetails := reason["reason"].(string)
reasonType := ""
if reason["type"] != nil {
reasonType = reason["type"].(string)
}
reasonDetails := "N/A"
if reason["reason"] != nil {
reasonDetails = reason["reason"].(string)
}
log.WithFields(log.Fields{
"type": reasonType,
"reason": reasonDetails,
"reasonType": reasonType,
"reason": reasonDetails,
}).Warn("Shard failure")
err = errors.New("ERROR_QUERY_FAILED_ELASTICSEARCH")
}
Expand Down
Loading

0 comments on commit e0c759d

Please sign in to comment.