Merge pull request #12616 from Security-Onion-Solutions/2.4/dev

2.4.60
This commit is contained in:
Mike Reeves
2024-03-20 10:55:42 -04:00
committed by GitHub
63 changed files with 1514 additions and 231 deletions

190
.github/DISCUSSION_TEMPLATE/2-4.yml vendored Normal file
View File

@@ -0,0 +1,190 @@
body:
- type: markdown
attributes:
value: |
⚠️ This category is solely for conversations related to Security Onion 2.4 ⚠️
If your organization needs more immediate, enterprise grade professional support, with one-on-one virtual meetings and screensharing, contact us via our website: https://securityonion.com/support
- type: dropdown
attributes:
label: Version
description: Which version of Security Onion 2.4.x are you asking about?
options:
-
- 2.4 Pre-release (Beta, Release Candidate)
- 2.4.10
- 2.4.20
- 2.4.30
- 2.4.40
- 2.4.50
- 2.4.60
- 2.4.70
- 2.4.80
- 2.4.90
- 2.4.100
- Other (please provide detail below)
validations:
required: true
- type: dropdown
attributes:
label: Installation Method
description: How did you install Security Onion?
options:
-
- Security Onion ISO image
- Network installation on Red Hat derivative like Oracle, Rocky, Alma, etc.
- Network installation on Ubuntu
- Network installation on Debian
- Other (please provide detail below)
validations:
required: true
- type: dropdown
attributes:
label: Description
description: >
Is this discussion about installation, configuration, upgrading, or other?
options:
-
- installation
- configuration
- upgrading
- other (please provide detail below)
validations:
required: true
- type: dropdown
attributes:
label: Installation Type
description: >
When you installed, did you choose Import, Eval, Standalone, Distributed, or something else?
options:
-
- Import
- Eval
- Standalone
- Distributed
- other (please provide detail below)
validations:
required: true
- type: dropdown
attributes:
label: Location
description: >
Is this deployment in the cloud, on-prem with Internet access, or airgap?
options:
-
- cloud
- on-prem with Internet access
- airgap
- other (please provide detail below)
validations:
required: true
- type: dropdown
attributes:
label: Hardware Specs
description: >
Does your hardware meet or exceed the minimum requirements for your installation type as shown at https://docs.securityonion.net/en/2.4/hardware.html?
options:
-
- Meets minimum requirements
- Exceeds minimum requirements
- Does not meet minimum requirements
- other (please provide detail below)
validations:
required: true
- type: input
attributes:
label: CPU
description: How many CPU cores do you have?
validations:
required: true
- type: input
attributes:
label: RAM
description: How much RAM do you have?
validations:
required: true
- type: input
attributes:
label: Storage for /
description: How much storage do you have for the / partition?
validations:
required: true
- type: input
attributes:
label: Storage for /nsm
description: How much storage do you have for the /nsm partition?
validations:
required: true
- type: dropdown
attributes:
label: Network Traffic Collection
description: >
Are you collecting network traffic from a tap or span port?
options:
-
- tap
- span port
- other (please provide detail below)
validations:
required: true
- type: dropdown
attributes:
label: Network Traffic Speeds
description: >
How much network traffic are you monitoring?
options:
-
- Less than 1Gbps
- 1Gbps to 10Gbps
- more than 10Gbps
validations:
required: true
- type: dropdown
attributes:
label: Status
description: >
Does SOC Grid show all services on all nodes as running OK?
options:
-
- Yes, all services on all nodes are running OK
- No, one or more services are failed (please provide detail below)
validations:
required: true
- type: dropdown
attributes:
label: Salt Status
description: >
Do you get any failures when you run "sudo salt-call state.highstate"?
options:
-
- Yes, there are salt failures (please provide detail below)
- No, there are no failures
validations:
required: true
- type: dropdown
attributes:
label: Logs
description: >
Are there any additional clues in /opt/so/log/?
options:
-
- Yes, there are additional clues in /opt/so/log/ (please provide detail below)
- No, there are no additional clues
validations:
required: true
- type: textarea
attributes:
label: Detail
description: Please read our discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 and then provide detailed information to help us help you.
placeholder: |-
STOP! Before typing, please read our discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 in their entirety!
If your organization needs more immediate, enterprise grade professional support, with one-on-one virtual meetings and screensharing, contact us via our website: https://securityonion.com/support
validations:
required: true
- type: checkboxes
attributes:
label: Guidelines
options:
- label: I have read the discussion guidelines at https://github.com/Security-Onion-Solutions/securityonion/discussions/1720 and assert that I have followed the guidelines.
required: true

42
.github/workflows/lock-threads.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: 'Lock Threads'
on:
schedule:
- cron: '50 1 * * *'
workflow_dispatch:
permissions:
issues: write
pull-requests: write
discussions: write
concurrency:
group: lock-threads
jobs:
close-threads:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v5
with:
days-before-issue-stale: -1
days-before-issue-close: 60
stale-issue-message: "This issue is stale because it has been inactive for an extended period. Stale issues convey that the issue, while important to someone, is not critical enough for the author, or other community members to work on, sponsor, or otherwise shepherd the issue through to a resolution."
close-issue-message: "This issue was closed because it has been stale for an extended period. It will be automatically locked in 30 days, after which no further commenting will be available."
days-before-pr-stale: 45
days-before-pr-close: 60
stale-pr-message: "This PR is stale because it has been inactive for an extended period. The longer a PR remains stale the more out of date with the main branch it becomes."
close-pr-message: "This PR was closed because it has been stale for an extended period. It will be automatically locked in 30 days. If there is still a commitment to finishing this PR re-open it before it is locked."
lock-threads:
runs-on: ubuntu-latest
steps:
- uses: jertel/lock-threads@main
with:
include-discussion-currently-open: true
discussion-inactive-days: 90
issue-inactive-days: 30
pr-inactive-days: 30

View File

@@ -1,17 +1,17 @@
### 2.4.50-20240220 ISO image released on 2024/02/20 ### 2.4.60-20240320 ISO image released on 2024/03/20
### Download and Verify ### Download and Verify
2.4.50-20240220 ISO image: 2.4.60-20240320 ISO image:
https://download.securityonion.net/file/securityonion/securityonion-2.4.50-20240220.iso https://download.securityonion.net/file/securityonion/securityonion-2.4.60-20240320.iso
MD5: BCA6476EF1BF79773D8EFB11700FDE8E MD5: 178DD42D06B2F32F3870E0C27219821E
SHA1: 9FF0A304AA368BCD2EF2BE89AD47E65650241927 SHA1: 73EDCD50817A7F6003FE405CF1808A30D034F89D
SHA256: 49D7695EFFF6F3C4840079BF564F3191B585639816ADE98672A38017F25E9570 SHA256: DD334B8D7088A7B78160C253B680D645E25984BA5CCAB5CC5C327CA72137FC06
Signature for ISO image: Signature for ISO image:
https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.50-20240220.iso.sig https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.60-20240320.iso.sig
Signing key: Signing key:
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.4/main/KEYS
@@ -25,22 +25,22 @@ wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/2.
Download the signature file for the ISO: Download the signature file for the ISO:
``` ```
wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.50-20240220.iso.sig wget https://github.com/Security-Onion-Solutions/securityonion/raw/2.4/main/sigs/securityonion-2.4.60-20240320.iso.sig
``` ```
Download the ISO image: Download the ISO image:
``` ```
wget https://download.securityonion.net/file/securityonion/securityonion-2.4.50-20240220.iso wget https://download.securityonion.net/file/securityonion/securityonion-2.4.60-20240320.iso
``` ```
Verify the downloaded ISO image using the signature file: Verify the downloaded ISO image using the signature file:
``` ```
gpg --verify securityonion-2.4.50-20240220.iso.sig securityonion-2.4.50-20240220.iso gpg --verify securityonion-2.4.60-20240320.iso.sig securityonion-2.4.60-20240320.iso
``` ```
The output should show "Good signature" and the Primary key fingerprint should match what's shown below: The output should show "Good signature" and the Primary key fingerprint should match what's shown below:
``` ```
gpg: Signature made Fri 16 Feb 2024 11:36:25 AM EST using RSA key ID FE507013 gpg: Signature made Tue 19 Mar 2024 03:17:58 PM EDT using RSA key ID FE507013
gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>" gpg: Good signature from "Security Onion Solutions, LLC <info@securityonionsolutions.com>"
gpg: WARNING: This key is not certified with a trusted signature! gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner. gpg: There is no indication that the signature belongs to the owner.

View File

@@ -1 +1 @@
2.4.50 2.4.60

View File

@@ -1,7 +1,10 @@
{% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %} {% from 'vars/globals.map.jinja' import GLOBALS %}
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %} {% if GLOBALS.pcap_engine == "TRANSITION" %}
{% import 'bpf/macros.jinja' as MACROS %} {% set PCAPBPF = ["ip and host 255.255.255.1 and port 1"] %}
{% else %}
{{ MACROS.remove_comments(BPFMERGED, 'pcap') }} {% import_yaml 'bpf/defaults.yaml' as BPFDEFAULTS %}
{% set BPFMERGED = salt['pillar.get']('bpf', BPFDEFAULTS.bpf, merge=True) %}
{% set PCAPBPF = BPFMERGED.pcap %} {% import 'bpf/macros.jinja' as MACROS %}
{{ MACROS.remove_comments(BPFMERGED, 'pcap') }}
{% set PCAPBPF = BPFMERGED.pcap %}
{% endif %}

View File

@@ -47,12 +47,16 @@ def check_for_fps():
fps = 1 fps = 1
except FileNotFoundError: except FileNotFoundError:
fn = '/proc/sys/crypto/' + feat_full + '_enabled' fn = '/proc/sys/crypto/' + feat_full + '_enabled'
with open(fn, 'r') as f: try:
contents = f.read() with open(fn, 'r') as f:
if '1' in contents: contents = f.read()
fps = 1 if '1' in contents:
fps = 1
except:
# Unknown, so assume 0
fps = 0
with open('/opt/so/log/sostatus/lks_enabled', 'w') as f: with open('/opt/so/log/sostatus/fps_enabled', 'w') as f:
f.write(str(fps)) f.write(str(fps))
def check_for_lks(): def check_for_lks():
@@ -76,7 +80,7 @@ def check_for_lks():
lks = 1 lks = 1
if lks: if lks:
break break
with open('/opt/so/log/sostatus/fps_enabled', 'w') as f: with open('/opt/so/log/sostatus/lks_enabled', 'w') as f:
f.write(str(lks)) f.write(str(lks))
def fail(msg): def fail(msg):

View File

@@ -65,6 +65,7 @@ elasticfleet:
- http_endpoint - http_endpoint
- httpjson - httpjson
- iis - iis
- journald
- juniper - juniper
- juniper_srx - juniper_srx
- kafka_log - kafka_log

View File

@@ -46,7 +46,7 @@ do
done done
printf "\n### Stripping out unused components" printf "\n### Stripping out unused components"
find /nsm/elastic-agent-workspace/elastic-agent-*/data/elastic-agent-*/components -maxdepth 1 -regex '.*fleet.*\|.*packet.*\|.*apm.*\|.*audit.*\|.*heart.*\|.*cloud.*' -delete find /nsm/elastic-agent-workspace/elastic-agent-*/data/elastic-agent-*/components -maxdepth 1 -regex '.*fleet.*\|.*packet.*\|.*apm.*\|.*heart.*\|.*cloud.*' -delete
printf "\n### Tarring everything up again" printf "\n### Tarring everything up again"
for OS in "${OSARCH[@]}" for OS in "${OSARCH[@]}"

View File

@@ -198,6 +198,35 @@ elasticsearch:
sort: sort:
field: '@timestamp' field: '@timestamp'
order: desc order: desc
so-detection:
index_sorting: false
index_template:
composed_of:
- detection-mappings
- detection-settings
index_patterns:
- so-detection*
priority: 500
template:
mappings:
date_detection: false
dynamic_templates:
- strings_as_keyword:
mapping:
ignore_above: 1024
type: keyword
match_mapping_type: string
settings:
index:
mapping:
total_fields:
limit: 1500
number_of_replicas: 0
number_of_shards: 1
refresh_interval: 30s
sort:
field: '@timestamp'
order: desc
so-common: so-common:
close: 30 close: 30
delete: 365 delete: 365
@@ -1078,6 +1107,50 @@ elasticsearch:
set_priority: set_priority:
priority: 50 priority: 50
min_age: 30d min_age: 30d
so-logs-aws_x_cloudfront_logs:
index_sorting: False
index_template:
index_patterns:
- "logs-aws.cloudfront_logs-*"
template:
settings:
index:
lifecycle:
name: so-logs-aws.cloudfront_logs-logs
number_of_replicas: 0
composed_of:
- "logs-aws.cloudfront_logs@package"
- "logs-aws.cloudfront_logs@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-aws_x_cloudtrail: so-logs-aws_x_cloudtrail:
index_sorting: false index_sorting: false
index_template: index_template:
@@ -1298,6 +1371,94 @@ elasticsearch:
set_priority: set_priority:
priority: 50 priority: 50
min_age: 30d min_age: 30d
so-logs-aws_x_guardduty:
index_sorting: False
index_template:
index_patterns:
- "logs-aws.guardduty-*"
template:
settings:
index:
lifecycle:
name: so-logs-aws.guardduty-logs
number_of_replicas: 0
composed_of:
- "logs-aws.guardduty@package"
- "logs-aws.guardduty@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-aws_x_inspector:
index_sorting: False
index_template:
index_patterns:
- "logs-aws.inspector-*"
template:
settings:
index:
lifecycle:
name: so-logs-aws.inspector-logs
number_of_replicas: 0
composed_of:
- "logs-aws.inspector@package"
- "logs-aws.inspector@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-aws_x_route53_public_logs: so-logs-aws_x_route53_public_logs:
index_sorting: false index_sorting: false
index_template: index_template:
@@ -1430,6 +1591,94 @@ elasticsearch:
set_priority: set_priority:
priority: 50 priority: 50
min_age: 30d min_age: 30d
so-logs-aws_x_securityhub_findings:
index_sorting: False
index_template:
index_patterns:
- "logs-aws.securityhub_findings-*"
template:
settings:
index:
lifecycle:
name: so-logs-aws.securityhub_findings-logs
number_of_replicas: 0
composed_of:
- "logs-aws.securityhub_findings@package"
- "logs-aws.securityhub_findings@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-aws_x_securityhub_insights:
index_sorting: False
index_template:
index_patterns:
- "logs-aws.securityhub_insights-*"
template:
settings:
index:
lifecycle:
name: so-logs-aws.securityhub_insights-logs
number_of_replicas: 0
composed_of:
- "logs-aws.securityhub_insights@package"
- "logs-aws.securityhub_insights@custom"
- "so-fleet_globals-1"
- "so-fleet_agent_id_verification-1"
priority: 501
data_stream:
hidden: false
allow_custom_routing: false
policy:
phases:
cold:
actions:
set_priority:
priority: 0
min_age: 30d
delete:
actions:
delete: {}
min_age: 365d
hot:
actions:
rollover:
max_age: 30d
max_primary_shard_size: 50gb
set_priority:
priority: 100
min_age: 0ms
warm:
actions:
set_priority:
priority: 50
min_age: 30d
so-logs-aws_x_vpcflow: so-logs-aws_x_vpcflow:
index_sorting: false index_sorting: false
index_template: index_template:
@@ -3897,7 +4146,7 @@ elasticsearch:
allow_custom_routing: false allow_custom_routing: false
hidden: false hidden: false
index_patterns: index_patterns:
- logs-endpoint.diagnostic.collection-* - .logs-endpoint.diagnostic.collection-*
priority: 501 priority: 501
template: template:
settings: settings:
@@ -8990,7 +9239,7 @@ elasticsearch:
actions: actions:
set_priority: set_priority:
priority: 50 priority: 50
min_age: 30d min_age: 30d
so-logs-ti_otx_x_threat: so-logs-ti_otx_x_threat:
index_sorting: false index_sorting: false
index_template: index_template:
@@ -10568,7 +10817,7 @@ elasticsearch:
hot: hot:
actions: actions:
rollover: rollover:
max_age: 30d max_age: 1d
max_primary_shard_size: 50gb max_primary_shard_size: 50gb
set_priority: set_priority:
priority: 100 priority: 100

View File

@@ -95,6 +95,7 @@ elasticsearch:
description: The order to sort by. Must set index_sorting to True. description: The order to sort by. Must set index_sorting to True.
global: True global: True
helpLink: elasticsearch.html helpLink: elasticsearch.html
policy:
phases: phases:
hot: hot:
max_age: max_age:

View File

@@ -0,0 +1,22 @@
{
"template": {
"mappings": {
"properties": {
"error": {
"properties": {
"message": {
"type": "match_only_text"
}
}
}
}
}
},
"_meta": {
"package": {
"name": "system"
},
"managed_by": "fleet",
"managed": true
}
}

View File

@@ -0,0 +1,138 @@
{
"template": {
"mappings": {
"properties": {
"so_audit_doc_id": {
"ignore_above": 1024,
"type": "keyword"
},
"@timestamp": {
"type": "date"
},
"so_kind": {
"ignore_above": 1024,
"type": "keyword"
},
"so_operation": {
"ignore_above": 1024,
"type": "keyword"
},
"so_detection": {
"properties": {
"publicId": {
"type": "text"
},
"title": {
"type": "text"
},
"severity": {
"ignore_above": 1024,
"type": "keyword"
},
"author": {
"type": "text"
},
"description": {
"type": "text"
},
"content": {
"type": "text"
},
"isEnabled": {
"type": "boolean"
},
"isReporting": {
"type": "boolean"
},
"isCommunity": {
"type": "boolean"
},
"tags": {
"type": "text"
},
"ruleset": {
"ignore_above": 1024,
"type": "keyword"
},
"engine": {
"ignore_above": 1024,
"type": "keyword"
},
"language": {
"ignore_above": 1024,
"type": "keyword"
},
"license": {
"ignore_above": 1024,
"type": "keyword"
},
"overrides": {
"properties": {
"type": {
"ignore_above": 1024,
"type": "keyword"
},
"isEnabled": {
"type": "boolean"
},
"createdAt": {
"type": "date"
},
"updatedAt": {
"type": "date"
},
"regex": {
"type": "text"
},
"value": {
"type": "text"
},
"thresholdType": {
"ignore_above": 1024,
"type": "keyword"
},
"track": {
"ignore_above": 1024,
"type": "keyword"
},
"ip": {
"type": "text"
},
"count": {
"type": "long"
},
"seconds": {
"type": "long"
},
"customFilter": {
"type": "text"
}
}
}
}
},
"so_detectioncomment": {
"properties": {
"createTime": {
"type": "date"
},
"detectionId": {
"ignore_above": 1024,
"type": "keyword"
},
"value": {
"type": "text"
},
"userId": {
"ignore_above": 1024,
"type": "keyword"
}
}
}
}
}
},
"_meta": {
"ecs_version": "1.12.2"
}
}

View File

@@ -0,0 +1,7 @@
{
"template": {},
"version": 1,
"_meta": {
"description": "default settings for common Security Onion Detections indices"
}
}

View File

@@ -1295,6 +1295,10 @@ firewall:
portgroups: portgroups:
- redis - redis
- beats_5644 - beats_5644
managersearch:
portgroups:
- redis
- beats_5644
self: self:
portgroups: portgroups:
- redis - redis

View File

@@ -0,0 +1,2 @@
global:
pcapengine: STENO

2
salt/global/map.jinja Normal file
View File

@@ -0,0 +1,2 @@
{% import_yaml 'global/defaults.yaml' as GLOBALDEFAULTS %}
{% set GLOBALMERGED = salt['pillar.get']('global', GLOBALDEFAULTS.global, merge=True) %}

View File

@@ -10,10 +10,15 @@ global:
regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$ regex: ^(([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?)?$
regexFailureMessage: You must enter a valid IP address or CIDR. regexFailureMessage: You must enter a valid IP address or CIDR.
mdengine: mdengine:
description: What engine to use for meta data generation. Options are ZEEK and SURICATA. description: Which engine to use for meta data generation. Options are ZEEK and SURICATA.
regex: ^(ZEEK|SURICATA)$ regex: ^(ZEEK|SURICATA)$
regexFailureMessage: You must enter either ZEEK or SURICATA. regexFailureMessage: You must enter either ZEEK or SURICATA.
global: True global: True
pcapengine:
description: Which engine to use for generating pcap. Options are STENO, SURICATA or TRANSITION.
regex: ^(STENO|SURICATA|TRANSITION)$
regexFailureMessage: You must enter either STENO, SURICATA or TRANSITION.
global: True
ids: ids:
description: Which IDS engine to use. Currently only Suricata is supported. description: Which IDS engine to use. Currently only Suricata is supported.
global: True global: True

View File

@@ -6,9 +6,10 @@ idstools:
description: Enter your registration code or oinkcode for paid NIDS rulesets. description: Enter your registration code or oinkcode for paid NIDS rulesets.
title: Registration Code title: Registration Code
global: True global: True
forcedType: string
helpLink: rules.html helpLink: rules.html
ruleset: ruleset:
description: Defines the ruleset you want to run. Options are ETOPEN or ETPRO. description: 'Defines the ruleset you want to run. Options are ETOPEN or ETPRO. WARNING! Changing the ruleset will remove all existing Suricata rules of the previous ruleset and their associated overrides. This removal cannot be undone.'
global: True global: True
regex: ETPRO\b|ETOPEN\b regex: ETPRO\b|ETOPEN\b
helpLink: rules.html helpLink: rules.html

View File

@@ -0,0 +1,2 @@
https://repo.securityonion.net/file/so-repo/prod/2.4/oracle/9
https://repo-alt.securityonion.net/prod/2.4/oracle/9

View File

@@ -0,0 +1,13 @@
[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=True
best=True
skip_if_unavailable=False
cachedir=/opt/so/conf/reposync/cache
keepcache=0
[securityonionsync]
name=Security Onion Repo repo
mirrorlist=file:///opt/so/conf/reposync/mirror.txt
enabled=1
gpgcheck=1

View File

@@ -1,5 +1,5 @@
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at # or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the # https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0. # Elastic License 2.0.
@@ -61,7 +61,7 @@ manager_sbin:
- user: 939 - user: 939
- group: 939 - group: 939
- file_mode: 755 - file_mode: 755
- exclude_pat: - exclude_pat:
- "*_test.py" - "*_test.py"
yara_update_scripts: yara_update_scripts:
@@ -75,6 +75,20 @@ yara_update_scripts:
- defaults: - defaults:
EXCLUDEDRULES: {{ STRELKAMERGED.rules.excluded }} EXCLUDEDRULES: {{ STRELKAMERGED.rules.excluded }}
so-repo-file:
file.managed:
- name: /opt/so/conf/reposync/repodownload.conf
- source: salt://manager/files/repodownload.conf
- user: socore
- group: socore
so-repo-mirrorlist:
file.managed:
- name: /opt/so/conf/reposync/mirror.txt
- source: salt://manager/files/mirror.txt
- user: socore
- group: socore
so-repo-sync: so-repo-sync:
{% if MANAGERMERGED.reposync.enabled %} {% if MANAGERMERGED.reposync.enabled %}
cron.present: cron.present:
@@ -103,55 +117,51 @@ rules_dir:
- group: socore - group: socore
- makedirs: True - makedirs: True
{% if STRELKAMERGED.rules.enabled %} {% if STRELKAMERGED.rules.enabled %}
strelkarepos: strelkarepos:
file.managed: file.managed:
- name: /opt/so/conf/strelka/repos.txt - name: /opt/so/conf/strelka/repos.txt
- source: salt://strelka/rules/repos.txt.jinja - source: salt://strelka/rules/repos.txt.jinja
- template: jinja - template: jinja
- defaults: - defaults:
STRELKAREPOS: {{ STRELKAMERGED.rules.repos }} STRELKAREPOS: {{ STRELKAMERGED.rules.repos }}
- makedirs: True - makedirs: True
strelka-yara-update: strelka-yara-update:
{% if MANAGERMERGED.reposync.enabled and not GLOBALS.airgap %} {% if MANAGERMERGED.reposync.enabled and not GLOBALS.airgap %}
cron.present: cron.present:
{% else %} {% else %}
cron.absent: cron.absent:
{% endif %} {% endif %}
- user: socore - user: socore
- name: '/usr/sbin/so-yara-update >> /opt/so/log/yarasync/yara-update.log 2>&1' - name: '/usr/sbin/so-yara-update >> /opt/so/log/yarasync/yara-update.log 2>&1'
- identifier: strelka-yara-update - identifier: strelka-yara-update
- hour: '7' - hour: '7'
- minute: '1' - minute: '1'
strelka-yara-download: strelka-yara-download:
{% if MANAGERMERGED.reposync.enabled and not GLOBALS.airgap %} {% if MANAGERMERGED.reposync.enabled and not GLOBALS.airgap %}
cron.present: cron.present:
{% else %} {% else %}
cron.absent: cron.absent:
{% endif %} {% endif %}
- user: socore - user: socore
- name: '/usr/sbin/so-yara-download >> /opt/so/log/yarasync/yara-download.log 2>&1' - name: '/usr/sbin/so-yara-download >> /opt/so/log/yarasync/yara-download.log 2>&1'
- identifier: strelka-yara-download - identifier: strelka-yara-download
- hour: '7' - hour: '7'
- minute: '1' - minute: '1'
{% if not GLOBALS.airgap %}
{% if not GLOBALS.airgap %}
update_yara_rules: update_yara_rules:
cmd.run: cmd.run:
- name: /usr/sbin/so-yara-update - name: /usr/sbin/so-yara-update
- onchanges: - onchanges:
- file: yara_update_scripts - file: yara_update_scripts
download_yara_rules: download_yara_rules:
cmd.run: cmd.run:
- name: /usr/sbin/so-yara-download - name: /usr/sbin/so-yara-download
- onchanges: - onchanges:
- file: yara_update_scripts - file: yara_update_scripts
{% endif %} {% endif %}
{% endif %} {% endif %}
{% else %} {% else %}
{{sls}}_state_not_allowed: {{sls}}_state_not_allowed:

View File

@@ -79,6 +79,32 @@ function getinstallinfo() {
source <(echo $INSTALLVARS) source <(echo $INSTALLVARS)
} }
function pcapspace() {
if [[ "$OPERATION" == "setup" ]]; then
# Use 25% for PCAP
PCAP_PERCENTAGE=1
DFREEPERCENT=21
local SPACESIZE=$(df -k /nsm | tail -1 | awk '{print $2}' | tr -d \n)
else
local NSMSIZE=$(salt "$MINION_ID" disk.usage --out=json | jq -r '.[]."/nsm"."1K-blocks" ')
local ROOTSIZE=$(salt "$MINION_ID" disk.usage --out=json | jq -r '.[]."/"."1K-blocks" ')
if [[ "$NSMSIZE" == "null" ]]; then
# Looks like there is no dedicated nsm partition. Using root
local SPACESIZE=$ROOTSIZE
else
local SPACESIZE=$NSMSIZE
fi
fi
local s=$(( $SPACESIZE / 1000000 ))
local s1=$(( $s / 4 * $PCAP_PERCENTAGE ))
MAX_PCAP_SPACE=$s1
}
function testMinion() { function testMinion() {
# Always run on the host, since this is going to be the manager of a distributed grid, or an eval/standalone. # Always run on the host, since this is going to be the manager of a distributed grid, or an eval/standalone.
# Distributed managers must run this in order for the sensor nodes to have access to the so-tcpreplay image. # Distributed managers must run this in order for the sensor nodes to have access to the so-tcpreplay image.
@@ -244,6 +270,10 @@ function add_sensor_to_minion() {
echo " lb_procs: '$CORECOUNT'" >> $PILLARFILE echo " lb_procs: '$CORECOUNT'" >> $PILLARFILE
echo "suricata:" >> $PILLARFILE echo "suricata:" >> $PILLARFILE
echo " enabled: True " >> $PILLARFILE echo " enabled: True " >> $PILLARFILE
if [[ $is_pcaplimit ]]; then
echo " pcap:" >> $PILLARFILE
echo " maxsize: $MAX_PCAP_SPACE" >> $PILLARFILE
fi
echo " config:" >> $PILLARFILE echo " config:" >> $PILLARFILE
echo " af-packet:" >> $PILLARFILE echo " af-packet:" >> $PILLARFILE
echo " threads: '$CORECOUNT'" >> $PILLARFILE echo " threads: '$CORECOUNT'" >> $PILLARFILE
@@ -251,7 +281,7 @@ function add_sensor_to_minion() {
echo " enabled: True" >> $PILLARFILE echo " enabled: True" >> $PILLARFILE
if [[ $is_pcaplimit ]]; then if [[ $is_pcaplimit ]]; then
echo " config:" >> $PILLARFILE echo " config:" >> $PILLARFILE
echo " diskfreepercentage: 60" >> $PILLARFILE echo " diskfreepercentage: $DFREEPERCENT" >> $PILLARFILE
fi fi
echo " " >> $PILLARFILE echo " " >> $PILLARFILE
} }
@@ -422,6 +452,7 @@ function updateMine() {
function createEVAL() { function createEVAL() {
is_pcaplimit=true is_pcaplimit=true
pcapspace
add_elasticsearch_to_minion add_elasticsearch_to_minion
add_sensor_to_minion add_sensor_to_minion
add_strelka_to_minion add_strelka_to_minion
@@ -442,6 +473,7 @@ function createEVAL() {
function createSTANDALONE() { function createSTANDALONE() {
is_pcaplimit=true is_pcaplimit=true
pcapspace
add_elasticsearch_to_minion add_elasticsearch_to_minion
add_logstash_to_minion add_logstash_to_minion
add_sensor_to_minion add_sensor_to_minion
@@ -531,6 +563,9 @@ function createIDH() {
function createHEAVYNODE() { function createHEAVYNODE() {
is_pcaplimit=true is_pcaplimit=true
PCAP_PERCENTAGE=1
DFREEPERCENT=21
pcapspace
add_elasticsearch_to_minion add_elasticsearch_to_minion
add_elastic_agent_to_minion add_elastic_agent_to_minion
add_logstash_to_minion add_logstash_to_minion
@@ -541,6 +576,10 @@ function createHEAVYNODE() {
} }
function createSENSOR() { function createSENSOR() {
is_pcaplimit=true
DFREEPERCENT=10
PCAP_PERCENTAGE=3
pcapspace
add_sensor_to_minion add_sensor_to_minion
add_strelka_to_minion add_strelka_to_minion
add_telegraf_to_minion add_telegraf_to_minion

View File

@@ -47,7 +47,7 @@ got_root(){
got_root got_root
if [ $# -ne 1 ] ; then if [ $# -ne 1 ] ; then
BRANCH=master BRANCH=2.4/main
else else
BRANCH=$1 BRANCH=$1
fi fi

View File

@@ -247,67 +247,6 @@ check_sudoers() {
fi fi
} }
check_log_size_limit() {
local num_minion_pillars
num_minion_pillars=$(find /opt/so/saltstack/local/pillar/minions/ -type f | wc -l)
if [[ $num_minion_pillars -gt 1 ]]; then
if find /opt/so/saltstack/local/pillar/minions/ -type f | grep -q "_heavynode"; then
lsl_msg='distributed'
fi
else
local minion_id
minion_id=$(lookup_salt_value "id" "" "grains" "" "local")
local minion_arr
IFS='_' read -ra minion_arr <<< "$minion_id"
local node_type="${minion_arr[0]}"
local current_limit
# since it is possible for the salt-master service to be stopped when this is run, we need to check the pillar values locally
# we need to combine default local and default pillars before doing this so we can define --pillar-root in salt-call
local epoch_date=$(date +%s%N)
mkdir -vp /opt/so/saltstack/soup_tmp_${epoch_date}/
cp -r /opt/so/saltstack/default/pillar/ /opt/so/saltstack/soup_tmp_${epoch_date}/
# use \cp here to overwrite any pillar files from default with those in local for the tmp directory
\cp -r /opt/so/saltstack/local/pillar/ /opt/so/saltstack/soup_tmp_${epoch_date}/
current_limit=$(salt-call pillar.get elasticsearch:log_size_limit --local --pillar-root=/opt/so/saltstack/soup_tmp_${epoch_date}/pillar --out=newline_values_only)
rm -rf /opt/so/saltstack/soup_tmp_${epoch_date}/
local percent
case $node_type in
'standalone' | 'eval')
percent=50
;;
*)
percent=80
;;
esac
local disk_dir="/"
if [ -d /nsm ]; then
disk_dir="/nsm"
fi
local disk_size_1k
disk_size_1k=$(df $disk_dir | grep -v "^Filesystem" | awk '{print $2}')
local ratio="1048576"
local disk_size_gb
disk_size_gb=$( echo "$disk_size_1k" "$ratio" | awk '{print($1/$2)}' )
local new_limit
new_limit=$( echo "$disk_size_gb" "$percent" | awk '{printf("%.0f", $1 * ($2/100))}')
if [[ $current_limit != "$new_limit" ]]; then
lsl_msg='single-node'
lsl_details=( "$current_limit" "$new_limit" "$minion_id" )
fi
fi
}
check_os_updates() { check_os_updates() {
# Check to see if there are OS updates # Check to see if there are OS updates
echo "Checking for OS updates." echo "Checking for OS updates."
@@ -417,6 +356,7 @@ preupgrade_changes() {
[[ "$INSTALLEDVERSION" == 2.4.20 ]] && up_to_2.4.30 [[ "$INSTALLEDVERSION" == 2.4.20 ]] && up_to_2.4.30
[[ "$INSTALLEDVERSION" == 2.4.30 ]] && up_to_2.4.40 [[ "$INSTALLEDVERSION" == 2.4.30 ]] && up_to_2.4.40
[[ "$INSTALLEDVERSION" == 2.4.40 ]] && up_to_2.4.50 [[ "$INSTALLEDVERSION" == 2.4.40 ]] && up_to_2.4.50
[[ "$INSTALLEDVERSION" == 2.4.50 ]] && up_to_2.4.60
true true
} }
@@ -432,6 +372,7 @@ postupgrade_changes() {
[[ "$POSTVERSION" == 2.4.20 ]] && post_to_2.4.30 [[ "$POSTVERSION" == 2.4.20 ]] && post_to_2.4.30
[[ "$POSTVERSION" == 2.4.30 ]] && post_to_2.4.40 [[ "$POSTVERSION" == 2.4.30 ]] && post_to_2.4.40
[[ "$POSTVERSION" == 2.4.40 ]] && post_to_2.4.50 [[ "$POSTVERSION" == 2.4.40 ]] && post_to_2.4.50
[[ "$POSTVERSION" == 2.4.50 ]] && post_to_2.4.60
true true
} }
@@ -488,6 +429,12 @@ post_to_2.4.50() {
POSTVERSION=2.4.50 POSTVERSION=2.4.50
} }
post_to_2.4.60() {
echo "Regenerating Elastic Agent Installers..."
so-elastic-agent-gen-installers
POSTVERSION=2.4.60
}
repo_sync() { repo_sync() {
echo "Sync the local repo." echo "Sync the local repo."
su socore -c '/usr/sbin/so-repo-sync' || fail "Unable to complete so-repo-sync." su socore -c '/usr/sbin/so-repo-sync' || fail "Unable to complete so-repo-sync."
@@ -591,6 +538,8 @@ up_to_2.4.40() {
up_to_2.4.50() { up_to_2.4.50() {
echo "Creating additional pillars.." echo "Creating additional pillars.."
mkdir -p /opt/so/saltstack/local/pillar/stig/ mkdir -p /opt/so/saltstack/local/pillar/stig/
mkdir -p /opt/so/saltstack/local/salt/stig/
chown socore:socore /opt/so/saltstack/local/salt/stig/
touch /opt/so/saltstack/local/pillar/stig/adv_stig.sls touch /opt/so/saltstack/local/pillar/stig/adv_stig.sls
touch /opt/so/saltstack/local/pillar/stig/soc_stig.sls touch /opt/so/saltstack/local/pillar/stig/soc_stig.sls
@@ -617,6 +566,14 @@ up_to_2.4.50() {
INSTALLEDVERSION=2.4.50 INSTALLEDVERSION=2.4.50
} }
up_to_2.4.60() {
echo "Creating directory to store Suricata classification.config"
mkdir -vp /opt/so/saltstack/local/salt/suricata/classification
chown socore:socore /opt/so/saltstack/local/salt/suricata/classification
INSTALLEDVERSION=2.4.60
}
determine_elastic_agent_upgrade() { determine_elastic_agent_upgrade() {
if [[ $is_airgap -eq 0 ]]; then if [[ $is_airgap -eq 0 ]]; then
update_elastic_agent_airgap update_elastic_agent_airgap
@@ -664,6 +621,10 @@ update_airgap_rules() {
if [ -d /nsm/repo/rules/sigma ]; then if [ -d /nsm/repo/rules/sigma ]; then
rsync -av $UPDATE_DIR/agrules/sigma/* /nsm/repo/rules/sigma/ rsync -av $UPDATE_DIR/agrules/sigma/* /nsm/repo/rules/sigma/
fi fi
# SOC Detections Airgap
rsync -av $UPDATE_DIR/agrules/detect-sigma/* /nsm/rules/detect-sigma/
rsync -av $UPDATE_DIR/agrules/detect-yara/* /nsm/rules/detect-yara/
} }
update_airgap_repo() { update_airgap_repo() {

0
salt/manager/tools/sbin_jinja/so-yara-update Executable file → Normal file
View File

View File

@@ -2,6 +2,12 @@
or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
https://securityonion.net/license; you may not use this file except in compliance with the https://securityonion.net/license; you may not use this file except in compliance with the
Elastic License 2.0. #} Elastic License 2.0. #}
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% import_yaml 'pcap/defaults.yaml' as PCAPDEFAULTS %} {% import_yaml 'pcap/defaults.yaml' as PCAPDEFAULTS %}
{% set PCAPMERGED = salt['pillar.get']('pcap', PCAPDEFAULTS.pcap, merge=True) %} {% set PCAPMERGED = salt['pillar.get']('pcap', PCAPDEFAULTS.pcap, merge=True) %}
{# disable stenographer if the pcap engine is set to SURICATA #}
{% if GLOBALS.pcap_engine == "SURICATA" %}
{% do PCAPMERGED.update({'enabled': False}) %}
{% endif %}

View File

@@ -72,13 +72,6 @@ stenoca:
- user: 941 - user: 941
- group: 939 - group: 939
pcapdir:
file.directory:
- name: /nsm/pcap
- user: 941
- group: 941
- makedirs: True
pcaptmpdir: pcaptmpdir:
file.directory: file.directory:
- name: /nsm/pcaptmp - name: /nsm/pcaptmp

View File

@@ -15,3 +15,12 @@ include:
{% else %} {% else %}
- pcap.disabled - pcap.disabled
{% endif %} {% endif %}
# This directory needs to exist regardless of whether STENO is enabled or not, in order for
# Sensoroni to be able to look at old steno PCAP data
pcapdir:
file.directory:
- name: /nsm/pcap
- user: 941
- group: 941
- makedirs: True

View File

@@ -4,32 +4,32 @@ pcap:
helpLink: stenographer.html helpLink: stenographer.html
config: config:
maxdirectoryfiles: maxdirectoryfiles:
description: The maximum number of packet/index files to create before deleting old files. description: By default, Stenographer limits the number of files in the pcap directory to 30000 to avoid limitations with the ext3 filesystem. However, if you're using the ext4 or xfs filesystems, then it is safe to increase this value. So if you have a large amount of storage and find that you only have 3 weeks worth of PCAP on disk while still having plenty of free space, then you may want to increase this default setting.
helpLink: stenographer.html helpLink: stenographer.html
diskfreepercentage: diskfreepercentage:
description: The disk space percent to always keep free for PCAP description: Stenographer will purge old PCAP on a regular basis to keep the disk free percentage at this level. If you have a distributed deployment with dedicated forward nodes, then the default value of 10 should be reasonable since Stenographer should be the main consumer of disk space in the /nsm partition. However, if you have systems that run both Stenographer and Elasticsearch at the same time (like eval and standalone installations), then youll want to make sure that this value is no lower than 21 so that you avoid Elasticsearch hitting its watermark setting at 80% disk usage. If you have an older standalone installation, then you may need to manually change this value to 21.
helpLink: stenographer.html helpLink: stenographer.html
blocks: blocks:
description: The number of 1MB packet blocks used by AF_PACKET to store packets in memory, per thread. You shouldn't need to change this. description: The number of 1MB packet blocks used by Stenographer and AF_PACKET to store packets in memory, per thread. You shouldn't need to change this.
advanced: True advanced: True
helpLink: stenographer.html helpLink: stenographer.html
preallocate_file_mb: preallocate_file_mb:
description: File size to pre-allocate for individual PCAP files. You shouldn't need to change this. description: File size to pre-allocate for individual Stenographer PCAP files. You shouldn't need to change this.
advanced: True advanced: True
helpLink: stenographer.html helpLink: stenographer.html
aiops: aiops:
description: The max number of async writes to allow at once. description: The max number of async writes to allow for Stenographer at once.
advanced: True advanced: True
helpLink: stenographer.html helpLink: stenographer.html
pin_to_cpu: pin_to_cpu:
description: Enable CPU pinning for PCAP. description: Enable CPU pinning for Stenographer PCAP.
advanced: True advanced: True
helpLink: stenographer.html helpLink: stenographer.html
cpus_to_pin_to: cpus_to_pin_to:
description: CPU to pin PCAP to. Currently only a single CPU is supported. description: CPU to pin Stenographer PCAP to. Currently only a single CPU is supported.
advanced: True advanced: True
helpLink: stenographer.html helpLink: stenographer.html
disks: disks:
description: List of disks to use for PCAP. This is currently not used. description: List of disks to use for Stenographer PCAP. This is currently not used.
advanced: True advanced: True
helpLink: stenographer.html helpLink: stenographer.html

View File

@@ -10,3 +10,4 @@ salt_bootstrap:
- name: /usr/sbin/bootstrap-salt.sh - name: /usr/sbin/bootstrap-salt.sh
- source: salt://salt/scripts/bootstrap-salt.sh - source: salt://salt/scripts/bootstrap-salt.sh
- mode: 755 - mode: 755
- show_changes: False

View File

@@ -1,58 +1,60 @@
sensoroni: sensoroni:
enabled: False enabled: False
config: config:
analyze: analyze:
enabled: False enabled: False
timeout_ms: 900000 timeout_ms: 900000
parallel_limit: 5 parallel_limit: 5
node_checkin_interval_ms: 10000 node_checkin_interval_ms: 10000
sensoronikey: sensoronikey:
soc_host: soc_host:
analyzers: suripcap:
echotrail: pcapMaxCount: 999999
base_url: https://api.echotrail.io/insights/ analyzers:
api_key: echotrail:
elasticsearch: base_url: https://api.echotrail.io/insights/
base_url: api_key:
auth_user: elasticsearch:
auth_pwd: base_url:
num_results: 10 auth_user:
api_key: auth_pwd:
index: _all num_results: 10
time_delta_minutes: 14400 api_key:
timestamp_field_name: '@timestamp' index: _all
map: {} time_delta_minutes: 14400
cert_path: timestamp_field_name: '@timestamp'
emailrep: map: {}
base_url: https://emailrep.io/ cert_path:
api_key: emailrep:
greynoise: base_url: https://emailrep.io/
base_url: https://api.greynoise.io/ api_key:
api_key: greynoise:
api_version: community base_url: https://api.greynoise.io/
localfile: api_key:
file_path: [] api_version: community
otx: localfile:
base_url: https://otx.alienvault.com/api/v1/ file_path: []
api_key: otx:
pulsedive: base_url: https://otx.alienvault.com/api/v1/
base_url: https://pulsedive.com/api/ api_key:
api_key: pulsedive:
spamhaus: base_url: https://pulsedive.com/api/
lookup_host: zen.spamhaus.org api_key:
nameservers: [] spamhaus:
sublime_platform: lookup_host: zen.spamhaus.org
base_url: https://api.platform.sublimesecurity.com nameservers: []
api_key: sublime_platform:
live_flow: False base_url: https://api.platform.sublimesecurity.com
mailbox_email_address: api_key:
message_source_id: live_flow: False
urlscan: mailbox_email_address:
base_url: https://urlscan.io/api/v1/ message_source_id:
api_key: urlscan:
enabled: False base_url: https://urlscan.io/api/v1/
visibility: public api_key:
timeout: 180 enabled: False
virustotal: visibility: public
base_url: https://www.virustotal.com/api/v3/search?query= timeout: 180
api_key: virustotal:
base_url: https://www.virustotal.com/api/v3/search?query=
api_key:

View File

@@ -23,6 +23,7 @@ so-sensoroni:
- /opt/so/conf/sensoroni/sensoroni.json:/opt/sensoroni/sensoroni.json:ro - /opt/so/conf/sensoroni/sensoroni.json:/opt/sensoroni/sensoroni.json:ro
- /opt/so/conf/sensoroni/analyzers:/opt/sensoroni/analyzers:rw - /opt/so/conf/sensoroni/analyzers:/opt/sensoroni/analyzers:rw
- /opt/so/log/sensoroni:/opt/sensoroni/logs:rw - /opt/so/log/sensoroni:/opt/sensoroni/logs:rw
- /nsm/suripcap/:/nsm/suripcap:rw
{% if DOCKER.containers['so-sensoroni'].custom_bind_mounts %} {% if DOCKER.containers['so-sensoroni'].custom_bind_mounts %}
{% for BIND in DOCKER.containers['so-sensoroni'].custom_bind_mounts %} {% for BIND in DOCKER.containers['so-sensoroni'].custom_bind_mounts %}
- {{ BIND }} - {{ BIND }}

View File

@@ -1,6 +1,5 @@
{%- from 'vars/globals.map.jinja' import GLOBALS %} {% from 'vars/globals.map.jinja' import GLOBALS %}
{%- from 'sensoroni/map.jinja' import SENSORONIMERGED %} {%- from 'sensoroni/map.jinja' import SENSORONIMERGED -%}
{%- from 'pcap/config.map.jinja' import PCAPMERGED %}
{ {
"logFilename": "/opt/sensoroni/logs/sensoroni.log", "logFilename": "/opt/sensoroni/logs/sensoroni.log",
"logLevel":"info", "logLevel":"info",
@@ -23,16 +22,19 @@
"importer": {}, "importer": {},
"statickeyauth": { "statickeyauth": {
"apiKey": "{{ GLOBALS.sensoroni_key }}" "apiKey": "{{ GLOBALS.sensoroni_key }}"
{%- if PCAPMERGED.enabled %} {% if GLOBALS.is_sensor %}
}, },
"stenoquery": { "stenoquery": {
"executablePath": "/opt/sensoroni/scripts/stenoquery.sh", "executablePath": "/opt/sensoroni/scripts/stenoquery.sh",
"pcapInputPath": "/nsm/pcap", "pcapInputPath": "/nsm/pcap",
"pcapOutputPath": "/nsm/pcapout" "pcapOutputPath": "/nsm/pcapout"
} },
{%- else %} "suriquery": {
} "pcapInputPath": "/nsm/suripcap",
"pcapOutputPath": "/nsm/pcapout",
"pcapMaxCount": {{ SENSORONIMERGED.config.suripcap.pcapMaxCount }}
{%- endif %} {%- endif %}
}
} }
} }
} }

View File

@@ -37,6 +37,11 @@ sensoroni:
helpLink: grid.html helpLink: grid.html
global: True global: True
advanced: True advanced: True
suripcap:
pcapMaxCount:
description: The maximum number of PCAP packets to extract from eligible PCAP files, for PCAP jobs. If there are issues fetching excessively large packet streams consider lowering this value to reduce the number of collected packets returned to the user interface.
helpLink: sensoroni.html
advanced: True
analyzers: analyzers:
echotrail: echotrail:
api_key: api_key:

View File

@@ -9,9 +9,16 @@
include: include:
- manager.sync_es_users - manager.sync_es_users
socdirtest:
file.directory:
- name: /opt/so/rules/elastalert/rules
- user: 939
- group: 939
- makedirs: True
socdir: socdir:
file.directory: file.directory:
- name: /opt/so/conf/soc - name: /opt/so/conf/soc/fingerprints
- user: 939 - user: 939
- group: 939 - group: 939
- makedirs: True - makedirs: True
@@ -57,6 +64,22 @@ socmotd:
- mode: 600 - mode: 600
- template: jinja - template: jinja
socsigmafinalpipeline:
file.managed:
- name: /opt/so/conf/soc/sigma_final_pipeline.yaml
- source: salt://soc/files/soc/sigma_final_pipeline.yaml
- user: 939
- group: 939
- mode: 600
socsigmasopipeline:
file.managed:
- name: /opt/so/conf/soc/sigma_so_pipeline.yaml
- source: salt://soc/files/soc/sigma_so_pipeline.yaml
- user: 939
- group: 939
- mode: 600
socbanner: socbanner:
file.managed: file.managed:
- name: /opt/so/conf/soc/banner.md - name: /opt/so/conf/soc/banner.md
@@ -114,6 +137,13 @@ socuploaddir:
- group: 939 - group: 939
- makedirs: True - makedirs: True
socsigmarepo:
file.directory:
- name: /opt/so/rules
- user: 939
- group: 939
- mode: 775
{% else %} {% else %}
{{sls}}_state_not_allowed: {{sls}}_state_not_allowed:

View File

@@ -20,7 +20,7 @@ soc:
- dashboards - dashboards
- name: actionCorrelate - name: actionCorrelate
description: actionCorrelateHelp description: actionCorrelateHelp
icon: fab fa-searchengin icon: fa-magnifying-glass-arrow-right
target: '' target: ''
links: links:
- '/#/hunt?q=("{:log.id.fuid}" OR "{:log.id.uid}" OR "{:network.community_id}") | groupby event.module* | groupby -sankey event.module* event.dataset | groupby event.dataset | groupby source.ip source.port destination.ip destination.port | groupby network.protocol | groupby source_geo.organization_name source.geo.country_name | groupby destination_geo.organization_name destination.geo.country_name | groupby rule.name rule.category event.severity_label | groupby dns.query.name | groupby file.mime_type | groupby http.virtual_host http.uri | groupby notice.note notice.message notice.sub_message | groupby ssl.server_name | groupby source.ip host.hostname user.name event.action event.type process.executable process.pid' - '/#/hunt?q=("{:log.id.fuid}" OR "{:log.id.uid}" OR "{:network.community_id}") | groupby event.module* | groupby -sankey event.module* event.dataset | groupby event.dataset | groupby source.ip source.port destination.ip destination.port | groupby network.protocol | groupby source_geo.organization_name source.geo.country_name | groupby destination_geo.organization_name destination.geo.country_name | groupby rule.name rule.category event.severity_label | groupby dns.query.name | groupby file.mime_type | groupby http.virtual_host http.uri | groupby notice.note notice.message notice.sub_message | groupby ssl.server_name | groupby source.ip host.hostname user.name event.action event.type process.executable process.pid'
@@ -64,13 +64,19 @@ soc:
icon: fa-external-link-alt icon: fa-external-link-alt
target: _blank target: _blank
links: links:
- 'https://{:sublime.url}/messages/{:sublime.message_group_id}' - 'https://{:sublime.url}/messages/{:sublime.message_group_id}'
- name: actionProcessInfo
description: actionProcessInfoHelp
icon: fa-person-running
target: ''
links:
- '/#/hunt?q=(process.entity_id:"{:process.entity_id}") | groupby event.dataset | groupby -sankey event.dataset event.action | groupby event.action | groupby process.name | groupby host.name user.name | groupby source.ip source.port destination.ip destination.port | groupby dns.question.name | groupby dns.answers.data | groupby file.path | groupby registry.path | groupby dll.path'
- name: actionProcessAncestors - name: actionProcessAncestors
description: actionProcessAncestorsHelp description: actionProcessAncestorsHelp
icon: fa-people-roof icon: fa-people-roof
target: '' target: ''
links: links:
- '/#/hunt?q=(process.entity_id:"{:process.entity_id}" OR process.entity_id:"{:process.Ext.ancestry|processAncestors}") | groupby process.parent.name | groupby -sankey process.parent.name process.name | groupby process.name | groupby event.module event.dataset | table soc_timestamp event.dataset host.name user.name process.parent.name process.name process.working_directory' - '/#/hunt?q=(process.entity_id:"{:process.entity_id}" OR process.entity_id:"{:process.Ext.ancestry|processAncestors}") | groupby event.dataset | groupby -sankey event.dataset event.action | groupby event.action | groupby process.parent.name | groupby -sankey process.parent.name process.name | groupby process.name | groupby host.name user.name | groupby source.ip source.port destination.ip destination.port | groupby dns.question.name | groupby dns.answers.data | groupby file.path | groupby registry.path | groupby dll.path'
eventFields: eventFields:
default: default:
- soc_timestamp - soc_timestamp
@@ -995,6 +1001,69 @@ soc:
- tds.header_type - tds.header_type
- log.id.uid - log.id.uid
- event.dataset - event.dataset
':endpoint:events_x_api':
- soc_timestamp
- host.name
- user.name
- process.name
- process.Ext.api.name
- process.thread.Ext.call_stack_final_user_module.path
- event.dataset
':endpoint:events_x_file':
- soc_timestamp
- host.name
- user.name
- process.name
- event.action
- file.path
- event.dataset
':endpoint:events_x_library':
- soc_timestamp
- host.name
- user.name
- process.name
- event.action
- dll.path
- dll.code_signature.status
- dll.code_signature.subject_name
- event.dataset
':endpoint:events_x_network':
- soc_timestamp
- host.name
- user.name
- process.name
- event.action
- source.ip
- source.port
- destination.ip
- destination.port
- network.community_id
- event.dataset
':endpoint:events_x_process':
- soc_timestamp
- host.name
- user.name
- process.parent.name
- process.name
- event.action
- process.working_directory
- event.dataset
':endpoint:events_x_registry':
- soc_timestamp
- host.name
- user.name
- process.name
- event.action
- registry.path
- event.dataset
':endpoint:events_x_security':
- soc_timestamp
- host.name
- user.name
- process.executable
- event.action
- event.outcome
- event.dataset
server: server:
bindAddress: 0.0.0.0:9822 bindAddress: 0.0.0.0:9822
baseUrl: / baseUrl: /
@@ -1008,6 +1077,16 @@ soc:
jobDir: jobs jobDir: jobs
kratos: kratos:
hostUrl: hostUrl:
elastalertengine:
allowRegex: ''
autoUpdateEnabled: false
communityRulesImportFrequencySeconds: 86400
denyRegex: ''
elastAlertRulesFolder: /opt/sensoroni/elastalert
rulesFingerprintFile: /opt/sensoroni/fingerprints/sigma.fingerprint
sigmaRulePackages:
- core
- emerging_threats_addon
elastic: elastic:
hostUrl: hostUrl:
remoteHostUrls: [] remoteHostUrls: []
@@ -1026,6 +1105,7 @@ soc:
esSearchOffsetMs: 1800000 esSearchOffsetMs: 1800000
maxLogLength: 1024 maxLogLength: 1024
asyncThreshold: 10 asyncThreshold: 10
lookupTunnelParent: true
influxdb: influxdb:
hostUrl: hostUrl:
token: token:
@@ -1049,6 +1129,21 @@ soc:
- rbac/custom_roles - rbac/custom_roles
userFiles: userFiles:
- rbac/users_roles - rbac/users_roles
strelkaengine:
allowRegex: ''
autoUpdateEnabled: false
compileYaraPythonScriptPath: /opt/so/conf/strelka/compile_yara.py
denyRegex: '.*'
reposFolder: /opt/sensoroni/yara/repos
rulesRepos:
- repo: https://github.com/Security-Onion-Solutions/securityonion-yara
license: DRL
yaraRulesFolder: /opt/sensoroni/yara/rules
suricataengine:
allowRegex: ''
communityRulesFile: /nsm/rules/suricata/emerging-all.rules
denyRegex: '.*'
rulesFingerprintFile: /opt/sensoroni/fingerprints/emerging-all.fingerprint
client: client:
enableReverseLookup: false enableReverseLookup: false
docsUrl: /docs/ docsUrl: /docs/
@@ -1059,6 +1154,7 @@ soc:
tipTimeoutMs: 6000 tipTimeoutMs: 6000
cacheExpirationMs: 300000 cacheExpirationMs: 300000
casesEnabled: true casesEnabled: true
detectionsEnabled: false
inactiveTools: ['toolUnused'] inactiveTools: ['toolUnused']
tools: tools:
- name: toolKibana - name: toolKibana
@@ -1114,6 +1210,9 @@ soc:
- name: caseExcludeToggle - name: caseExcludeToggle
filter: 'NOT _index:"*:so-case*"' filter: 'NOT _index:"*:so-case*"'
enabled: true enabled: true
- name: detectionsExcludeToggle
filter: 'NOT _index:"*:so-detection*"'
enabled: true
- name: socExcludeToggle - name: socExcludeToggle
filter: 'NOT event.module:"soc"' filter: 'NOT event.module:"soc"'
enabled: true enabled: true
@@ -1384,6 +1483,9 @@ soc:
- name: caseExcludeToggle - name: caseExcludeToggle
filter: 'NOT _index:"*:so-case*"' filter: 'NOT _index:"*:so-case*"'
enabled: true enabled: true
- name: detectionsExcludeToggle
filter: 'NOT _index:"*:so-detection*"'
enabled: true
- name: socExcludeToggle - name: socExcludeToggle
filter: 'NOT event.module:"soc"' filter: 'NOT event.module:"soc"'
enabled: true enabled: true
@@ -1417,13 +1519,22 @@ soc:
query: 'event.category: network AND _exists_:process.executable AND (_exists_:dns.question.name OR _exists_:dns.answers.data) | groupby -sankey host.name dns.question.name | groupby event.dataset event.type | groupby host.name | groupby process.executable | groupby dns.question.name | groupby dns.answers.data' query: 'event.category: network AND _exists_:process.executable AND (_exists_:dns.question.name OR _exists_:dns.answers.data) | groupby -sankey host.name dns.question.name | groupby event.dataset event.type | groupby host.name | groupby process.executable | groupby dns.question.name | groupby dns.answers.data'
- name: Host Process Activity - name: Host Process Activity
description: Process activity captured on an endpoint description: Process activity captured on an endpoint
query: 'event.category:process | groupby -sankey host.name user.name* | groupby event.dataset event.action | groupby host.name | groupby user.name | groupby process.working_directory | groupby process.executable | groupby process.command_line | groupby process.parent.executable | groupby process.parent.command_line | groupby -sankey process.parent.executable process.executable | table soc_timestamp event.dataset host.name user.name process.parent.name process.name process.working_directory' query: 'event.category:process | groupby -sankey host.name user.name* | groupby event.dataset event.action | groupby host.name | groupby user.name | groupby process.working_directory | groupby process.executable | groupby process.command_line | groupby process.parent.executable | groupby process.parent.command_line | groupby -sankey process.parent.executable process.executable | table soc_timestamp host.name user.name process.parent.name process.name event.action process.working_directory event.dataset'
- name: Host File Activity - name: Host File Activity
description: File activity captured on an endpoint description: File activity captured on an endpoint
query: 'event.category: file AND _exists_:process.executable | groupby -sankey host.name process.executable | groupby host.name | groupby event.dataset event.action event.type | groupby file.name | groupby process.executable' query: 'event.category: file AND _exists_:process.executable | groupby -sankey host.name process.executable | groupby host.name | groupby event.dataset event.action event.type | groupby file.name | groupby process.executable'
- name: Host Network & Process Mappings - name: Host Network & Process Mappings
description: Network activity mapped to originating processes description: Network activity mapped to originating processes
query: 'event.category: network AND _exists_:process.executable | groupby -sankey event.action host.name | groupby -sankey host.name user.name | groupby event.dataset* event.type* event.action* | groupby host.name | groupby user.name | groupby dns.question.name | groupby process.executable | groupby winlog.event_data.TargetObject | groupby process.name | groupby source.ip | groupby destination.ip | groupby destination.port' query: 'event.category: network AND _exists_:process.executable | groupby -sankey event.action host.name | groupby -sankey host.name user.name | groupby event.dataset* event.type* event.action* | groupby host.name | groupby user.name | groupby dns.question.name | groupby process.executable | groupby winlog.event_data.TargetObject | groupby process.name | groupby source.ip | groupby destination.ip | groupby destination.port'
- name: Host API Events
description: API (Application Programming Interface) events from endpoints
query: 'event.dataset:endpoint.events.api | groupby host.name | groupby -sankey host.name user.name | groupby user.name | groupby process.name | groupby process.Ext.api.name'
- name: Host Library Events
description: Library events from endpoints
query: 'event.dataset:endpoint.events.library | groupby host.name | groupby -sankey host.name user.name | groupby user.name | groupby process.name | groupby event.action | groupby dll.path | groupby dll.code_signature.status | groupby dll.code_signature.subject_name'
- name: Host Security Events
description: Security events from endpoints
query: 'event.dataset:endpoint.events.security | groupby host.name | groupby -sankey host.name user.name | groupby user.name | groupby process.executable | groupby event.action | groupby event.outcome'
- name: Strelka - name: Strelka
description: Strelka file analysis description: Strelka file analysis
query: 'event.module:strelka | groupby file.mime_type | groupby -sankey file.mime_type file.source | groupby file.source | groupby file.name' query: 'event.module:strelka | groupby file.mime_type | groupby -sankey file.mime_type file.source | groupby file.source | groupby file.name'
@@ -1754,3 +1865,55 @@ soc:
- amber+strict - amber+strict
- red - red
customEnabled: false customEnabled: false
detections:
viewEnabled: true
createLink: /detection/create
eventFetchLimit: 500
eventItemsPerPage: 50
groupFetchLimit: 50
mostRecentlyUsedLimit: 5
safeStringMaxLength: 100
queryBaseFilter: '_index:"*:so-detection" AND so_kind:detection'
eventFields:
default:
- so_detection.title
- so_detection.isEnabled
- so_detection.language
- so_detection.severity
queries:
- name: "All Detections"
query: "_id:*"
- name: "Custom Detections"
query: "so_detection.isCommunity:false"
- name: "All Detections - Enabled"
query: "so_detection.isEnabled:true"
- name: "All Detections - Disabled"
query: "so_detection.isEnabled:false"
- name: "Detection Type - Suricata (NIDS)"
query: "so_detection.language:suricata"
- name: "Detection Type - Sigma - All"
query: "so_detection.language:sigma"
- name: "Detection Type - Sigma - Windows"
query: 'so_detection.language:sigma AND so_detection.content: "*product: windows*"'
- name: "Detection Type - Yara (Strelka)"
query: "so_detection.language:yara"
detection:
presets:
severity:
customEnabled: false
labels:
- unknown
- informational
- low
- medium
- high
- critical
language:
customEnabled: false
labels:
- suricata
- sigma
- yara
severityTranslations:
minor: low
major: high

View File

@@ -22,12 +22,18 @@ so-soc:
- sobridge: - sobridge:
- ipv4_address: {{ DOCKER.containers['so-soc'].ip }} - ipv4_address: {{ DOCKER.containers['so-soc'].ip }}
- binds: - binds:
- /nsm/rules:/nsm/rules:rw
- /opt/so/conf/strelka:/opt/sensoroni/yara:rw
- /opt/so/rules/elastalert/rules:/opt/sensoroni/elastalert:rw
- /opt/so/conf/soc/fingerprints:/opt/sensoroni/fingerprints:rw
- /nsm/soc/jobs:/opt/sensoroni/jobs:rw - /nsm/soc/jobs:/opt/sensoroni/jobs:rw
- /nsm/soc/uploads:/nsm/soc/uploads:rw - /nsm/soc/uploads:/nsm/soc/uploads:rw
- /opt/so/log/soc/:/opt/sensoroni/logs/:rw - /opt/so/log/soc/:/opt/sensoroni/logs/:rw
- /opt/so/conf/soc/soc.json:/opt/sensoroni/sensoroni.json:ro - /opt/so/conf/soc/soc.json:/opt/sensoroni/sensoroni.json:ro
- /opt/so/conf/soc/motd.md:/opt/sensoroni/html/motd.md:ro - /opt/so/conf/soc/motd.md:/opt/sensoroni/html/motd.md:ro
- /opt/so/conf/soc/banner.md:/opt/sensoroni/html/login/banner.md:ro - /opt/so/conf/soc/banner.md:/opt/sensoroni/html/login/banner.md:ro
- /opt/so/conf/soc/sigma_so_pipeline.yaml:/opt/sensoroni/sigma_so_pipeline.yaml:ro
- /opt/so/conf/soc/sigma_final_pipeline.yaml:/opt/sensoroni/sigma_final_pipeline.yaml:rw
- /opt/so/conf/soc/custom.js:/opt/sensoroni/html/js/custom.js:ro - /opt/so/conf/soc/custom.js:/opt/sensoroni/html/js/custom.js:ro
- /opt/so/conf/soc/custom_roles:/opt/sensoroni/rbac/custom_roles:ro - /opt/so/conf/soc/custom_roles:/opt/sensoroni/rbac/custom_roles:ro
- /opt/so/conf/soc/soc_users_roles:/opt/sensoroni/rbac/users_roles:rw - /opt/so/conf/soc/soc_users_roles:/opt/sensoroni/rbac/users_roles:rw

View File

@@ -0,0 +1,14 @@
import os
import yara
import glob
import sys
def compile_yara_rules(rules_dir: str) -> None:
compiled_rules_path: str = os.path.join(rules_dir, "rules.yar.compiled")
rule_files: list[str] = glob.glob(os.path.join(rules_dir, '**/*.yar'), recursive=True)
if rule_files:
rules: yara.Rules = yara.compile(filepaths={os.path.basename(f): f for f in rule_files})
rules.save(compiled_rules_path)
compile_yara_rules(sys.argv[1])

View File

@@ -0,0 +1,7 @@
name: Security Onion - Final Pipeline
priority: 95
transformations:
- id: override_field_name_mapping
type: field_name_mapping
mapping:
FieldNameToOverride: NewFieldName

View File

@@ -0,0 +1,81 @@
name: Security Onion Baseline Pipeline
priority: 90
transformations:
- id: baseline_field_name_mapping
type: field_name_mapping
mapping:
cs-method: http.method
c-uri: http.uri
c-useragent: http.useragent
cs-version: http.version
uid: user.uid
sid: rule.uuid
answer: answers
query: dns.query.name
src_ip: source.ip.keyword
src_port: source.port
dst_ip: destination.ip.keyword
dst_port: destination.port
winlog.event_data.User: user.name
# Maps "antivirus" category to Windows Defender logs shipped by Elastic Agent Winlog Integration
# winlog.event_data.threat_name has to be renamed prior to ingestion, it is originally winlog.event_data.Threat Name
- id: antivirus_field-mappings_windows-defender
type: field_name_mapping
mapping:
Signature: winlog.event_data.threat_name
rule_conditions:
- type: logsource
category: antivirus
- id: antivirus_add-fields_windows-defender
type: add_condition
conditions:
winlog.channel: 'Microsoft-Windows-Windows Defender/Operational'
winlog.provider_name: 'Microsoft-Windows-Windows Defender'
event.code: "1116"
rule_conditions:
- type: logsource
category: antivirus
# Drops the Hashes field which is specific to Sysmon logs
# Ingested sysmon logs will have the Hashes field mapped to ECS specific fields
- id: hashes_drop_sysmon-specific-field
type: drop_detection_item
field_name_conditions:
- type: include_fields
fields:
- winlog.event_data.Hashes
rule_conditions:
- type: logsource
product: windows
- id: hashes_process-creation
type: field_name_mapping
mapping:
winlog.event_data.sha256: process.hash.sha256
winlog.event_data.sha1: process.hash.sha1
winlog.event_data.md5: process.hash.md5
winlog.event_data.Imphash: process.pe.imphash
rule_conditions:
- type: logsource
product: windows
category: process_creation
- id: hashes_image-load
type: field_name_mapping
mapping:
winlog.event_data.sha256: dll.hash.sha256
winlog.event_data.sha1: dll.hash.sha1
winlog.event_data.md5: dll.hash.md5
winlog.event_data.Imphash: dll.pe.imphash
rule_conditions:
- type: logsource
product: windows
category: image_load
- id: hashes_driver-load
type: field_name_mapping
mapping:
winlog.event_data.sha256: dll.hash.sha256
winlog.event_data.sha1: dll.hash.sha1
winlog.event_data.md5: dll.hash.md5
winlog.event_data.Imphash: dll.pe.imphash
rule_conditions:
- type: logsource
product: windows
category: driver_load

View File

@@ -30,6 +30,17 @@
{# since cases is not a valid soc config item and only used for the map files, remove it from being placed in the config #} {# since cases is not a valid soc config item and only used for the map files, remove it from being placed in the config #}
{% do SOCMERGED.config.server.modules.pop('cases') %} {% do SOCMERGED.config.server.modules.pop('cases') %}
{# remove these modules if detections is disabled #}
{% if not SOCMERGED.config.server.client.detectionsEnabled %}
{% do SOCMERGED.config.server.modules.pop('elastalertengine') %}
{% do SOCMERGED.config.server.modules.pop('strelkaengine') %}
{% do SOCMERGED.config.server.modules.pop('suricataengine') %}
{% elif pillar.global.airgap %}
{# if system is Airgap, don't autoupdate Yara & Sigma rules #}
{% do SOCMERGED.config.server.modules.elastalertengine.update({'autoUpdateEnabled': false}) %}
{% do SOCMERGED.config.server.modules.strelkaengine.update({'autoUpdateEnabled': false}) %}
{% endif %}
{% if pillar.manager.playbook == 0 %} {% if pillar.manager.playbook == 0 %}
{% do SOCMERGED.config.server.client.inactiveTools.append('toolPlaybook') %} {% do SOCMERGED.config.server.client.inactiveTools.append('toolPlaybook') %}
{% endif %} {% endif %}
@@ -66,6 +77,14 @@
{% do SOCMERGED.config.server.client.alerts.update({'actions': standard_actions}) %} {% do SOCMERGED.config.server.client.alerts.update({'actions': standard_actions}) %}
{% do SOCMERGED.config.server.client.cases.update({'actions': standard_actions}) %} {% do SOCMERGED.config.server.client.cases.update({'actions': standard_actions}) %}
{# replace the _x_ with . for soc ui to config conversion #}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.api': SOCMERGED.config.eventFields.pop(':endpoint:events_x_api') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.file': SOCMERGED.config.eventFields.pop(':endpoint:events_x_file') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.library': SOCMERGED.config.eventFields.pop(':endpoint:events_x_library') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.network': SOCMERGED.config.eventFields.pop(':endpoint:events_x_network') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.process': SOCMERGED.config.eventFields.pop(':endpoint:events_x_process') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.registry': SOCMERGED.config.eventFields.pop(':endpoint:events_x_registry') }) %}
{% do SOCMERGED.config.eventFields.update({':endpoint:events.security': SOCMERGED.config.eventFields.pop(':endpoint:events_x_security') }) %}
{% set standard_eventFields = SOCMERGED.config.pop('eventFields') %} {% set standard_eventFields = SOCMERGED.config.pop('eventFields') %}
{% do SOCMERGED.config.server.client.hunt.update({'eventFields': standard_eventFields}) %} {% do SOCMERGED.config.server.client.hunt.update({'eventFields': standard_eventFields}) %}
{% do SOCMERGED.config.server.client.dashboards.update({'eventFields': standard_eventFields}) %} {% do SOCMERGED.config.server.client.dashboards.update({'eventFields': standard_eventFields}) %}

View File

@@ -32,6 +32,14 @@ soc:
global: True global: True
advanced: True advanced: True
helpLink: soc-customization.html helpLink: soc-customization.html
sigma_final_pipeline__yaml:
title: Final Sigma Pipeline
description: Final Processing Pipeline for Sigma Rules (future use, not yet complete)
syntax: yaml
file: True
global: True
advanced: True
helpLink: soc-customization.html
config: config:
licenseKey: licenseKey:
title: License Key title: License Key
@@ -47,10 +55,17 @@ soc:
global: True global: True
forcedType: "[]{}" forcedType: "[]{}"
eventFields: eventFields:
default: default: &eventFields
description: Event fields mappings are defined by the format ":event.module:event.dataset". For example, to customize which fields show for 'syslog' events originating from 'zeek', find the eventField item in the left panel that looks like ':zeek:syslog'. This 'default' entry is used for all events that do not match an existing mapping defined in the list to the left. description: Event fields mappings are defined by the format ":event.module:event.dataset". For example, to customize which fields show for 'syslog' events originating from 'zeek', find the eventField item in the left panel that looks like ':zeek:syslog'. The 'default' entry is used for all events that do not match an existing mapping defined in the list to the left.
global: True global: True
advanced: True advanced: True
':endpoint:events_x_api': *eventFields
':endpoint:events_x_file': *eventFields
':endpoint:events_x_library': *eventFields
':endpoint:events_x_network': *eventFields
':endpoint:events_x_process': *eventFields
':endpoint:events_x_registry': *eventFields
':endpoint:events_x_security': *eventFields
server: server:
srvKey: srvKey:
description: Unique key for protecting the integrity of user submitted data via the web browser. description: Unique key for protecting the integrity of user submitted data via the web browser.
@@ -62,6 +77,15 @@ soc:
global: True global: True
advanced: True advanced: True
modules: modules:
elastalertengine:
sigmaRulePackages:
description: 'Defines the Sigma Community Ruleset you want to run. One of these (core | core+ | core++ | all ) as well as an optional Add-on (emerging_threats_addon). WARNING! Changing the ruleset will remove all existing Sigma rules of the previous ruleset and their associated overrides. This removal cannot be undone. (future use, not yet complete)'
global: True
advanced: False
autoUpdateEnabled:
description: 'Set to true to enable automatic Internet-connected updates of the Sigma Community Ruleset. If this is an Airgap system, this setting will be overridden and set to false. (future use, not yet complete)'
global: True
advanced: True
elastic: elastic:
index: index:
description: Comma-separated list of indices or index patterns (wildcard "*" supported) that SOC will search for records. description: Comma-separated list of indices or index patterns (wildcard "*" supported) that SOC will search for records.
@@ -102,6 +126,9 @@ soc:
description: Maximum number of events that can be acknowledged synchronously. When acknowledging large numbers of events, where the count exceeds this value, the acknowledge update will be performed in the background, as it can take several minutes to complete. description: Maximum number of events that can be acknowledged synchronously. When acknowledging large numbers of events, where the count exceeds this value, the acknowledge update will be performed in the background, as it can take several minutes to complete.
global: True global: True
advanced: True advanced: True
lookupTunnelParent:
description: When true, if a pivoted event appears to be encapsulated, such as in a VXLAN packet, then SOC will pivot to the VXLAN packet stream. When false, SOC will attempt to pivot to the encapsulated packet stream itself, but at the risk that it may be unable to locate it in the stored PCAP data.
global: True
sostatus: sostatus:
refreshIntervalMs: refreshIntervalMs:
description: Duration (in milliseconds) between refreshes of the grid status. Shortening this duration may not have expected results, as the backend systems feeding this sostatus data will continue their updates as scheduled. description: Duration (in milliseconds) between refreshes of the grid status. Shortening this duration may not have expected results, as the backend systems feeding this sostatus data will continue their updates as scheduled.
@@ -120,6 +147,11 @@ soc:
description: Duration (in milliseconds) to wait for a response from the Salt API when executing common grid management tasks before giving up and showing an error on the SOC UI. description: Duration (in milliseconds) to wait for a response from the Salt API when executing common grid management tasks before giving up and showing an error on the SOC UI.
global: True global: True
advanced: True advanced: True
strelkaengine:
autoUpdateEnabled:
description: 'Set to true to enable automatic Internet-connected updates of the Yara rulesets. If this is an Airgap system, this setting will be overridden and set to false. (future use, not yet complete)'
global: True
advanced: True
client: client:
enableReverseLookup: enableReverseLookup:
description: Set to true to enable reverse DNS lookups for IP addresses in the SOC UI. description: Set to true to enable reverse DNS lookups for IP addresses in the SOC UI.
@@ -142,6 +174,9 @@ soc:
casesEnabled: casesEnabled:
description: Set to true to enable case management in SOC. description: Set to true to enable case management in SOC.
global: True global: True
detectionsEnabled:
description: Set to true to enable the Detections module in SOC. (future use, not yet complete)
global: True
inactiveTools: inactiveTools:
description: List of external tools to remove from the SOC UI. description: List of external tools to remove from the SOC UI.
global: True global: True

View File

@@ -48,15 +48,17 @@ update_stig_profile:
{% if not salt['file.file_exists'](OSCAP_OUTPUT_DIR ~ '/pre-oscap-report.html') %} {% if not salt['file.file_exists'](OSCAP_OUTPUT_DIR ~ '/pre-oscap-report.html') %}
run_initial_scan: run_initial_scan:
module.run: cmd.run:
- name: openscap.xccdf - name: 'oscap xccdf eval --profile {{ OSCAP_PROFILE_NAME }} --results {{ OSCAP_OUTPUT_DIR }}/pre-oscap-results.xml --report {{ OSCAP_OUTPUT_DIR }}/pre-oscap-report.html {{ OSCAP_PROFILE_LOCATION }}'
- params: 'eval --profile {{ OSCAP_PROFILE_NAME }} --results {{ OSCAP_OUTPUT_DIR }}/pre-oscap-results.xml --report {{ OSCAP_OUTPUT_DIR }}/pre-oscap-report.html {{ OSCAP_PROFILE_LOCATION }}' - success_retcodes:
- 2
{% endif %} {% endif %}
run_remediate: run_remediate:
module.run: cmd.run:
- name: openscap.xccdf - name: 'oscap xccdf eval --remediate --profile {{ OSCAP_PROFILE_NAME }} {{ OSCAP_PROFILE_LOCATION }}'
- params: 'eval --remediate --profile {{ OSCAP_PROFILE_NAME }} --results {{ OSCAP_OUTPUT_DIR }}/post-oscap-results.xml --report {{ OSCAP_PROFILE_LOCATION }}' - success_retcodes:
- 2
{# OSCAP rule id: xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_burstaction #} {# OSCAP rule id: xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_burstaction #}
disable_ctrl_alt_del_action: disable_ctrl_alt_del_action:
@@ -82,9 +84,10 @@ remove_nullok_from_system_auth_auth:
- backup: '.bak' - backup: '.bak'
run_post_scan: run_post_scan:
module.run: cmd.run:
- name: openscap.xccdf - name: 'oscap xccdf eval --profile {{ OSCAP_PROFILE_NAME }} --results {{ OSCAP_OUTPUT_DIR }}/post-oscap-results.xml --report {{ OSCAP_OUTPUT_DIR }}/post-oscap-report.html /usr/share/xml/scap/ssg/content/ssg-ol9-ds.xml'
- params: 'eval --profile {{ OSCAP_PROFILE_NAME }} --results {{ OSCAP_OUTPUT_DIR }}/post-oscap-results.xml --report {{ OSCAP_OUTPUT_DIR }}/post-oscap-report.html {{ OSCAP_PROFILE_LOCATION }}' - success_retcodes:
- 2
{% else %} {% else %}
{{sls}}_no_license_detected: {{sls}}_no_license_detected:

View File

@@ -611,7 +611,7 @@ the release. Additionally, the original security profile has been modified by Se
<ns5:select idref="xccdf_org.ssgproject.content_rule_account_emergency_expire_date" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_account_emergency_expire_date" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_account_password_pam_faillock_password_auth" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_account_password_pam_faillock_password_auth" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_account_password_pam_faillock_system_auth" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_account_password_pam_faillock_system_auth" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_account_password_selinux_faillock_dir" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_account_password_selinux_faillock_dir" selected="false" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_account_temp_expire_date" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_account_temp_expire_date" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_account_unique_id" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_account_unique_id" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_accounts_authorized_local_users" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_accounts_authorized_local_users" selected="true" />
@@ -1007,8 +1007,8 @@ the release. Additionally, the original security profile has been modified by Se
<ns5:select idref="xccdf_org.ssgproject.content_rule_rsyslog_remote_access_monitoring" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_rsyslog_remote_access_monitoring" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_rsyslog_remote_loghost" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_rsyslog_remote_loghost" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_security_patches_up_to_date" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_security_patches_up_to_date" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_selinux_policytype" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_selinux_policytype" selected="false" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_selinux_state" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_selinux_state" selected="false" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_service_auditd_enabled" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_service_auditd_enabled" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_service_autofs_disabled" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_service_autofs_disabled" selected="true" />
<ns5:select idref="xccdf_org.ssgproject.content_rule_service_chronyd_enabled" selected="true" /> <ns5:select idref="xccdf_org.ssgproject.content_rule_service_chronyd_enabled" selected="true" />

View File

@@ -50,15 +50,15 @@ backend_taste:
- user: 939 - user: 939
- group: 939 - group: 939
{% if STRELKAMERGED.rules.enabled %} {% if STRELKAMERGED.rules.enabled %}
strelkarules: strelkarules:
file.recurse: file.recurse:
- name: /opt/so/conf/strelka/rules - name: /opt/so/conf/strelka/rules
- source: salt://strelka/rules - source: salt://strelka/rules
- user: 939 - user: 939
- group: 939 - group: 939
- clean: True - clean: True
{% endif %} {% endif %}
{% else %} {% else %}

View File

@@ -1,5 +1,5 @@
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one # Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at # or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the # https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0. # Elastic License 2.0.
@@ -21,6 +21,13 @@ strelkarulesdir:
- group: 939 - group: 939
- makedirs: True - makedirs: True
strelkareposdir:
file.directory:
- name: /opt/so/conf/strelka/repos
- user: 939
- group: 939
- makedirs: True
strelkadatadir: strelkadatadir:
file.directory: file.directory:
- name: /nsm/strelka - name: /nsm/strelka

View File

@@ -0,0 +1,51 @@
#
# config classification:shortname,short description,priority
#
config classification: not-suspicious,Not Suspicious Traffic,3
config classification: unknown,Unknown Traffic,3
config classification: bad-unknown,Potentially Bad Traffic, 2
config classification: attempted-recon,Attempted Information Leak,2
config classification: successful-recon-limited,Information Leak,2
config classification: successful-recon-largescale,Large Scale Information Leak,2
config classification: attempted-dos,Attempted Denial of Service,2
config classification: successful-dos,Denial of Service,2
config classification: attempted-user,Attempted User Privilege Gain,1
config classification: unsuccessful-user,Unsuccessful User Privilege Gain,1
config classification: successful-user,Successful User Privilege Gain,1
config classification: attempted-admin,Attempted Administrator Privilege Gain,1
config classification: successful-admin,Successful Administrator Privilege Gain,1
# NEW CLASSIFICATIONS
config classification: rpc-portmap-decode,Decode of an RPC Query,2
config classification: shellcode-detect,Executable code was detected,1
config classification: string-detect,A suspicious string was detected,3
config classification: suspicious-filename-detect,A suspicious filename was detected,2
config classification: suspicious-login,An attempted login using a suspicious username was detected,2
config classification: system-call-detect,A system call was detected,2
config classification: tcp-connection,A TCP connection was detected,4
config classification: trojan-activity,A Network Trojan was detected, 1
config classification: unusual-client-port-connection,A client was using an unusual port,2
config classification: network-scan,Detection of a Network Scan,3
config classification: denial-of-service,Detection of a Denial of Service Attack,2
config classification: non-standard-protocol,Detection of a non-standard protocol or event,2
config classification: protocol-command-decode,Generic Protocol Command Decode,3
config classification: web-application-activity,access to a potentially vulnerable web application,2
config classification: web-application-attack,Web Application Attack,1
config classification: misc-activity,Misc activity,3
config classification: misc-attack,Misc Attack,2
config classification: icmp-event,Generic ICMP event,3
config classification: inappropriate-content,Inappropriate Content was Detected,1
config classification: policy-violation,Potential Corporate Privacy Violation,1
config classification: default-login-attempt,Attempt to login by a default username and password,2
# Update
config classification: targeted-activity,Targeted Malicious Activity was Detected,1
config classification: exploit-kit,Exploit Kit Activity Detected,1
config classification: external-ip-check,Device Retrieving External IP Address Detected,2
config classification: domain-c2,Domain Observed Used for C2 Detected,1
config classification: pup-activity,Possibly Unwanted Program Detected,2
config classification: credential-theft,Successful Credential Theft Detected,1
config classification: social-engineering,Possible Social Engineering Attempted,2
config classification: coin-mining,Crypto Currency Mining Activity Detected,2
config classification: command-and-control,Malware Command and Control Activity Detected,1

View File

@@ -129,6 +129,13 @@ surithresholding:
- group: 940 - group: 940
- template: jinja - template: jinja
suriclassifications:
file.managed:
- name: /opt/so/conf/suricata/classification.config
- source: salt://suricata/classification/classification.config
- user: 940
- group: 940
# BPF compilation and configuration # BPF compilation and configuration
{% if SURICATABPF %} {% if SURICATABPF %}
{% set BPF_CALC = salt['cmd.script']('salt://common/tools/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + SURICATABPF|join(" "),cwd='/root') %} {% set BPF_CALC = salt['cmd.script']('salt://common/tools/sbin/so-bpf-compile', GLOBALS.sensor.interface + ' ' + SURICATABPF|join(" "),cwd='/root') %}

View File

@@ -1,5 +1,16 @@
suricata: suricata:
enabled: False enabled: False
pcap:
filesize: 1000mb
maxsize: 25
compression: "none"
lz4-checksum: "no"
lz4-level: 8
filename: "%n/so-pcap.%t"
mode: "multi"
use-stream-depth: "no"
conditional: "all"
dir: "/nsm/suripcap"
config: config:
threading: threading:
set-cpu-affinity: "no" set-cpu-affinity: "no"

View File

@@ -27,11 +27,13 @@ so-suricata:
- binds: - binds:
- /opt/so/conf/suricata/suricata.yaml:/etc/suricata/suricata.yaml:ro - /opt/so/conf/suricata/suricata.yaml:/etc/suricata/suricata.yaml:ro
- /opt/so/conf/suricata/threshold.conf:/etc/suricata/threshold.conf:ro - /opt/so/conf/suricata/threshold.conf:/etc/suricata/threshold.conf:ro
- /opt/so/conf/suricata/classification.config:/etc/suricata/classification.config:ro
- /opt/so/conf/suricata/rules:/etc/suricata/rules:ro - /opt/so/conf/suricata/rules:/etc/suricata/rules:ro
- /opt/so/log/suricata/:/var/log/suricata/:rw - /opt/so/log/suricata/:/var/log/suricata/:rw
- /nsm/suricata/:/nsm/:rw - /nsm/suricata/:/nsm/:rw
- /nsm/suricata/extracted:/var/log/suricata//filestore:rw - /nsm/suricata/extracted:/var/log/suricata//filestore:rw
- /opt/so/conf/suricata/bpf:/etc/suricata/bpf:ro - /opt/so/conf/suricata/bpf:/etc/suricata/bpf:ro
- /nsm/suripcap/:/nsm/suripcap:rw
{% if DOCKER.containers['so-suricata'].custom_bind_mounts %} {% if DOCKER.containers['so-suricata'].custom_bind_mounts %}
{% for BIND in DOCKER.containers['so-suricata'].custom_bind_mounts %} {% for BIND in DOCKER.containers['so-suricata'].custom_bind_mounts %}
- {{ BIND }} - {{ BIND }}
@@ -49,10 +51,12 @@ so-suricata:
- file: surithresholding - file: surithresholding
- file: /opt/so/conf/suricata/rules/ - file: /opt/so/conf/suricata/rules/
- file: /opt/so/conf/suricata/bpf - file: /opt/so/conf/suricata/bpf
- file: suriclassifications
- require: - require:
- file: suriconfig - file: suriconfig
- file: surithresholding - file: surithresholding
- file: suribpf - file: suribpf
- file: suriclassifications
delete_so-suricata_so-status.disabled: delete_so-suricata_so-status.disabled:
file.uncomment: file.uncomment:

View File

@@ -7,6 +7,7 @@
{% from 'suricata/map.jinja' import SURICATAMERGED %} {% from 'suricata/map.jinja' import SURICATAMERGED %}
include: include:
- suricata.pcap
{% if SURICATAMERGED.enabled and GLOBALS.role != 'so-import' %} {% if SURICATAMERGED.enabled and GLOBALS.role != 'so-import' %}
- suricata.enabled - suricata.enabled
{% elif GLOBALS.role == 'so-import' %} {% elif GLOBALS.role == 'so-import' %}

View File

@@ -8,6 +8,24 @@
{% set surimeta_evelog_index = [] %} {% set surimeta_evelog_index = [] %}
{% set surimeta_filestore_index = [] %} {% set surimeta_filestore_index = [] %}
{# before we change outputs back to list, enable pcap-log if suricata is the pcapengine #}
{% if GLOBALS.pcap_engine in ["SURICATA", "TRANSITION"] %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'enabled': 'yes'}) %}
{# move the items in suricata.pcap into suricata.config.outputs.pcap-log. these items were placed under suricata.config for ease of access in SOC #}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'compression': SURICATAMERGED.pcap.compression}) %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'lz4-checksum': SURICATAMERGED.pcap['lz4-checksum']}) %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'lz4-level': SURICATAMERGED.pcap['lz4-level']}) %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'filename': SURICATAMERGED.pcap.filename}) %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'limit': SURICATAMERGED.pcap.filesize}) %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'mode': SURICATAMERGED.pcap.mode}) %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'use-stream-depth': SURICATAMERGED.pcap['use-stream-depth']}) %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'conditional': SURICATAMERGED.pcap.conditional}) %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'dir': SURICATAMERGED.pcap.dir}) %}
{# multiply maxsize by 1000 since it is saved in GB, i.e. 52 = 52000MB. filesize is also saved in MB and we strip the MB and convert to int #}
{% set maxfiles = (SURICATAMERGED.pcap.maxsize * 1000 / (SURICATAMERGED.pcap.filesize[:-2] | int) / SURICATAMERGED.config['af-packet'].threads | int) | round | int %}
{% do SURICATAMERGED.config.outputs['pcap-log'].update({'max-files': maxfiles}) %}
{% endif %}
{# suricata.config.af-packet has to be rewritten here since we cant display '- interface' in the ui #} {# suricata.config.af-packet has to be rewritten here since we cant display '- interface' in the ui #}
{# we are limited to only one iterface #} {# we are limited to only one iterface #}
{% load_yaml as afpacket %} {% load_yaml as afpacket %}

28
salt/suricata/pcap.sls Normal file
View File

@@ -0,0 +1,28 @@
{% from 'vars/globals.map.jinja' import GLOBALS %}
{% from 'suricata/map.jinja' import SURICATAMERGED %}
# This directory needs to exist regardless of whether SURIPCAP is enabled or not, in order for
# Sensoroni to be able to look at old Suricata PCAP data
suripcapdir:
file.directory:
- name: /nsm/suripcap
- user: 940
- group: 939
- mode: 775
- makedirs: True
{% if GLOBALS.pcap_engine in ["SURICATA", "TRANSITION"] %}
{# there should only be 1 interface in af-packet so we can just reference the first list item #}
{% for i in range(1, SURICATAMERGED.config['af-packet'][0].threads + 1) %}
suripcapthread{{i}}dir:
file.directory:
- name: /nsm/suripcap/{{i}}
- user: 940
- group: 939
- mode: 775
{% endfor %}
{% endif %}

View File

@@ -11,6 +11,60 @@ suricata:
multiline: True multiline: True
title: SIDS title: SIDS
helpLink: suricata.html helpLink: suricata.html
classification:
classification__config:
description: Classifications config file.
file: True
global: True
multiline: True
title: Classifications
helpLink: suricata.html
pcap:
filesize:
description: Max file size for individual PCAP files written by Suricata. Increasing this number could improve write performance at the expense of pcap retrieval times.
advanced: True
helplink: suricata.html
maxsize:
description: Size in GB for total usage size of PCAP on disk.
helplink: suricata.html
compression:
description: Enable compression of Suricata PCAP.
advanced: True
helpLink: suricata.html
lz4-checksum:
description: Enable PCAP lz4 checksum.
advanced: True
helpLink: suricata.html
lz4-level:
description: lz4 compression level of PCAP. 0 for no compression 16 for max compression.
advanced: True
helpLink: suricata.html
filename:
description: Filename output for Suricata PCAP.
advanced: True
readonly: True
helpLink: suricata.html
mode:
description: Suricata PCAP mode. Currently only multi is supported.
advanced: True
readonly: True
helpLink: suricata.html
use-stream-depth:
description: Set to "no" to ignore the stream depth and capture the entire flow. Set this to "yes" to truncate the flow based on the stream depth.
advanced: True
regex: ^(yes|no)$
regexFailureMessage: You must enter either yes or no.
helpLink: suricata.html
conditional:
description: Set to "all" to capture PCAP for all flows. Set to "alerts" to capture PCAP just for alerts or set to "tag" to capture PCAP for just tagged rules.
regex: ^(all|alerts|tag)$
regexFailureMessage: You must enter either all, alert or tag.
helpLink: suricata.html
dir:
description: Parent directory to store PCAP.
advanced: True
readonly: True
helpLink: suricata.html
config: config:
af-packet: af-packet:
interface: interface:
@@ -44,6 +98,7 @@ suricata:
set-cpu-affinity: set-cpu-affinity:
description: Bind(yes) or unbind(no) management and worker threads to a core or range of cores. description: Bind(yes) or unbind(no) management and worker threads to a core or range of cores.
regex: ^(yes|no)$ regex: ^(yes|no)$
regexFailureMessage: You must enter either yes or no.
helpLink: suricata.html helpLink: suricata.html
cpu-affinity: cpu-affinity:
management-cpu-set: management-cpu-set:
@@ -153,6 +208,12 @@ suricata:
header: header:
description: Header name where the actual IP address will be reported. description: Header name where the actual IP address will be reported.
helpLink: suricata.html helpLink: suricata.html
pcap-log:
enabled:
description: This value is ignored by SO. pcapengine in globals takes precidence.
readonly: True
helpLink: suricata.html
advanced: True
asn1-max-frames: asn1-max-frames:
description: Maximum nuber of asn1 frames to decode. description: Maximum nuber of asn1 frames to decode.
helpLink: suricata.html helpLink: suricata.html
@@ -209,6 +270,9 @@ suricata:
memcap: memcap:
description: Can be specified in kb,mb,gb. description: Can be specified in kb,mb,gb.
helpLink: suricata.html helpLink: suricata.html
depth:
description: Controls how far into a stream that reassembly is done.
helpLink: suricata.html
host: host:
hash-size: hash-size:
description: Hash size in bytes. description: Hash size in bytes.

View File

@@ -41,6 +41,8 @@ tgraf_sync_script_{{script}}:
- mode: 770 - mode: 770
- template: jinja - template: jinja
- source: salt://telegraf/scripts/{{script}} - source: salt://telegraf/scripts/{{script}}
- defaults:
GLOBALS: {{ GLOBALS }}
{% endfor %} {% endfor %}
telegraf_sbin: telegraf_sbin:

View File

@@ -14,4 +14,11 @@
{% do TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]].remove('zeekloss.sh') %} {% do TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]].remove('zeekloss.sh') %}
{% do TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]].remove('zeekcaptureloss.sh') %} {% do TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]].remove('zeekcaptureloss.sh') %}
{% endif %} {% endif %}
{% from 'pcap/config.map.jinja' import PCAPMERGED %}
{# PCAPMERGED.enabled is set false in soc ui or if suricata is the pcap engine #}
{% if not PCAPMERGED.enabled %}
{% do TELEGRAFMERGED.scripts[GLOBALS.role.split('-')[1]].remove('stenoloss.sh') %}
{% endif %}
{% endif %} {% endif %}

View File

@@ -5,13 +5,17 @@
# https://securityonion.net/license; you may not use this file except in compliance with the # https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0. # Elastic License 2.0.
{%- if GLOBALS.pcap_engine in ["SURICATA", "TRANSITION"] %}
PCAPLOC=/host/nsm/suripcap
{%- else %}
PCAPLOC=/host/nsm/pcap
{%- endif %}
# if this script isn't already running # if this script isn't already running
if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
# Get the data # Get the data
OLDPCAP=$(find /host/nsm/pcap -type f -exec stat -c'%n %Z' {} + | sort | grep -v "\." | head -n 1 | awk {'print $2'}) OLDPCAP=$(find $PCAPLOC -type f -exec stat -c'%n %Z' {} + | sort | grep -v "/\." | head -n 1 | awk {'print $2'})
DATE=$(date +%s) DATE=$(date +%s)
AGE=$(($DATE - $OLDPCAP)) AGE=$(($DATE - $OLDPCAP))

View File

@@ -10,8 +10,8 @@
# if this script isn't already running # if this script isn't already running
if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then if [[ ! "`pidof -x $(basename $0) -o %PPID`" ]]; then
CHECKIT=$(grep "Thread 0" /var/log/stenographer/stenographer.log |tac |head -2|wc -l) CHECKIT=$(grep "Thread 0 stats" /var/log/stenographer/stenographer.log |tac |head -2|wc -l)
STENOGREP=$(grep "Thread 0" /var/log/stenographer/stenographer.log |tac |head -2) STENOGREP=$(grep "Thread 0 stats" /var/log/stenographer/stenographer.log |tac |head -2)
declare RESULT=($STENOGREP) declare RESULT=($STENOGREP)

View File

@@ -1,5 +1,6 @@
{% import 'vars/init.map.jinja' as INIT %} {% import 'vars/init.map.jinja' as INIT %}
{% from 'docker/docker.map.jinja' import DOCKER %} {% from 'docker/docker.map.jinja' import DOCKER %}
{% from 'global/map.jinja' import GLOBALMERGED %}
{% from 'vars/' ~ INIT.GRAINS.role.split('-')[1] ~ '.map.jinja' import ROLE_GLOBALS %} {# role is so-role so we have to split off the 'so' #} {% from 'vars/' ~ INIT.GRAINS.role.split('-')[1] ~ '.map.jinja' import ROLE_GLOBALS %} {# role is so-role so we have to split off the 'so' #}
@@ -7,6 +8,7 @@
set GLOBALS = { set GLOBALS = {
'hostname': INIT.GRAINS.nodename, 'hostname': INIT.GRAINS.nodename,
'is_manager': false, 'is_manager': false,
'is_sensor': false,
'manager': INIT.GRAINS.master, 'manager': INIT.GRAINS.master,
'minion_id': INIT.GRAINS.id, 'minion_id': INIT.GRAINS.id,
'main_interface': INIT.PILLAR.host.mainint, 'main_interface': INIT.PILLAR.host.mainint,
@@ -20,6 +22,7 @@
'influxdb_host': INIT.PILLAR.global.influxdb_host, 'influxdb_host': INIT.PILLAR.global.influxdb_host,
'manager_ip': INIT.PILLAR.global.managerip, 'manager_ip': INIT.PILLAR.global.managerip,
'md_engine': INIT.PILLAR.global.mdengine, 'md_engine': INIT.PILLAR.global.mdengine,
'pcap_engine': GLOBALMERGED.pcapengine,
'pipeline': INIT.PILLAR.global.pipeline, 'pipeline': INIT.PILLAR.global.pipeline,
'so_version': INIT.PILLAR.global.soversion, 'so_version': INIT.PILLAR.global.soversion,
'so_docker_gateway': DOCKER.gateway, 'so_docker_gateway': DOCKER.gateway,
@@ -61,5 +64,8 @@
{% do GLOBALS.update({'is_manager': true}) %} {% do GLOBALS.update({'is_manager': true}) %}
{% endif %} {% endif %}
{% if GLOBALS.role in GLOBALS.sensor_roles %}
{% do GLOBALS.update({'is_sensor': true}) %}
{% endif %}
{% do salt['defaults.merge'](GLOBALS, ROLE_GLOBALS, merge_lists=False, in_place=True) %} {% do salt['defaults.merge'](GLOBALS, ROLE_GLOBALS, merge_lists=False, in_place=True) %}

View File

@@ -1812,7 +1812,7 @@ repo_sync_local() {
mkdir -p /nsm/repo mkdir -p /nsm/repo
mkdir -p /opt/so/conf/reposync/cache mkdir -p /opt/so/conf/reposync/cache
echo "https://repo.securityonion.net/file/so-repo/prod/2.4/oracle/9" > /opt/so/conf/reposync/mirror.txt echo "https://repo.securityonion.net/file/so-repo/prod/2.4/oracle/9" > /opt/so/conf/reposync/mirror.txt
echo "https://so-repo-east.s3.us-east-005.backblazeb2.com/prod/2.4/oracle/9" >> /opt/so/conf/reposync/mirror.txt echo "https://repo-alt.securityonion.net/prod/2.4/oracle/9" >> /opt/so/conf/reposync/mirror.txt
echo "[main]" > /opt/so/conf/reposync/repodownload.conf echo "[main]" > /opt/so/conf/reposync/repodownload.conf
echo "gpgcheck=1" >> /opt/so/conf/reposync/repodownload.conf echo "gpgcheck=1" >> /opt/so/conf/reposync/repodownload.conf
echo "installonly_limit=3" >> /opt/so/conf/reposync/repodownload.conf echo "installonly_limit=3" >> /opt/so/conf/reposync/repodownload.conf

View File

@@ -687,10 +687,8 @@ if ! [[ -f $install_opt_file ]]; then
logCmd "so-minion -o=setup" logCmd "so-minion -o=setup"
title "Creating Global SLS" title "Creating Global SLS"
if [[ $is_airgap ]]; then # Airgap Rules
# Airgap Rules airgap_rules
airgap_rules
fi
manager_pillar manager_pillar

View File

@@ -195,10 +195,12 @@ whiptail_create_web_user() {
[ -n "$TESTING" ] && return [ -n "$TESTING" ] && return
WEBUSER=$(whiptail --title "$whiptail_title" --inputbox \ WEBUSER=$(whiptail --title "$whiptail_title" --inputbox \
"Please enter an email address to create an administrator account for the Security Onion Console (SOC) web interface.\n\nThis will also be used for Elasticsearch and Kibana." 12 60 "$1" 3>&1 1>&2 2>&3) "Please enter an email address to create an administrator account for the Security Onion Console (SOC) web interface.\n\nThis will also be used for Elasticsearch and Kibana.\n\nMust only include letters, numbers, or + - _ % . @ characters. All capitalized letters will be converted to lowercase." 15 60 "$1" 3>&1 1>&2 2>&3)
local exitstatus=$? local exitstatus=$?
whiptail_check_exitstatus $exitstatus whiptail_check_exitstatus $exitstatus
WEBUSER=${WEBUSER,,}
} }
whiptail_create_web_user_password1() { whiptail_create_web_user_password1() {

Binary file not shown.