Merge branch 'bugfix/reinstall' into experimental

This commit is contained in:
William Wernert
2020-12-02 14:45:46 -05:00
202 changed files with 3722 additions and 4150 deletions
+12
View File
@@ -0,0 +1,12 @@
PLEASE STOP AND READ THIS INFORMATION!
If you are creating an issue just to ask a question, you will likely get faster and better responses by posting to our discussions forum instead:
https://securityonion.net/discuss
If you think you have found a possible bug or are observing a behavior that you weren't expecting, use the discussion forum to start a conversation about it instead of creating an issue.
If you are very familiar with the latest version of the product and are confident you have found a bug in Security Onion, you can continue with creating an issue here, but please make sure you have done the following:
- duplicated the issue on a fresh installation of the latest version
- provide information about your system and how you installed Security Onion
- include relevant log files
- include reproduction steps
+15
View File
@@ -0,0 +1,15 @@
name: leak-test
on: [push,pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: '0'
- name: Gitleaks
uses: zricethezav/gitleaks-action@master
+1
View File
@@ -1,4 +1,5 @@
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBF7rzwEBEADBg87uJhnC3Ls7s60hbHGaywGrPtbz2WuYA/ev3YS3X7WS75p8 mQINBF7rzwEBEADBg87uJhnC3Ls7s60hbHGaywGrPtbz2WuYA/ev3YS3X7WS75p8
PGlzTWUCujx0pEHbK2vYfExl3zksZ8ZmLyZ9VB3oSLiWBzJgKAeB7YCFEo8te+eE PGlzTWUCujx0pEHbK2vYfExl3zksZ8ZmLyZ9VB3oSLiWBzJgKAeB7YCFEo8te+eE
P2Z+8c+kX4eOV+2waxZyewA2TipSkhWgStSI4Ow8SyVUcUWA3hCw7mo2duNVi7KO P2Z+8c+kX4eOV+2waxZyewA2TipSkhWgStSI4Ow8SyVUcUWA3hCw7mo2duNVi7KO
+8 -10
View File
@@ -1,16 +1,14 @@
## Security Onion 2.3.0 ## Security Onion 2.3.10
Security Onion 2.3.0 is here! Security Onion 2.3.10 is here!
### Warnings and Disclaimers ## Screenshots
- If this breaks your system, you get to keep both pieces! Alerts
- This is a work in progress and is in constant flux. ![Alerts](https://raw.githubusercontent.com/security-onion-solutions/securityonion/master/screenshots/alerts-1.png)
- This configuration may change drastically over time leading up to the final release.
- Do NOT run this on a system that you care about! Hunt
- Do NOT run this on a system that has data that you care about! ![Hunt](https://raw.githubusercontent.com/security-onion-solutions/securityonion/master/screenshots/hunt-1.png)
- This script should only be run on a TEST box with TEST data!
- Use of this script may result in nausea, vomiting, or a burning sensation.
### Release Notes ### Release Notes
+12 -12
View File
@@ -1,16 +1,16 @@
### 2.2.0-rc3 ISO image built on 2020/09/17 ### 2.3.10 ISO image built on 2020/11/19
### Download and Verify ### Download and Verify
2.2.0-rc3 ISO image: 2.3.10 ISO image:
https://download.securityonion.net/file/securityonion/securityonion-2.2.0-rc3.iso https://download.securityonion.net/file/securityonion/securityonion-2.3.10.iso
MD5: 051883501C905653ACBCEC513C294778 MD5: 55E10BAE3D90DF47CA4D5DCCDCB67A96
SHA1: 0A66F6636F53B268E7FFB743A3136AC5CC3E0E96 SHA1: 01361123F35CEACE077803BC8074594D57EE653A
SHA256: 5A9F303954AF1B1D271CE526E5DCBFC28F3FFC0621B291A29F0F7F2E8EB11C43 SHA256: 772EA4EFFFF12F026593F5D1CC93DB538CC17B9BA5F60308F1976B6ED7032A8D
Signature for ISO image: Signature for ISO image:
https://github.com/Security-Onion-Solutions/securityonion/raw/master/sigs/securityonion-2.2.0-rc3.iso.sig https://github.com/Security-Onion-Solutions/securityonion/raw/master/sigs/securityonion-2.3.10.iso.sig
Signing key: Signing key:
https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/master/KEYS https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/master/KEYS
@@ -24,22 +24,22 @@ wget https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/ma
Download the signature file for the ISO: Download the signature file for the ISO:
``` ```
wget https://github.com/Security-Onion-Solutions/securityonion/raw/master/sigs/securityonion-2.2.0-rc3.iso.sig wget https://github.com/Security-Onion-Solutions/securityonion/raw/master/sigs/securityonion-2.3.10.iso.sig
``` ```
Download the ISO image: Download the ISO image:
``` ```
wget https://download.securityonion.net/file/securityonion/securityonion-2.2.0-rc3.iso wget https://download.securityonion.net/file/securityonion/securityonion-2.3.10.iso
``` ```
Verify the downloaded ISO image using the signature file: Verify the downloaded ISO image using the signature file:
``` ```
gpg --verify securityonion-2.2.0-rc3.iso.sig securityonion-2.2.0-rc3.iso gpg --verify securityonion-2.3.10.iso.sig securityonion-2.3.10.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 Thu 17 Sep 2020 10:05:27 AM EDT using RSA key ID FE507013 gpg: Signature made Thu 19 Nov 2020 03:38:54 PM EST 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.
@@ -47,4 +47,4 @@ Primary key fingerprint: C804 A93D 36BE 0C73 3EA1 9644 7C10 60B7 FE50 7013
``` ```
Once you've verified the ISO image, you're ready to proceed to our Installation guide: Once you've verified the ISO image, you're ready to proceed to our Installation guide:
https://docs.securityonion.net/en/2.2/installation.html https://docs.securityonion.net/en/2.3/installation.html
+1 -1
View File
@@ -1 +1 @@
2.3.0 2.3.20
+13
View File
@@ -0,0 +1,13 @@
elasticsearch:
templates:
- so/so-beats-template.json.jinja
- so/so-common-template.json
- so/so-firewall-template.json.jinja
- so/so-flow-template.json.jinja
- so/so-ids-template.json.jinja
- so/so-import-template.json.jinja
- so/so-osquery-template.json.jinja
- so/so-ossec-template.json.jinja
- so/so-strelka-template.json.jinja
- so/so-syslog-template.json.jinja
- so/so-zeek-template.json.jinja
+18 -17
View File
@@ -14,22 +14,23 @@ base:
- logstash.search - logstash.search
- elasticsearch.search - elasticsearch.search
'*_sensor':
- global
- zeeklogs
- healthcheck.sensor
- minions.{{ grains.id }}
'*_manager or *_managersearch':
- match: compound
- global
- data.*
- secrets
- minions.{{ grains.id }}
'*_manager': '*_manager':
- logstash - logstash
- logstash.manager - logstash.manager
- elasticsearch.manager
'*_manager or *_managersearch':
- match: compound
- data.*
- secrets
- global
- minions.{{ grains.id }}
'*_sensor':
- zeeklogs
- healthcheck.sensor
- global
- minions.{{ grains.id }}
'*_eval': '*_eval':
- data.* - data.*
@@ -57,29 +58,29 @@ base:
- minions.{{ grains.id }} - minions.{{ grains.id }}
'*_heavynode': '*_heavynode':
- global
- zeeklogs - zeeklogs
- global
- minions.{{ grains.id }} - minions.{{ grains.id }}
'*_helix': '*_helix':
- global
- fireeye - fireeye
- zeeklogs - zeeklogs
- logstash - logstash
- logstash.helix - logstash.helix
- global
- minions.{{ grains.id }} - minions.{{ grains.id }}
'*_fleet': '*_fleet':
- global
- data.* - data.*
- secrets - secrets
- global
- minions.{{ grains.id }} - minions.{{ grains.id }}
'*_searchnode': '*_searchnode':
- global
- logstash - logstash
- logstash.search - logstash.search
- elasticsearch.search - elasticsearch.search
- global
- minions.{{ grains.id }} - minions.{{ grains.id }}
'*_import': '*_import':
+61 -1
View File
@@ -1,4 +1,64 @@
#!py #!py
import logging
def status(): def status():
return __salt__['cmd.run']('/usr/sbin/so-status') return __salt__['cmd.run']('/usr/sbin/so-status')
def mysql_conn(retry):
log = logging.getLogger(__name__)
from time import sleep
try:
from MySQLdb import _mysql
except ImportError as e:
log.error(e)
return False
mainint = __salt__['pillar.get']('host:mainint')
ip_arr = __salt__['grains.get']('ip_interfaces').get(mainint)
mysql_up = False
if len(ip_arr) == 1:
mainip = ip_arr[0]
if not(retry >= 1):
log.debug('`retry` set to value below 1, resetting it to 1 to prevent errors.')
retry = 1
for i in range(0, retry):
log.debug(f'Connection attempt {i+1}')
try:
db = _mysql.connect(
host=mainip,
user='root',
passwd=__salt__['pillar.get']('secrets:mysql')
)
log.debug(f'Connected to MySQL server on {mainip} after {i+1} attempts.')
db.query("""SELECT 1;""")
log.debug(f'Successfully completed query against MySQL server on {mainip}')
db.close()
mysql_up = True
break
except _mysql.OperationalError as e:
log.debug(e)
except Exception as e:
log.error('Unexpected error occured.')
log.error(e)
break
sleep(1)
if not mysql_up:
log.error(f'Could not connect to MySQL server on {mainip} after {retry} attempts.')
else:
log.error(f'Main interface {mainint} has more than one IP address assigned to it, which is not supported.')
log.debug(f'{mainint}:')
for addr in ip_arr:
log.debug(f' - {addr}')
return mysql_up
+1
View File
@@ -18,6 +18,7 @@
/opt/so/log/filebeat/*.log /opt/so/log/filebeat/*.log
/opt/so/log/telegraf/*.log /opt/so/log/telegraf/*.log
/opt/so/log/redis/*.log /opt/so/log/redis/*.log
/opt/so/log/salt/so-salt-minion-check
{ {
{{ logrotate_conf | indent(width=4) }} {{ logrotate_conf | indent(width=4) }}
} }
+14 -2
View File
@@ -32,6 +32,18 @@ soconfperms:
- gid: 939 - gid: 939
- dir_mode: 770 - dir_mode: 770
sostatusconf:
file.directory:
- name: /opt/so/conf/so-status
- uid: 939
- gid: 939
- dir_mode: 770
so-status.conf:
file.touch:
- name: /opt/so/conf/so-status/so-status.conf
- unless: ls /opt/so/conf/so-status/so-status.conf
sosaltstackperms: sosaltstackperms:
file.directory: file.directory:
- name: /opt/so/saltstack - name: /opt/so/saltstack
@@ -158,8 +170,8 @@ Etc/UTC:
utilsyncscripts: utilsyncscripts:
file.recurse: file.recurse:
- name: /usr/sbin - name: /usr/sbin
- user: 0 - user: root
- group: 0 - group: root
- file_mode: 755 - file_mode: 755
- template: jinja - template: jinja
- source: salt://common/tools/sbin - source: salt://common/tools/sbin
-5
View File
@@ -1,5 +0,0 @@
{% set docker = {
'containers': [
'so-domainstats'
]
} %}
-20
View File
@@ -1,20 +0,0 @@
{% set docker = {
'containers': [
'so-filebeat',
'so-nginx',
'so-telegraf',
'so-dockerregistry',
'so-soc',
'so-kratos',
'so-idstools',
'so-elasticsearch',
'so-kibana',
'so-steno',
'so-suricata',
'so-zeek',
'so-curator',
'so-elastalert',
'so-soctopus',
'so-sensoroni'
]
} %}
-10
View File
@@ -1,10 +0,0 @@
{% set docker = {
'containers': [
'so-mysql',
'so-fleet',
'so-redis',
'so-filebeat',
'so-nginx',
'so-telegraf'
]
} %}
-7
View File
@@ -1,7 +0,0 @@
{% set docker = {
'containers': [
'so-mysql',
'so-fleet',
'so-redis'
]
} %}
-5
View File
@@ -1,5 +0,0 @@
{% set docker = {
'containers': [
'so-freqserver'
]
} %}
-6
View File
@@ -1,6 +0,0 @@
{% set docker = {
'containers': [
'so-influxdb',
'so-grafana'
]
} %}
-15
View File
@@ -1,15 +0,0 @@
{% set docker = {
'containers': [
'so-nginx',
'so-telegraf',
'so-redis',
'so-logstash',
'so-elasticsearch',
'so-curator',
'so-steno',
'so-suricata',
'so-wazuh',
'so-filebeat',
'so-sensoroni'
]
} %}
-12
View File
@@ -1,12 +0,0 @@
{% set docker = {
'containers': [
'so-nginx',
'so-telegraf',
'so-idstools',
'so-steno',
'so-zeek',
'so-redis',
'so-logstash',
'so-filebeat
]
} %}
-9
View File
@@ -1,9 +0,0 @@
{% set docker = {
'containers': [
'so-nginx',
'so-telegraf',
'so-logstash',
'so-elasticsearch',
'so-curator',
]
} %}
-10
View File
@@ -1,10 +0,0 @@
{% set docker = {
'containers': [
'so-filebeat',
'so-nginx',
'so-soc',
'so-kratos',
'so-elasticsearch',
'so-kibana'
]
} %}
-18
View File
@@ -1,18 +0,0 @@
{% set docker = {
'containers': [
'so-dockerregistry',
'so-nginx',
'so-telegraf',
'so-soc',
'so-kratos',
'so-aptcacherng',
'so-idstools',
'so-redis',
'so-elasticsearch',
'so-logstash',
'so-kibana',
'so-elastalert',
'so-filebeat',
'so-soctopus'
]
} %}
-18
View File
@@ -1,18 +0,0 @@
{% set docker = {
'containers': [
'so-nginx',
'so-telegraf',
'so-soc',
'so-kratos',
'so-aptcacherng',
'so-idstools',
'so-redis',
'so-logstash',
'so-elasticsearch',
'so-curator',
'so-kibana',
'so-elastalert',
'so-filebeat',
'so-soctopus'
]
} %}
-5
View File
@@ -1,5 +0,0 @@
{% set docker = {
'containers': [
'so-zeek'
]
} %}
-5
View File
@@ -1,5 +0,0 @@
{% set docker = {
'containers': [
'so-playbook'
]
} %}
-10
View File
@@ -1,10 +0,0 @@
{% set docker = {
'containers': [
'so-nginx',
'so-telegraf',
'so-logstash',
'so-elasticsearch',
'so-curator',
'so-filebeat'
]
} %}
-9
View File
@@ -1,9 +0,0 @@
{% set docker = {
'containers': [
'so-telegraf',
'so-steno',
'so-suricata',
'so-filebeat',
'so-sensoroni'
]
} %}
-48
View File
@@ -1,48 +0,0 @@
{% set role = grains.id.split('_') | last %}
{% from 'common/maps/'~ role ~'.map.jinja' import docker with context %}
# Check if the service is enabled and append it's required containers
# to the list predefined by the role / minion id affix
{% macro append_containers(pillar_name, k, compare )%}
{% if salt['pillar.get'](pillar_name~':'~k, {}) != compare %}
{% if k == 'enabled' %}
{% set k = pillar_name %}
{% endif %}
{% from 'common/maps/'~k~'.map.jinja' import docker as d with context %}
{% for li in d['containers'] %}
{{ docker['containers'].append(li) }}
{% endfor %}
{% endif %}
{% endmacro %}
{% set docker = salt['grains.filter_by']({
'*_'~role: {
'containers': docker['containers']
}
},grain='id', merge=salt['pillar.get']('docker')) %}
{% if role in ['eval', 'managersearch', 'manager', 'standalone'] %}
{{ append_containers('manager', 'grafana', 0) }}
{{ append_containers('global', 'fleet_manager', 0) }}
{{ append_containers('global', 'wazuh', 0) }}
{{ append_containers('manager', 'thehive', 0) }}
{{ append_containers('manager', 'playbook', 0) }}
{{ append_containers('manager', 'freq', 0) }}
{{ append_containers('manager', 'domainstats', 0) }}
{% endif %}
{% if role in ['eval', 'heavynode', 'sensor', 'standalone'] %}
{{ append_containers('strelka', 'enabled', 0) }}
{% endif %}
{% if role in ['heavynode', 'standalone'] %}
{{ append_containers('global', 'mdengine', 'SURICATA') }}
{% endif %}
{% if role == 'searchnode' %}
{{ append_containers('manager', 'wazuh', 0) }}
{% endif %}
{% if role == 'sensor' %}
{{ append_containers('global', 'mdengine', 'SURICATA') }}
{% endif %}
-22
View File
@@ -1,22 +0,0 @@
{% set docker = {
'containers': [
'so-nginx',
'so-telegraf',
'so-soc',
'so-kratos',
'so-aptcacherng',
'so-idstools',
'so-redis',
'so-logstash',
'so-elasticsearch',
'so-curator',
'so-kibana',
'so-elastalert',
'so-filebeat',
'so-suricata',
'so-steno',
'so-dockerregistry',
'so-soctopus',
'so-sensoroni'
]
} %}
-9
View File
@@ -1,9 +0,0 @@
{% set docker = {
'containers': [
'so-strelka-coordinator',
'so-strelka-gatekeeper',
'so-strelka-manager',
'so-strelka-frontend',
'so-strelka-filestream'
]
} %}
-7
View File
@@ -1,7 +0,0 @@
{% set docker = {
'containers': [
'so-thehive',
'so-thehive-es',
'so-cortex'
]
} %}
-7
View File
@@ -1,7 +0,0 @@
{% set docker = {
'containers': [
'so-nginx',
'so-telegraf',
'so-elasticsearch'
]
} %}
-5
View File
@@ -1,5 +0,0 @@
{% set docker = {
'containers': [
'so-wazuh'
]
} %}
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
if [ ! -f /opt/so/state/dockernet.state ]; then
docker network create -d bridge so-elastic-net
touch /opt/so/state/dockernet.state
else
exit
fi
+96 -12
View File
@@ -15,12 +15,10 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
IMAGEREPO=securityonion
# Check for prerequisites # Check for prerequisites
if [ "$(id -u)" -ne 0 ]; then if [ "$(id -u)" -ne 0 ]; then
echo "This script must be run using sudo!" echo "This script must be run using sudo!"
exit 1 exit 1
fi fi
# Define a banner to separate sections # Define a banner to separate sections
@@ -31,14 +29,43 @@ header() {
printf '%s\n' "$banner" "$*" "$banner" printf '%s\n' "$banner" "$*" "$banner"
} }
lookup_salt_value() {
key=$1
group=$2
kind=$3
if [ -z "$kind" ]; then
kind=pillar
fi
if [ -n "$group" ]; then
group=${group}:
fi
salt-call --no-color ${kind}.get ${group}${key} --out=newline_values_only
}
lookup_pillar() { lookup_pillar() {
key=$1 key=$1
salt-call --no-color pillar.get global:${key} --out=newline_values_only pillar=$2
if [ -z "$pillar" ]; then
pillar=global
fi
lookup_salt_value "$key" "$pillar" "pillar"
} }
lookup_pillar_secret() { lookup_pillar_secret() {
key=$1 lookup_pillar "$1" "secrets"
salt-call --no-color pillar.get secrets:${key} --out=newline_values_only }
lookup_grain() {
lookup_salt_value "$1" "" "grains"
}
lookup_role() {
id=$(lookup_grain id)
pieces=($(echo $id | tr '_' ' '))
echo ${pieces[1]}
} }
check_container() { check_container() {
@@ -47,7 +74,64 @@ check_container() {
} }
check_password() { check_password() {
local password=$1 local password=$1
echo "$password" | egrep -v "'|\"|\\\\" > /dev/null 2>&1 echo "$password" | egrep -v "'|\"|\\$|\\\\" > /dev/null 2>&1
return $? return $?
} }
set_os() {
if [ -f /etc/redhat-release ]; then
OS=centos
else
OS=ubuntu
fi
}
set_minionid() {
MINIONID=$(lookup_grain id)
}
set_version() {
CURRENTVERSION=0.0.0
if [ -f /etc/soversion ]; then
CURRENTVERSION=$(cat /etc/soversion)
fi
if [ -z "$VERSION" ]; then
if [ -z "$NEWVERSION" ]; then
if [ "$CURRENTVERSION" == "0.0.0" ]; then
echo "ERROR: Unable to detect Security Onion version; terminating script."
exit 1
else
VERSION=$CURRENTVERSION
fi
else
VERSION="$NEWVERSION"
fi
fi
}
require_manager() {
# Check to see if this is a manager
MANAGERCHECK=$(cat /etc/salt/grains | grep role | awk '{print $2}')
if [ $MANAGERCHECK == 'so-eval' ] || [ $MANAGERCHECK == 'so-manager' ] || [ $MANAGERCHECK == 'so-managersearch' ] || [ $MANAGERCHECK == 'so-standalone' ] || [ $MANAGERCHECK == 'so-helix' ] || [ $MANAGERCHECK == 'so-import' ]; then
echo "This is a manager, We can proceed."
else
echo "Please run this command on the manager; the manager controls the grid."
exit 1
fi
}
is_single_node_grid() {
role=$(lookup_role)
if [ "$role" != "eval" ] && [ "$role" != "standalone" ] && [ "$role" != "import" ]; then
return 1
fi
return 0
}
fail() {
msg=$1
echo "ERROR: $msg"
echo "Exiting."
exit 1
}
+2 -2
View File
@@ -31,7 +31,7 @@ fi
USER=$1 USER=$1
CORTEX_KEY=$(lookup_pillar cortexkey) CORTEX_KEY=$(lookup_pillar cortexkey)
CORTEX_IP=$(lookup_pillar managerip) CORTEX_API_URL="$(lookup_pillar url_base)/cortex/api"
CORTEX_ORG_NAME=$(lookup_pillar cortexorgname) CORTEX_ORG_NAME=$(lookup_pillar cortexorgname)
CORTEX_USER=$USER CORTEX_USER=$USER
@@ -43,7 +43,7 @@ fi
read -rs CORTEX_PASS read -rs CORTEX_PASS
# Create new user in Cortex # Create new user in Cortex
resp=$(curl -sk -XPOST -H "Authorization: Bearer $CORTEX_KEY" -H "Content-Type: application/json" "https://$CORTEX_IP/cortex/api/user" -d "{\"name\": \"$CORTEX_USER\",\"roles\": [\"read\",\"analyze\",\"orgadmin\"],\"organization\": \"$CORTEX_ORG_NAME\",\"login\": \"$CORTEX_USER\",\"password\" : \"$CORTEX_PASS\" }") resp=$(curl -sk -XPOST -H "Authorization: Bearer $CORTEX_KEY" -H "Content-Type: application/json" -L "https://$CORTEX_API_URL/user" -d "{\"name\": \"$CORTEX_USER\",\"roles\": [\"read\",\"analyze\",\"orgadmin\"],\"organization\": \"$CORTEX_ORG_NAME\",\"login\": \"$CORTEX_USER\",\"password\" : \"$CORTEX_PASS\" }")
if [[ "$resp" =~ \"status\":\"Ok\" ]]; then if [[ "$resp" =~ \"status\":\"Ok\" ]]; then
echo "Successfully added user to Cortex." echo "Successfully added user to Cortex."
else else
+2 -2
View File
@@ -31,7 +31,7 @@ fi
USER=$1 USER=$1
CORTEX_KEY=$(lookup_pillar cortexkey) CORTEX_KEY=$(lookup_pillar cortexkey)
CORTEX_IP=$(lookup_pillar managerip) CORTEX_API_URL="$(lookup_pillar url_base)/cortex/api"
CORTEX_USER=$USER CORTEX_USER=$USER
case "${2^^}" in case "${2^^}" in
@@ -46,7 +46,7 @@ case "${2^^}" in
;; ;;
esac esac
resp=$(curl -sk -XPATCH -H "Authorization: Bearer $CORTEX_KEY" -H "Content-Type: application/json" "https://$CORTEX_IP/cortex/api/user/${CORTEX_USER}" -d "{\"status\":\"${CORTEX_STATUS}\" }") resp=$(curl -sk -XPATCH -H "Authorization: Bearer $CORTEX_KEY" -H "Content-Type: application/json" -L "https://$CORTEX_API_URL/user/${CORTEX_USER}" -d "{\"status\":\"${CORTEX_STATUS}\" }")
if [[ "$resp" =~ \"status\":\"Locked\" || "$resp" =~ \"status\":\"Ok\" ]]; then if [[ "$resp" =~ \"status\":\"Locked\" || "$resp" =~ \"status\":\"Ok\" ]]; then
echo "Successfully updated user in Cortex." echo "Successfully updated user in Cortex."
else else
+3 -92
View File
@@ -16,96 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
. /usr/sbin/so-common . /usr/sbin/so-common
. /usr/sbin/so-image-common
manager_check() { require_manager
# Check to see if this is a manager update_docker_containers "refresh"
MANAGERCHECK=$(cat /etc/salt/grains | grep role | awk '{print $2}')
if [ $MANAGERCHECK == 'so-eval' ] || [ $MANAGERCHECK == 'so-manager' ] || [ $MANAGERCHECK == 'so-managersearch' ] || [ $MANAGERCHECK == 'so-standalone' ] || [ $MANAGERCHECK == 'so-helix' ]; then
echo "This is a manager. We can proceed"
else
echo "Please run soup on the manager. The manager controls all updates."
exit 1
fi
}
update_docker_containers() {
# Download the containers from the interwebs
for i in "${TRUSTED_CONTAINERS[@]}"
do
# Pull down the trusted docker image
echo "Downloading $i"
docker pull --disable-content-trust=false docker.io/$IMAGEREPO/$i
# Tag it with the new registry destination
docker tag $IMAGEREPO/$i $HOSTNAME:5000/$IMAGEREPO/$i
docker push $HOSTNAME:5000/$IMAGEREPO/$i
done
}
version_check() {
if [ -f /etc/soversion ]; then
VERSION=$(cat /etc/soversion)
else
echo "Unable to detect version. I will now terminate."
exit 1
fi
}
manager_check
version_check
# Use the hostname
HOSTNAME=$(hostname)
# List all the containers
if [ $MANAGERCHECK != 'so-helix' ]; then
TRUSTED_CONTAINERS=( \
"so-acng:$VERSION" \
"so-thehive-cortex:$VERSION" \
"so-curator:$VERSION" \
"so-domainstats:$VERSION" \
"so-elastalert:$VERSION" \
"so-elasticsearch:$VERSION" \
"so-filebeat:$VERSION" \
"so-fleet:$VERSION" \
"so-fleet-launcher:$VERSION" \
"so-freqserver:$VERSION" \
"so-grafana:$VERSION" \
"so-idstools:$VERSION" \
"so-influxdb:$VERSION" \
"so-kibana:$VERSION" \
"so-kratos:$VERSION" \
"so-logstash:$VERSION" \
"so-minio:$VERSION" \
"so-mysql:$VERSION" \
"so-nginx:$VERSION" \
"so-pcaptools:$VERSION" \
"so-playbook:$VERSION" \
"so-redis:$VERSION" \
"so-soc:$VERSION" \
"so-soctopus:$VERSION" \
"so-steno:$VERSION" \
"so-strelka-frontend:$VERSION" \
"so-strelka-manager:$VERSION" \
"so-strelka-backend:$VERSION" \
"so-strelka-filestream:$VERSION" \
"so-suricata:$VERSION" \
"so-telegraf:$VERSION" \
"so-thehive:$VERSION" \
"so-thehive-es:$VERSION" \
"so-wazuh:$VERSION" \
"so-zeek:$VERSION" )
else
TRUSTED_CONTAINERS=( \
"so-filebeat:$VERSION" \
"so-idstools:$VERSION" \
"so-logstash:$VERSION" \
"so-nginx:$VERSION" \
"so-redis:$VERSION" \
"so-steno:$VERSION" \
"so-suricata:$VERSION" \
"so-telegraf:$VERSION" \
"so-zeek:$VERSION" )
fi
update_docker_containers
+67 -73
View File
@@ -19,8 +19,7 @@
# #
# Purpose: This script will allow you to test your elastalert rule without entering the Docker container. # Purpose: This script will allow you to test your elastalert rule without entering the Docker container.
. /usr/sbin/so-elastic-common HOST_RULE_DIR=/opt/so/rules/elastalert
OPTIONS="" OPTIONS=""
SKIP=0 SKIP=0
RESULTS_TO_LOG="n" RESULTS_TO_LOG="n"
@@ -29,114 +28,109 @@ FILE_SAVE_LOCATION=""
usage() usage()
{ {
cat <<EOF cat <<EOF
Test Elastalert Rule Test Elastalert Rule
Options: Options:
-h This message -h This message
-a Trigger real alerts instead of the debug alert -a Trigger real alerts instead of the debug alert
-l <path_to_file> Write results to specified log file -l <path_to_file> Write results to specified log file
-o '<options>' Specify Elastalert options ( Ex. --schema-only , --count-only, --days N ) -o '<options>' Specify Elastalert options ( Ex. --schema-only , --count-only, --days N )
-r <rule_name> Specify path/name of rule to test -r <rule_name> Specify filename of rule to test (must exist in $HOST_RULE_DIR; do not include path)
EOF EOF
} }
while getopts "hal:o:r:" OPTION while getopts "hal:o:r:" OPTION
do do
case $OPTION in case $OPTION in
h) h)
usage usage
exit 0 exit 0
;; ;;
a) a)
OPTIONS="--alert" OPTIONS="--alert"
;; ;;
l) l)
RESULTS_TO_LOG="y" RESULTS_TO_LOG="y"
FILE_SAVE_LOCATION=$OPTARG FILE_SAVE_LOCATION=$OPTARG
;; ;;
o)
o) OPTIONS=$OPTARG
OPTIONS=$OPTARG ;;
;; r)
RULE_NAME=$OPTARG
r) SKIP=1
RULE_NAME=$OPTARG ;;
SKIP=1 *)
;; usage
*) exit 0
usage ;;
exit 0 esac
;;
esac
done done
docker_exec(){ docker_exec(){
if [ ${RESULTS_TO_LOG,,} = "y" ] ; then CMD="docker exec -it so-elastalert elastalert-test-rule /opt/elastalert/rules/$RULE_NAME --config /opt/config/elastalert_config.yaml $OPTIONS"
docker exec -it so-elastalert bash -c "elastalert-test-rule $RULE_NAME $OPTIONS" > $FILE_SAVE_LOCATION if [ "${RESULTS_TO_LOG,,}" = "y" ] ; then
$CMD > "$FILE_SAVE_LOCATION"
else else
docker exec -it so-elastalert bash -c "elastalert-test-rule $RULE_NAME $OPTIONS" $CMD
fi fi
} }
rule_prompt(){ rule_prompt(){
CURRENT_RULES=$(find /opt/so/rules/elastalert -name "*.yaml") CURRENT_RULES=$(cd "$HOST_RULE_DIR" && find . -type f \( -name "*.yaml" -o -name "*.yml" \) | sed -e 's/^\.\///')
echo if [ -z "$CURRENT_RULES" ]; then
echo "This script will allow you to test an Elastalert rule." echo "There are no rules available to test. Rule files must be placed in the $HOST_RULE_DIR directory."
echo exit 1
echo "Below is a list of active Elastalert rules:" fi
echo echo
echo "This script will allow you to test an Elastalert rule."
echo
echo "Below is a list of available Elastalert rules:"
echo
echo "-----------------------------------" echo "-----------------------------------"
echo echo
echo "$CURRENT_RULES" echo "$CURRENT_RULES"
echo echo
echo "-----------------------------------" echo "-----------------------------------"
echo echo
echo "Note: To test a rule it must be accessible by the Elastalert Docker container." while [ -z "$RULE_NAME" ]; do
echo read -p "Please enter the rule filename you want to test (filename only, no path): " -e RULE_NAME
echo "Make sure to swap the local path (/opt/so/rules/elastalert/) for the docker path (/etc/elastalert/rules/)"
echo "Example: /opt/so/rules/elastalert/nids2hive.yaml would be /etc/elastalert/rules/nids2hive.yaml"
echo
while [ -z $RULE_NAME ]; do
echo "Please enter the file path and rule name you want to test."
read -e RULE_NAME
done done
} }
log_save_prompt(){ log_save_prompt(){
RESULTS_TO_LOG="" RESULTS_TO_LOG=""
while [ -z $RESULTS_TO_LOG ]; do read -p "The results can be rather long. Would you like to write the results to a file? (y/N) " -e RESULTS_TO_LOG
echo "The results can be rather long. Would you like to write the results to a file? (Y/N)"
read RESULTS_TO_LOG
done
} }
log_path_prompt(){ log_path_prompt(){
while [ -z $FILE_SAVE_LOCATION ]; do while [ -z "$FILE_SAVE_LOCATION" ]; do
echo "Please enter the file path and file name." read -p "Please enter the log file path and file name: " -e FILE_SAVE_LOCATION
read -e FILE_SAVE_LOCATION done
done
echo "Depending on the rule this may take a while." echo "Depending on the rule this may take a while."
} }
if [ $SKIP -eq 0 ]; then if [ $SKIP -eq 0 ]; then
rule_prompt rule_prompt
log_save_prompt log_save_prompt
if [ ${RESULTS_TO_LOG,,} = "y" ] ; then if [ "${RESULTS_TO_LOG,,}" = "y" ] ; then
log_path_prompt log_path_prompt
fi fi
fi fi
echo
docker_exec docker_exec
RESULT=$?
if [ $? -eq 0 ]; then
echo "Test completed successfully!"
else
echo "Something went wrong..."
fi
echo echo
if [ $RESULT -eq 0 ]; then
echo "Test completed successfully!"
else
echo "Test failed."
fi
echo
+15 -3
View File
@@ -50,7 +50,11 @@ done
if [ $SKIP -ne 1 ]; then if [ $SKIP -ne 1 ]; then
# List indices # List indices
echo echo
curl {{ NODEIP }}:9200/_cat/indices?v {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -k -L https://{{ NODEIP }}:9200/_cat/indices?v
{% else %}
curl -L {{ NODEIP }}:9200/_cat/indices?v
{% endif %}
echo echo
# Inform user we are about to delete all data # Inform user we are about to delete all data
echo echo
@@ -89,10 +93,18 @@ fi
# Delete data # Delete data
echo "Deleting data..." echo "Deleting data..."
INDXS=$(curl -s -XGET {{ NODEIP }}:9200/_cat/indices?v | egrep 'logstash|elastalert|so-' | awk '{ print $3 }') {% if grains['role'] in ['so-node','so-heavynode'] %}
INDXS=$(curl -s -XGET -k -L https://{{ NODEIP }}:9200/_cat/indices?v | egrep 'logstash|elastalert|so-' | awk '{ print $3 }')
{% else %}
INDXS=$(curl -s -XGET -L {{ NODEIP }}:9200/_cat/indices?v | egrep 'logstash|elastalert|so-' | awk '{ print $3 }')
{% endif %}
for INDX in ${INDXS} for INDX in ${INDXS}
do do
curl -XDELETE "{{ NODEIP }}:9200/${INDX}" > /dev/null 2>&1 {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -XDELETE -k -L https://"{{ NODEIP }}:9200/${INDX}" > /dev/null 2>&1
{% else %}
curl -XDELETE -L "{{ NODEIP }}:9200/${INDX}" > /dev/null 2>&1
{% endif %}
done done
#Start Logstash/Filebeat #Start Logstash/Filebeat
@@ -22,5 +22,5 @@ THEHIVEESPORT=9400
echo "Removing read only attributes for indices..." echo "Removing read only attributes for indices..."
echo echo
for p in $ESPORT $THEHIVEESPORT; do for p in $ESPORT $THEHIVEESPORT; do
curl -XPUT -H "Content-Type: application/json" http://$IP:$p/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}' 2>&1 | if grep -q ack; then echo "Index settings updated..."; else echo "There was any issue updating the read-only attribute. Please ensure Elasticsearch is running.";fi; curl -XPUT -H "Content-Type: application/json" -L http://$IP:$p/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}' 2>&1 | if grep -q ack; then echo "Index settings updated..."; else echo "There was any issue updating the read-only attribute. Please ensure Elasticsearch is running.";fi;
done done
@@ -19,7 +19,15 @@
. /usr/sbin/so-common . /usr/sbin/so-common
if [ "$1" == "" ]; then if [ "$1" == "" ]; then
curl -s {{ NODEIP }}:9200/_nodes/stats | jq .nodes | jq ".[] | .ingest.pipelines" {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -s -k -L https://{{ NODEIP }}:9200/_nodes/stats | jq .nodes | jq ".[] | .ingest.pipelines"
{% else %}
curl -s -L {{ NODEIP }}:9200/_nodes/stats | jq .nodes | jq ".[] | .ingest.pipelines"
{% endif %}
else else
curl -s {{ NODEIP }}:9200/_nodes/stats | jq .nodes | jq ".[] | .ingest.pipelines.\"$1\"" {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -s -k -L https://{{ NODEIP }}:9200/_nodes/stats | jq .nodes | jq ".[] | .ingest.pipelines.\"$1\""
{% else %}
curl -s -L {{ NODEIP }}:9200/_nodes/stats | jq .nodes | jq ".[] | .ingest.pipelines.\"$1\""
{% endif %}
fi fi
@@ -17,7 +17,15 @@
{%- set NODEIP = salt['pillar.get']('elasticsearch:mainip', '') -%} {%- set NODEIP = salt['pillar.get']('elasticsearch:mainip', '') -%}
. /usr/sbin/so-common . /usr/sbin/so-common
if [ "$1" == "" ]; then if [ "$1" == "" ]; then
curl -s {{ NODEIP }}:9200/_ingest/pipeline/* | jq 'keys' {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -s -k -L https://{{ NODEIP }}:9200/_ingest/pipeline/* | jq 'keys'
{% else %}
curl -s -L {{ NODEIP }}:9200/_ingest/pipeline/* | jq 'keys'
{% endif %}
else else
curl -s {{ NODEIP }}:9200/_ingest/pipeline/$1 | jq {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -s -k -L https://{{ NODEIP }}:9200/_ingest/pipeline/$1 | jq
{% else %}
curl -s -L {{ NODEIP }}:9200/_ingest/pipeline/$1 | jq
{% endif %}
fi fi
@@ -18,10 +18,14 @@
. /usr/sbin/so-common . /usr/sbin/so-common
if [ "$1" == "" ]; then if [ "$1" == "" ]; then
{% if grains['role'] in ['so-node','so-heavynode'] %} {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -s -k kttps://{{ NODEIP }}:9200/_template/* | jq 'keys' curl -s -k -L https://{{ NODEIP }}:9200/_template/* | jq 'keys'
{% else %} {% else %}
curl -s {{ NODEIP }}:9200/_template/* | jq 'keys' curl -s -L {{ NODEIP }}:9200/_template/* | jq 'keys'
{% endif %} {% endif %}
else else
curl -s {{ NODEIP }}:9200/_template/$1 | jq {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -s -k -L https://{{ NODEIP }}:9200/_template/$1 | jq
{% else %}
curl -s -L {{ NODEIP }}:9200/_template/$1 | jq
{% endif %}
fi fi
@@ -31,9 +31,9 @@ COUNT=0
ELASTICSEARCH_CONNECTED="no" ELASTICSEARCH_CONNECTED="no"
while [[ "$COUNT" -le 240 ]]; do while [[ "$COUNT" -le 240 ]]; do
{% if grains['role'] in ['so-node','so-heavynode'] %} {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -k --output /dev/null --silent --head --fail https://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT" curl -k --output /dev/null --silent --head --fail -L https://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT"
{% else %} {% else %}
curl --output /dev/null --silent --head --fail http://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT" curl --output /dev/null --silent --head --fail -L http://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT"
{% endif %} {% endif %}
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
ELASTICSEARCH_CONNECTED="yes" ELASTICSEARCH_CONNECTED="yes"
@@ -55,7 +55,11 @@ cd ${ELASTICSEARCH_TEMPLATES}
echo "Loading templates..." echo "Loading templates..."
for i in *; do TEMPLATE=$(echo $i | cut -d '-' -f2); echo "so-$TEMPLATE"; curl ${ELASTICSEARCH_AUTH} -s -XPUT http://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_template/so-$TEMPLATE -H 'Content-Type: application/json' -d@$i 2>/dev/null; echo; done {% if grains['role'] in ['so-node','so-heavynode'] %}
for i in *; do TEMPLATE=$(echo $i | cut -d '-' -f2); echo "so-$TEMPLATE"; curl -k ${ELASTICSEARCH_AUTH} -s -XPUT -L https://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_template/so-$TEMPLATE -H 'Content-Type: application/json' -d@$i 2>/dev/null; echo; done
{% else %}
for i in *; do TEMPLATE=$(echo $i | cut -d '-' -f2); echo "so-$TEMPLATE"; curl ${ELASTICSEARCH_AUTH} -s -XPUT -L http://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_template/so-$TEMPLATE -H 'Content-Type: application/json' -d@$i 2>/dev/null; echo; done
{% endif %}
echo echo
cd - >/dev/null cd - >/dev/null
+9 -28
View File
@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
. /usr/sbin/so-common . /usr/sbin/so-common
. /usr/sbin/so-image-common
local_salt_dir=/opt/so/saltstack/local local_salt_dir=/opt/so/saltstack/local
cat << EOF cat << EOF
@@ -39,34 +40,14 @@ fi
echo "Please wait while switching to Elastic Features." echo "Please wait while switching to Elastic Features."
manager_check() { require_manager
# Check to see if this is a manager
MANAGERCHECK=$(cat /etc/salt/grains | grep role | awk '{print $2}') TRUSTED_CONTAINERS=( \
if [[ "$MANAGERCHECK" =~ ^('so-eval'|'so-manager'|'so-standalone'|'so-managersearch')$ ]]; then "so-elasticsearch" \
echo "This is a manager. We can proceed" "so-filebeat" \
else "so-kibana" \
echo "Please run so-features-enable on the manager." "so-logstash" )
exit 0 update_docker_containers "features" "-features"
fi
}
manager_check
VERSION=$(grep soversion $local_salt_dir/pillar/global.sls | cut -d':' -f2|sed 's/ //g')
# Modify global.sls to enable Features # Modify global.sls to enable Features
sed -i 's/features: False/features: True/' $local_salt_dir/pillar/global.sls sed -i 's/features: False/features: True/' $local_salt_dir/pillar/global.sls
SUFFIX="-features"
TRUSTED_CONTAINERS=( \
"so-elasticsearch:$VERSION$SUFFIX" \
"so-filebeat:$VERSION$SUFFIX" \
"so-kibana:$VERSION$SUFFIX" \
"so-logstash:$VERSION$SUFFIX" )
for i in "${TRUSTED_CONTAINERS[@]}"
do
# Pull down the trusted docker image
echo "Downloading $i"
docker pull --disable-content-trust=false docker.io/$IMAGEREPO/$i
# Tag it with the new registry destination
docker tag $IMAGEREPO/$i $HOSTNAME:5000/$IMAGEREPO/$i
docker push $HOSTNAME:5000/$IMAGEREPO/$i
done
+1 -1
View File
@@ -116,7 +116,7 @@ def addhostgroup(args):
print('Missing host group name argument', file=sys.stderr) print('Missing host group name argument', file=sys.stderr)
showUsage(args) showUsage(args)
name = args[1] name = args[0]
content = loadYaml(hostgroupsFilename) content = loadYaml(hostgroupsFilename)
if name in content['firewall']['hostgroups']: if name in content['firewall']['hostgroups']:
print('Already exists', file=sys.stderr) print('Already exists', file=sys.stderr)
+3 -3
View File
@@ -26,9 +26,9 @@ docker exec so-fleet /bin/sh -c 'for pack in /packs/palantir/Fleet/Endpoints/pac
docker exec so-fleet fleetctl apply -f /packs/osquery-config.conf docker exec so-fleet fleetctl apply -f /packs/osquery-config.conf
# Enable Fleet # Update the Enroll Secret
echo "Enabling Fleet..." echo "Updating the Enroll Secret..."
salt-call state.apply fleet.event_enable-fleet queue=True >> /root/fleet-setup.log salt-call state.apply fleet.event_update-enroll-secret queue=True >> /root/fleet-setup.log
salt-call state.apply nginx queue=True >> /root/fleet-setup.log salt-call state.apply nginx queue=True >> /root/fleet-setup.log
# Generate osquery install packages # Generate osquery install packages
+4 -4
View File
@@ -48,7 +48,7 @@ fi
FLEET_HASH=$(docker exec so-soctopus python -c "import bcrypt; print(bcrypt.hashpw('$FLEET_PASS'.encode('utf-8'), bcrypt.gensalt()).decode('utf-8'));" 2>&1) FLEET_HASH=$(docker exec so-soctopus python -c "import bcrypt; print(bcrypt.hashpw('$FLEET_PASS'.encode('utf-8'), bcrypt.gensalt()).decode('utf-8'));" 2>&1)
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
echo "Failed to generate Fleet password hash." echo "Failed to generate Fleet password hash"
exit 2 exit 2
fi fi
@@ -56,9 +56,9 @@ MYSQL_OUTPUT=$(docker exec so-mysql mysql -u root --password=$MYSQL_PASS fleet -
"INSERT INTO users (password,salt,username,email,admin,enabled) VALUES ('$FLEET_HASH','','$FLEET_USER','$FLEET_USER',1,1)" 2>&1) "INSERT INTO users (password,salt,username,email,admin,enabled) VALUES ('$FLEET_HASH','','$FLEET_USER','$FLEET_USER',1,1)" 2>&1)
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
echo "Successfully added user to Fleet." echo "Successfully added user to Fleet"
else else
echo "Unable to add user to Fleet; user might already exist." echo "Unable to add user to Fleet; user might already exist"
echo $resp echo "$MYSQL_OUTPUT"
exit 2 exit 2
fi fi
+3 -3
View File
@@ -20,7 +20,7 @@
usage() { usage() {
echo "Usage: $0 <user-name>" echo "Usage: $0 <user-name>"
echo "" echo ""
echo "Enables or disables a user in Fleet." echo "Enables or disables a user in Fleet"
exit 1 exit 1
} }
@@ -50,9 +50,9 @@ MYSQL_OUTPUT=$(docker exec so-mysql mysql -u root --password=$MYSQL_PASS fleet -
"UPDATE users SET enabled=$FLEET_STATUS WHERE username='$FLEET_USER'" 2>&1) "UPDATE users SET enabled=$FLEET_STATUS WHERE username='$FLEET_USER'" 2>&1)
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
echo "Successfully updated user in Fleet." echo "Successfully updated user in Fleet"
else else
echo "Failed to update user in Fleet." echo "Failed to update user in Fleet"
echo $resp echo $resp
exit 2 exit 2
fi fi
+175
View File
@@ -0,0 +1,175 @@
#!/bin/bash
#
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# NOTE: This script depends on so-common
IMAGEREPO=securityonion
container_list() {
MANAGERCHECK=$1
if [ -z "$MANAGERCHECK" ]; then
MANAGERCHECK=so-unknown
if [ -f /etc/salt/grains ]; then
MANAGERCHECK=$(cat /etc/salt/grains | grep role | awk '{print $2}')
fi
fi
if [ $MANAGERCHECK == 'so-import' ]; then
TRUSTED_CONTAINERS=( \
"so-elasticsearch" \
"so-filebeat" \
"so-idstools" \
"so-kibana" \
"so-kratos" \
"so-nginx" \
"so-pcaptools" \
"so-soc" \
"so-steno" \
"so-suricata" \
"so-zeek" )
elif [ $MANAGERCHECK != 'so-helix' ]; then
TRUSTED_CONTAINERS=( \
"so-acng" \
"so-curator" \
"so-domainstats" \
"so-elastalert" \
"so-elasticsearch" \
"so-filebeat" \
"so-fleet" \
"so-fleet-launcher" \
"so-freqserver" \
"so-grafana" \
"so-idstools" \
"so-influxdb" \
"so-kibana" \
"so-kratos" \
"so-logstash" \
"so-minio" \
"so-mysql" \
"so-nginx" \
"so-pcaptools" \
"so-playbook" \
"so-redis" \
"so-soc" \
"so-soctopus" \
"so-steno" \
"so-strelka-backend" \
"so-strelka-filestream" \
"so-strelka-frontend" \
"so-strelka-manager" \
"so-suricata" \
"so-telegraf" \
"so-thehive" \
"so-thehive-cortex" \
"so-thehive-es" \
"so-wazuh" \
"so-zeek" )
else
TRUSTED_CONTAINERS=( \
"so-filebeat" \
"so-idstools" \
"so-logstash" \
"so-nginx" \
"so-redis" \
"so-steno" \
"so-suricata" \
"so-telegraf" \
"so-zeek" )
fi
}
update_docker_containers() {
local CURLTYPE=$1
local IMAGE_TAG_SUFFIX=$2
local PROGRESS_CALLBACK=$3
local LOG_FILE=$4
local CONTAINER_REGISTRY=quay.io
local SIGNPATH=/root/sosigs
if [ -z "$CURLTYPE" ]; then
CURLTYPE=unknown
fi
if [ -z "$LOG_FILE" ]; then
if [ -c /dev/tty ]; then
LOG_FILE=/dev/tty
else
LOG_FILE=/dev/null
fi
fi
# Recheck the version for scenarios were the VERSION wasn't known before this script was imported
set_version
set_os
if [ -z "$TRUSTED_CONTAINERS" ]; then
container_list
fi
# Let's make sure we have the public key
curl -sSL https://raw.githubusercontent.com/Security-Onion-Solutions/securityonion/master/KEYS | gpg --import - >> "$LOG_FILE" 2>&1
rm -rf $SIGNPATH >> "$LOG_FILE" 2>&1
mkdir -p $SIGNPATH >> "$LOG_FILE" 2>&1
# Download the containers from the interwebs
for i in "${TRUSTED_CONTAINERS[@]}"
do
if [ -z "$PROGRESS_CALLBACK" ]; then
echo "Downloading $i" >> "$LOG_FILE" 2>&1
else
$PROGRESS_CALLBACK $i
fi
# Pull down the trusted docker image
local image=$i:$VERSION$IMAGE_TAG_SUFFIX
docker pull $CONTAINER_REGISTRY/$IMAGEREPO/$image >> "$LOG_FILE" 2>&1
# Get signature
curl -A "$CURLTYPE/$CURRENTVERSION/$OS/$(uname -r)" https://sigs.securityonion.net/$VERSION/$i:$VERSION$IMAGE_TAG_SUFFIX.sig --output $SIGNPATH/$image.sig >> "$LOG_FILE" 2>&1
if [[ $? -ne 0 ]]; then
echo "Unable to pull signature file for $image" >> "$LOG_FILE" 2>&1
exit 1
fi
# Dump our hash values
DOCKERINSPECT=$(docker inspect $CONTAINER_REGISTRY/$IMAGEREPO/$image)
echo "$DOCKERINSPECT" | jq ".[0].RepoDigests[] | select(. | contains(\"$CONTAINER_REGISTRY\"))" > $SIGNPATH/$image.txt
echo "$DOCKERINSPECT" | jq ".[0].Created, .[0].RootFS.Layers" >> $SIGNPATH/$image.txt
if [[ $? -ne 0 ]]; then
echo "Unable to inspect $image" >> "$LOG_FILE" 2>&1
exit 1
fi
GPGTEST=$(gpg --verify $SIGNPATH/$image.sig $SIGNPATH/$image.txt 2>&1)
if [[ $? -eq 0 ]]; then
if [[ -z "$SKIP_TAGPUSH" ]]; then
# Tag it with the new registry destination
if [ -z "$HOSTNAME" ]; then
HOSTNAME=$(hostname)
fi
docker tag $CONTAINER_REGISTRY/$IMAGEREPO/$image $HOSTNAME:5000/$IMAGEREPO/$image >> "$LOG_FILE" 2>&1
docker push $HOSTNAME:5000/$IMAGEREPO/$image >> "$LOG_FILE" 2>&1
fi
else
echo "There is a problem downloading the $image image. Details: " >> "$LOG_FILE" 2>&1
echo "" >> "$LOG_FILE" 2>&1
echo $GPGTEST >> "$LOG_FILE" 2>&1
exit 1
fi
done
}
+1 -2
View File
@@ -27,8 +27,7 @@ function usage {
cat << EOF cat << EOF
Usage: $0 <pcap-file-1> [pcap-file-2] [pcap-file-N] Usage: $0 <pcap-file-1> [pcap-file-2] [pcap-file-N]
Imports one or more PCAP files onto a sensor node. The PCAP traffic will be analyzed and Imports one or more PCAP files onto a sensor node. The PCAP traffic will be analyzed and made available for review in the Security Onion toolset.
made available for review in the Security Onion toolset.
EOF EOF
} }
+5 -1
View File
@@ -15,4 +15,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
curl -X GET "localhost:9200/_cat/indices?v" {% if grains['role'] in ['so-node','so-heavynode'] %}
curl -X GET -k -L https://localhost:9200/_cat/indices?v
{% else %}
curl -X GET -L localhost:9200/_cat/indices?v
{% endif %}
+63
View File
@@ -0,0 +1,63 @@
#!/bin/bash
. $(dirname $0)/so-common
if [ "$FORCE_IP_UPDATE" != "1" ]; then
is_single_node_grid || fail "Cannot update the IP on a distributed grid"
fi
echo "This tool will update a manager's IP address to the new IP assigned to the management network interface."
echo
echo "WARNING: This tool is still undergoing testing, use at your own risk!"
echo
if [ -z "$OLD_IP" ]; then
OLD_IP=$(lookup_pillar "managerip")
if [ -z "$OLD_IP" ]; then
fail "Unable to find old IP; possible salt system failure"
fi
echo "Found old IP $OLD_IP."
fi
if [ -z "$NEW_IP" ]; then
iface=$(lookup_pillar "mainint" "host")
NEW_IP=$(ip -4 addr list $iface | grep inet | cut -d' ' -f6 | cut -d/ -f1)
if [ -z "$NEW_IP" ]; then
fail "Unable to detect new IP on interface $iface. "
fi
echo "Detected new IP $NEW_IP on interface $iface."
fi
if [ "$OLD_IP" == "$NEW_IP" ]; then
fail "IP address has not changed"
fi
echo "About to change old IP $OLD_IP to new IP $NEW_IP."
echo
read -n 1 -p "Would you like to continue? (y/N) " CONTINUE
echo
if [ "$CONTINUE" == "y" ]; then
for file in $(grep -rlI $OLD_IP /opt/so/saltstack /etc); do
echo "Updating file: $file"
sed -i "s|$OLD_IP|$NEW_IP|g" $file
done
echo "The IP has been changed from $OLD_IP to $NEW_IP."
echo
read -n 1 -p "The system must reboot to ensure all services have restarted with the new configuration. Reboot now? (y/N)" CONTINUE
echo
if [ "$CONTINUE" == "y" ]; then
reboot
fi
else
echo "Exiting without changes."
fi
@@ -23,7 +23,7 @@
KIBANA_HOST={{ MANAGER }} KIBANA_HOST={{ MANAGER }}
KSO_PORT=5601 KSO_PORT=5601
OUTFILE="saved_objects.ndjson" OUTFILE="saved_objects.ndjson"
curl -s -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -XPOST $KIBANA_HOST:$KSO_PORT/api/saved_objects/_export -d '{ "type": [ "index-pattern", "config", "visualization", "dashboard", "search" ], "excludeExportDetails": false }' > $OUTFILE curl -s -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -XPOST -L $KIBANA_HOST:$KSO_PORT/api/saved_objects/_export -d '{ "type": [ "index-pattern", "config", "visualization", "dashboard", "search" ], "excludeExportDetails": false }' > $OUTFILE
# Clean up using PLACEHOLDER # Clean up using PLACEHOLDER
sed -i "s/$KIBANA_HOST/PLACEHOLDER/g" $OUTFILE sed -i "s/$KIBANA_HOST/PLACEHOLDER/g" $OUTFILE
+18
View File
@@ -0,0 +1,18 @@
#!/bin/bash
#
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
$(dirname $0)/so-import-pcap $@
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
#
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
. /usr/sbin/so-common
salt-call state.apply playbook.db_init,playbook,playbook.automation_user_create
/usr/sbin/so-soctopus-restart
echo "Importing Plays - this will take some time...."
wait 5
/usr/sbin/so-playbook-ruleupdate
+104
View File
@@ -0,0 +1,104 @@
{% import_yaml 'salt/minion.defaults.yaml' as SALT_MINION_DEFAULTS -%}
#!/bin/bash
#
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# this script checks the time the file /opt/so/log/salt/state-apply-test was last modified and restarts the salt-minion service if it is outside a threshold date/time
# the file is modified via file.touch using a scheduled job healthcheck.salt-minion.state-apply-test that runs a state.apply.
# by default the file should be updated every 5-8 minutes.
# this allows us to test that the minion is able apply states and communicate with the master
# if the file is unable to be touched via the state.apply, then we assume there is a possibilty that the minion is hung (though it could be possible the master is down as well)
# we then stop the service, pkill salt-minion, the start the salt-minion service back up
. /usr/sbin/so-common
QUIET=false
UPTIME_REQ=1800 #in seconds, how long the box has to be up before considering restarting salt-minion due to /opt/so/log/salt/state-apply-test not being touched
CURRENT_TIME=$(date +%s)
SYSTEM_START_TIME=$(date -d "$(</proc/uptime awk '{print $1}') seconds ago" +%s)
LAST_HIGHSTATE_END=$([ -e "/opt/so/log/salt/lasthighstate" ] && date -r /opt/so/log/salt/lasthighstate +%s || echo 0)
LAST_HEALTHCHECK_STATE_APPLY=$([ -e "/opt/so/log/salt/state-apply-test" ] && date -r /opt/so/log/salt/state-apply-test +%s || echo 0)
# SETTING THRESHOLD TO ANYTHING UNDER 600 seconds may cause a lot of salt-minion restarts since the job to touch the file occurs every 5-8 minutes by default
THRESHOLD={{SALT_MINION_DEFAULTS.salt.minion.check_threshold}} #within how many seconds the file /opt/so/log/salt/state-apply-test must have been touched/modified before the salt minion is restarted
THRESHOLD_DATE=$((LAST_HEALTHCHECK_STATE_APPLY+THRESHOLD))
logCmd() {
cmd=$1
info "Executing command: $cmd"
$cmd >> "/opt/so/log/salt/so-salt-minion-check"
}
log() {
msg=$1
level=${2:-I}
now=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ")
if ! $QUIET; then
echo $msg
fi
echo -e "$now | $level | $msg" >> "/opt/so/log/salt/so-salt-minion-check" 2>&1
}
error() {
log "$1" "E"
}
info() {
log "$1" "I"
}
usage()
{
cat <<EOF
Check health of salt-minion and restart it if needed
Options:
-h This message
-q Don't output to terminal
EOF
}
while getopts ":q" opt; do
case "$opt" in
q )
QUIET=true
;;
* ) usage
exit 0
;;
esac
done
log "running so-salt-minion-check"
if [ $CURRENT_TIME -ge $((SYSTEM_START_TIME+$UPTIME_REQ)) ]; then
if [ $THRESHOLD_DATE -le $CURRENT_TIME ]; then
log "salt-minion is unable to apply states" E
log "/opt/so/log/salt/healthcheck-state-apply not touched by required date: `date -d @$THRESHOLD_DATE`, last touched: `date -d @$LAST_HEALTHCHECK_STATE_APPLY`" I
log "last highstate completed at `date -d @$LAST_HIGHSTATE_END`" I
log "checking if any jobs are running" I
logCmd "salt-call --local saltutil.running" I
log "killing all salt-minion processes" I
logCmd "pkill -9 -ef /usr/bin/salt-minion" I
log "starting salt-minion service" I
logCmd "systemctl start salt-minion" I
else
log "/opt/so/log/salt/healthcheck-state-apply last touched: `date -d @$LAST_HEALTHCHECK_STATE_APPLY` must be touched by `date -d @$THRESHOLD_DATE` to avoid salt-minion restart" I
fi
else
log "system uptime only $((CURRENT_TIME-SYSTEM_START_TIME)) seconds does not meet $UPTIME_REQ second requirement." I
fi
+93
View File
@@ -0,0 +1,93 @@
#!/bin/bash
. /usr/sbin/so-common
if [[ $1 =~ ^(-q|--quiet) ]]; then
quiet=true
fi
before=
after=
reload_required=false
print_sshd_t() {
local string=$1
local state=$2
echo "${state}:"
local grep_out
grep_out=$(sshd -T | grep "^${string}")
if [[ $state == "Before" ]]; then
before=$grep_out
else
after=$grep_out
fi
echo $grep_out
}
print_msg() {
local msg=$1
if ! [[ $quiet ]]; then
printf "%s\n" \
"----" \
"$msg" \
"----" \
""
fi
}
if ! [[ $quiet ]]; then print_sshd_t "ciphers" "Before"; fi
sshd -T | grep "^ciphers" | sed -e "s/\(3des-cbc\|aes128-cbc\|aes192-cbc\|aes256-cbc\|arcfour\|arcfour128\|arcfour256\|blowfish-cbc\|cast128-cbc\|rijndael-cbc@lysator.liu.se\)\,\?//g" >> /etc/ssh/sshd_config
if ! [[ $quiet ]]; then
print_sshd_t "ciphers" "After"
echo ""
fi
if [[ $before != $after ]]; then
reload_required=true
fi
if ! [[ $quiet ]]; then print_sshd_t "kexalgorithms" "Before"; fi
sshd -T | grep "^kexalgorithms" | sed -e "s/\(diffie-hellman-group14-sha1\|ecdh-sha2-nistp256\|diffie-hellman-group-exchange-sha256\|diffie-hellman-group1-sha1\|diffie-hellman-group-exchange-sha1\|ecdh-sha2-nistp521\|ecdh-sha2-nistp384\)\,\?//g" >> /etc/ssh/sshd_config
if ! [[ $quiet ]]; then
print_sshd_t "kexalgorithms" "After"
echo ""
fi
if [[ $before != $after ]]; then
reload_required=true
fi
if ! [[ $quiet ]]; then print_sshd_t "macs" "Before"; fi
sshd -T | grep "^macs" | sed -e "s/\(hmac-sha2-512,\|umac-128@openssh.com,\|hmac-sha2-256,\|umac-64@openssh.com,\|hmac-sha1,\|hmac-sha1-etm@openssh.com,\|umac-64-etm@openssh.com,\|hmac-sha1\)//g" >> /etc/ssh/sshd_config
if ! [[ $quiet ]]; then
print_sshd_t "macs" "After"
echo ""
fi
if [[ $before != $after ]]; then
reload_required=true
fi
if ! [[ $quiet ]]; then print_sshd_t "hostkeyalgorithms" "Before"; fi
sshd -T | grep "^hostkeyalgorithms" | sed "s|ecdsa-sha2-nistp256,||g" | sed "s|ssh-rsa,||g" >> /etc/ssh/sshd_config
if ! [[ $quiet ]]; then
print_sshd_t "hostkeyalgorithms" "After"
echo ""
fi
if [[ $before != $after ]]; then
reload_required=true
fi
if [[ $reload_required == true ]]; then
print_msg "Reloading sshd to load config changes..."
systemctl reload sshd
fi
{% if grains['os'] != 'CentOS' %}
print_msg "[ WARNING ] Any new ssh sessions will need to remove and reaccept the ECDSA key for this server before reconnecting."
{% endif %}
+50 -23
View File
@@ -14,8 +14,6 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
{%- from 'common/maps/so-status.map.jinja' import docker with context %}
{%- set container_list = docker['containers'] | sort | unique %}
if ! [ "$(id -u)" = 0 ]; then if ! [ "$(id -u)" = 0 ]; then
echo "This command must be run as root" echo "This command must be run as root"
@@ -23,14 +21,24 @@ if ! [ "$(id -u)" = 0 ]; then
fi fi
# Constants # Constants
SYSTEM_START_TIME=$(date -d "$(</proc/uptime awk '{print $1}') seconds ago" +%s)
# file populated by salt.lasthighstate state at end of successful highstate run
LAST_HIGHSTATE_END=$([ -e "/opt/so/log/salt/lasthighstate" ] && date -r /opt/so/log/salt/lasthighstate +%s || echo 0)
HIGHSTATE_RUNNING=$(salt-call --local saltutil.running --out=json | jq -r '.local[].fun' | grep -q 'state.highstate' && echo $?)
ERROR_STRING="ERROR" ERROR_STRING="ERROR"
SUCCESS_STRING="OK" SUCCESS_STRING="OK"
PENDING_STRING="PENDING" PENDING_STRING="PENDING"
MISSING_STRING='MISSING' MISSING_STRING='MISSING'
DISABLED_STRING='DISABLED'
WAIT_START_STRING='WAIT_START'
STARTING_STRING='STARTING'
CALLER=$(ps -o comm= $PPID) CALLER=$(ps -o comm= $PPID)
declare -a BAD_STATUSES=("removing" "paused" "exited" "dead") declare -a BAD_STATUSES=("removing" "paused" "exited" "dead")
declare -a PENDING_STATUSES=("paused" "created" "restarting") declare -a PENDING_STATUSES=("paused" "created" "restarting")
declare -a GOOD_STATUSES=("running") declare -a GOOD_STATUSES=("running")
declare -a DISABLED_CONTAINERS=()
mapfile -t DISABLED_CONTAINERS < <(sort -u /opt/so/conf/so-status/so-status.conf | grep "^\s*#" | tr -d "#")
declare -a temp_container_name_list=() declare -a temp_container_name_list=()
declare -a temp_container_state_list=() declare -a temp_container_state_list=()
@@ -72,9 +80,9 @@ compare_lists() {
# {% endraw %} # {% endraw %}
create_expected_container_list() { create_expected_container_list() {
{% for item in container_list -%}
expected_container_list+=("{{ item }}") mapfile -t expected_container_list < <(sort -u /opt/so/conf/so-status/so-status.conf | tr -d "#")
{% endfor -%}
} }
populate_container_lists() { populate_container_lists() {
@@ -104,46 +112,67 @@ populate_container_lists() {
parse_status() { parse_status() {
local container_state=${1} local container_state=${1}
local service_name=${2}
[[ $container_state = "missing" ]] && printf $MISSING_STRING && return 1
for state in "${GOOD_STATUSES[@]}"; do for state in "${GOOD_STATUSES[@]}"; do
[[ $container_state = "$state" ]] && printf $SUCCESS_STRING && return 0 [[ $container_state = "$state" ]] && printf $SUCCESS_STRING && return 0
done done
for state in "${PENDING_STATUSES[@]}"; do
[[ $container_state = "$state" ]] && printf $PENDING_STRING && return 0
done
# This is technically not needed since the default is error state
for state in "${BAD_STATUSES[@]}"; do for state in "${BAD_STATUSES[@]}"; do
[[ $container_state = "$state" ]] && printf $ERROR_STRING && return 1 [[ " ${DISABLED_CONTAINERS[@]} " =~ " ${service_name} " ]] && printf $DISABLED_STRING && return 0
done done
printf $ERROR_STRING && return 1 # if a highstate has finished running since the system has started
# then the containers should be running so let's check the status
if [ $LAST_HIGHSTATE_END -ge $SYSTEM_START_TIME ]; then
[[ $container_state = "missing" ]] && printf $MISSING_STRING && return 1
for state in "${PENDING_STATUSES[@]}"; do
[[ $container_state = "$state" ]] && printf $PENDING_STRING && return 0
done
# This is technically not needed since the default is error state
for state in "${BAD_STATUSES[@]}"; do
[[ $container_state = "$state" ]] && printf $ERROR_STRING && return 1
done
printf $ERROR_STRING && return 1
# if a highstate has not run since system start time, but a highstate is currently running
# then show that the containers are STARTING
elif [[ "$HIGHSTATE_RUNNING" == 0 ]]; then
printf $STARTING_STRING && return 0
# if a highstate has not finished running since system startup and isn't currently running
# then just show that the containers are WAIT_START; waiting to be started
else
printf $WAIT_START_STRING && return 1
fi
} }
# {% raw %} # {% raw %}
print_line() { print_line() {
local service_name=${1} local service_name=${1}
local service_state="$( parse_status ${2} )" local service_state="$( parse_status ${2} ${1} )"
local columns=$(tput cols) local columns=$(tput cols)
local state_color="\e[0m" local state_color="\e[0m"
local PADDING_CONSTANT=14 local PADDING_CONSTANT=15
if [[ $service_state = "$ERROR_STRING" ]] || [[ $service_state = "$MISSING_STRING" ]]; then if [[ $service_state = "$ERROR_STRING" ]] || [[ $service_state = "$MISSING_STRING" ]] || [[ $service_state = "$WAIT_START_STRING" ]]; then
state_color="\e[1;31m" state_color="\e[1;31m"
elif [[ $service_state = "$SUCCESS_STRING" ]]; then elif [[ $service_state = "$SUCCESS_STRING" ]]; then
state_color="\e[1;32m" state_color="\e[1;32m"
elif [[ $service_state = "$PENDING_STRING" ]]; then elif [[ $service_state = "$PENDING_STRING" ]] || [[ $service_state = "$DISABLED_STRING" ]] || [[ $service_state = "$STARTING_STRING" ]]; then
state_color="\e[1;33m" state_color="\e[1;33m"
fi fi
printf " $service_name " printf " $service_name "
for i in $(seq 0 $(( $columns - $PADDING_CONSTANT - ${#service_name} - ${#service_state} ))); do for i in $(seq 0 $(( $columns - $PADDING_CONSTANT - ${#service_name} - ${#service_state} ))); do
printf "-" printf "${state_color}%b\e[0m" "-"
done done
printf " [ " printf " [ "
printf "${state_color}%b\e[0m" "$service_state" printf "${state_color}%b\e[0m" "$service_state"
@@ -152,12 +181,10 @@ print_line() {
non_term_print_line() { non_term_print_line() {
local service_name=${1} local service_name=${1}
local service_state="$( parse_status ${2} )" local service_state="$( parse_status ${2} ${1} )"
local PADDING_CONSTANT=10
printf " $service_name " printf " $service_name "
for i in $(seq 0 $(( 40 - $PADDING_CONSTANT - ${#service_name} - ${#service_state} ))); do for i in $(seq 0 $(( 35 - ${#service_name} - ${#service_state} ))); do
printf "-" printf "-"
done done
printf " [ " printf " [ "
+2
View File
@@ -23,6 +23,8 @@ REPLAY_ENABLED=$(docker images | grep so-tcpreplay)
REPLAY_RUNNING=$(docker ps | grep so-tcpreplay) REPLAY_RUNNING=$(docker ps | grep so-tcpreplay)
if [ "$REPLAY_ENABLED" != "" ] && [ "$REPLAY_RUNNING" != "" ]; then if [ "$REPLAY_ENABLED" != "" ] && [ "$REPLAY_RUNNING" != "" ]; then
echo
echo "Preparing to replay PCAPs..."
docker cp so-tcpreplay:/opt/samples /opt/samples docker cp so-tcpreplay:/opt/samples /opt/samples
docker exec -it so-tcpreplay /usr/local/bin/tcpreplay -i bond0 -M10 /opt/samples/* docker exec -it so-tcpreplay /usr/local/bin/tcpreplay -i bond0 -M10 /opt/samples/*
echo echo
+4 -4
View File
@@ -31,7 +31,7 @@ fi
USER=$1 USER=$1
THEHIVE_KEY=$(lookup_pillar hivekey) THEHIVE_KEY=$(lookup_pillar hivekey)
THEHIVE_IP=$(lookup_pillar managerip) THEHVIE_API_URL="$(lookup_pillar url_base)/thehive/api"
THEHIVE_USER=$USER THEHIVE_USER=$USER
# Read password for new user from stdin # Read password for new user from stdin
@@ -47,11 +47,11 @@ if ! check_password "$THEHIVE_PASS"; then
fi fi
# Create new user in TheHive # Create new user in TheHive
resp=$(curl -sk -XPOST -H "Authorization: Bearer $THEHIVE_KEY" -H "Content-Type: application/json" "https://$THEHIVE_IP/thehive/api/user" -d "{\"login\" : \"$THEHIVE_USER\",\"name\" : \"$THEHIVE_USER\",\"roles\" : [\"read\",\"alert\",\"write\",\"admin\"],\"preferences\" : \"{}\",\"password\" : \"$THEHIVE_PASS\"}") resp=$(curl -sk -XPOST -H "Authorization: Bearer $THEHIVE_KEY" -H "Content-Type: application/json" -L "https://$THEHVIE_API_URL/user" -d "{\"login\" : \"$THEHIVE_USER\",\"name\" : \"$THEHIVE_USER\",\"roles\" : [\"read\",\"alert\",\"write\",\"admin\"],\"preferences\" : \"{}\",\"password\" : \"$THEHIVE_PASS\"}")
if [[ "$resp" =~ \"status\":\"Ok\" ]]; then if [[ "$resp" =~ \"status\":\"Ok\" ]]; then
echo "Successfully added user to TheHive." echo "Successfully added user to TheHive"
else else
echo "Unable to add user to TheHive; user might already exist." echo "Unable to add user to TheHive; user might already exist"
echo $resp echo $resp
exit 2 exit 2
fi fi
@@ -20,7 +20,7 @@
usage() { usage() {
echo "Usage: $0 <user-name> <true|false>" echo "Usage: $0 <user-name> <true|false>"
echo "" echo ""
echo "Enables or disables a user in thehive." echo "Enables or disables a user in TheHive."
exit 1 exit 1
} }
@@ -31,7 +31,7 @@ fi
USER=$1 USER=$1
THEHIVE_KEY=$(lookup_pillar hivekey) THEHIVE_KEY=$(lookup_pillar hivekey)
THEHIVE_IP=$(lookup_pillar managerip) THEHVIE_API_URL="$(lookup_pillar url_base)/thehive/api"
THEHIVE_USER=$USER THEHIVE_USER=$USER
case "${2^^}" in case "${2^^}" in
@@ -46,11 +46,11 @@ case "${2^^}" in
;; ;;
esac esac
resp=$(curl -sk -XPATCH -H "Authorization: Bearer $THEHIVE_KEY" -H "Content-Type: application/json" "https://$THEHIVE_IP/thehive/api/user/${THEHIVE_USER}" -d "{\"status\":\"${THEHIVE_STATUS}\" }") resp=$(curl -sk -XPATCH -H "Authorization: Bearer $THEHIVE_KEY" -H "Content-Type: application/json" -L "https://$THEHVIE_API_URL/user/${THEHIVE_USER}" -d "{\"status\":\"${THEHIVE_STATUS}\" }")
if [[ "$resp" =~ \"status\":\"Locked\" || "$resp" =~ \"status\":\"Ok\" ]]; then if [[ "$resp" =~ \"status\":\"Locked\" || "$resp" =~ \"status\":\"Ok\" ]]; then
echo "Successfully updated user in thehive." echo "Successfully updated user in TheHive"
else else
echo "Failed to update user in thehive." echo "Failed to update user in TheHive"
echo "$resp" echo "$resp"
exit 2 exit 2
fi fi
+10 -10
View File
@@ -8,9 +8,9 @@
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
. /usr/sbin/so-common source $(dirname $0)/so-common
if [[ $# < 1 || $# > 2 ]]; then if [[ $# -lt 1 || $# -gt 2 ]]; then
echo "Usage: $0 <list|add|update|enable|disable|validate|valemail|valpass> [email]" echo "Usage: $0 <list|add|update|enable|disable|validate|valemail|valpass> [email]"
echo "" echo ""
echo " list: Lists all user email addresses currently defined in the identity system" echo " list: Lists all user email addresses currently defined in the identity system"
@@ -22,7 +22,7 @@ if [[ $# < 1 || $# > 2 ]]; then
echo " valemail: Validates that the given email address is acceptable for defining a new user; requires 'email' parameter" echo " valemail: Validates that the given email address is acceptable for defining a new user; requires 'email' parameter"
echo " valpass: Validates that a password is acceptable for defining a new user" echo " valpass: Validates that a password is acceptable for defining a new user"
echo "" echo ""
echo " Note that the password can be piped into stdin to avoid prompting for it." echo " Note that the password can be piped into STDIN to avoid prompting for it"
exit 1 exit 1
fi fi
@@ -56,14 +56,14 @@ function verifyEnvironment() {
require "openssl" require "openssl"
require "sqlite3" require "sqlite3"
[[ ! -f $databasePath ]] && fail "Unable to find database file; specify path via KRATOS_DB_PATH environment variable" [[ ! -f $databasePath ]] && fail "Unable to find database file; specify path via KRATOS_DB_PATH environment variable"
response=$(curl -Ss ${kratosUrl}/) response=$(curl -Ss -L ${kratosUrl}/)
[[ "$response" != "404 page not found" ]] && fail "Unable to communicate with Kratos; specify URL via KRATOS_URL environment variable" [[ "$response" != "404 page not found" ]] && fail "Unable to communicate with Kratos; specify URL via KRATOS_URL environment variable"
} }
function findIdByEmail() { function findIdByEmail() {
email=$1 email=$1
response=$(curl -Ss ${kratosUrl}/identities) response=$(curl -Ss -L ${kratosUrl}/identities)
identityId=$(echo "${response}" | jq ".[] | select(.verifiable_addresses[0].value == \"$email\") | .id") identityId=$(echo "${response}" | jq ".[] | select(.verifiable_addresses[0].value == \"$email\") | .id")
echo $identityId echo $identityId
} }
@@ -113,7 +113,7 @@ function updatePassword() {
} }
function listUsers() { function listUsers() {
response=$(curl -Ss ${kratosUrl}/identities) response=$(curl -Ss -L ${kratosUrl}/identities)
[[ $? != 0 ]] && fail "Unable to communicate with Kratos" [[ $? != 0 ]] && fail "Unable to communicate with Kratos"
echo "${response}" | jq -r ".[] | .verifiable_addresses[0].value" | sort echo "${response}" | jq -r ".[] | .verifiable_addresses[0].value" | sort
@@ -131,7 +131,7 @@ function createUser() {
EOF EOF
) )
response=$(curl -Ss ${kratosUrl}/identities -d "$addUserJson") response=$(curl -Ss -L ${kratosUrl}/identities -d "$addUserJson")
[[ $? != 0 ]] && fail "Unable to communicate with Kratos" [[ $? != 0 ]] && fail "Unable to communicate with Kratos"
identityId=$(echo "${response}" | jq ".id") identityId=$(echo "${response}" | jq ".id")
@@ -153,7 +153,7 @@ function updateStatus() {
identityId=$(findIdByEmail "$email") identityId=$(findIdByEmail "$email")
[[ ${identityId} == "" ]] && fail "User not found" [[ ${identityId} == "" ]] && fail "User not found"
response=$(curl -Ss "${kratosUrl}/identities/$identityId") response=$(curl -Ss -L "${kratosUrl}/identities/$identityId")
[[ $? != 0 ]] && fail "Unable to communicate with Kratos" [[ $? != 0 ]] && fail "Unable to communicate with Kratos"
oldConfig=$(echo "select config from identity_credentials where identity_id=${identityId};" | sqlite3 "$databasePath") oldConfig=$(echo "select config from identity_credentials where identity_id=${identityId};" | sqlite3 "$databasePath")
@@ -171,7 +171,7 @@ function updateStatus() {
fi fi
updatedJson=$(echo "$response" | jq ".traits.status = \"$status\" | del(.verifiable_addresses) | del(.id) | del(.schema_url)") updatedJson=$(echo "$response" | jq ".traits.status = \"$status\" | del(.verifiable_addresses) | del(.id) | del(.schema_url)")
response=$(curl -Ss -XPUT ${kratosUrl}/identities/$identityId -d "$updatedJson") response=$(curl -Ss -XPUT -L ${kratosUrl}/identities/$identityId -d "$updatedJson")
[[ $? != 0 ]] && fail "Unable to mark user as locked" [[ $? != 0 ]] && fail "Unable to mark user as locked"
} }
@@ -191,7 +191,7 @@ function deleteUser() {
identityId=$(findIdByEmail "$email") identityId=$(findIdByEmail "$email")
[[ ${identityId} == "" ]] && fail "User not found" [[ ${identityId} == "" ]] && fail "User not found"
response=$(curl -Ss -XDELETE "${kratosUrl}/identities/$identityId") response=$(curl -Ss -XDELETE -L "${kratosUrl}/identities/$identityId")
[[ $? != 0 ]] && fail "Unable to communicate with Kratos" [[ $? != 0 ]] && fail "Unable to communicate with Kratos"
} }
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
docker exec -it so-wazuh /usr/bin/node /var/ossec/api/configuration/auth/htpasswd /var/ossec/api/configuration/auth/user $1
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
docker exec -it so-wazuh /usr/bin/node /var/ossec/api/configuration/auth/htpasswd /var/ossec/api/configuration/auth/user $1
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
docker exec -it so-wazuh /usr/bin/node /var/ossec/api/configuration/auth/htpasswd -D /var/ossec/api/configuration/auth/user $1
+119 -143
View File
@@ -16,24 +16,22 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
. /usr/sbin/so-common . /usr/sbin/so-common
UPDATE_DIR=/tmp/sogh/securityonion UPDATE_DIR=/tmp/sogh/securityonion
INSTALLEDVERSION=$(cat /etc/soversion) INSTALLEDVERSION=$(cat /etc/soversion)
INSTALLEDSALTVERSION=$(salt --versions-report | grep Salt: | awk {'print $2'}) INSTALLEDSALTVERSION=$(salt --versions-report | grep Salt: | awk {'print $2'})
DEFAULT_SALT_DIR=/opt/so/saltstack/default DEFAULT_SALT_DIR=/opt/so/saltstack/default
BATCHSIZE=5 BATCHSIZE=5
SOUP_LOG=/root/soup.log SOUP_LOG=/root/soup.log
exec 3>&1 1>${SOUP_LOG} 2>&1 exec 3>&1 1>${SOUP_LOG} 2>&1
manager_check() { add_common() {
# Check to see if this is a manager cp $UPDATE_DIR/salt/common/tools/sbin/so-common $DEFAULT_SALT_DIR/salt/common/tools/sbin/
MANAGERCHECK=$(cat /etc/salt/grains | grep role | awk '{print $2}') cp $UPDATE_DIR/salt/common/tools/sbin/so-image-common $DEFAULT_SALT_DIR/salt/common/tools/sbin/
if [[ "$MANAGERCHECK" =~ ^('so-eval'|'so-manager'|'so-standalone'|'so-managersearch'|'so-import')$ ]]; then salt-call state.apply common queue=True
echo "This is a manager. We can proceed." echo "Run soup one more time"
MINIONID=$(salt-call grains.get id --out=txt|awk -F: {'print $2'}|tr -d ' ') exit 0
else
echo "Please run soup on the manager. The manager controls all updates."
exit 0
fi
} }
airgap_mounted() { airgap_mounted() {
@@ -47,7 +45,7 @@ airgap_mounted() {
echo "If you just copied the .iso file over you can specify the path." echo "If you just copied the .iso file over you can specify the path."
echo "If you burned the ISO to a disk the standard way you can specify the device." echo "If you burned the ISO to a disk the standard way you can specify the device."
echo "Example: /home/user/securityonion-2.X.0.iso" echo "Example: /home/user/securityonion-2.X.0.iso"
echo "Example: /dev/cdrom" echo "Example: /dev/sdx1"
echo "" echo ""
read -p 'Enter the location of the iso: ' ISOLOC read -p 'Enter the location of the iso: ' ISOLOC
if [ -f $ISOLOC ]; then if [ -f $ISOLOC ]; then
@@ -79,6 +77,30 @@ airgap_mounted() {
fi fi
} }
airgap_update_dockers() {
if [ $is_airgap -eq 0 ]; then
# Let's copy the tarball
if [ ! -f $AGDOCKER/registry.tar ]; then
echo "Unable to locate registry. Exiting"
exit 1
else
echo "Stopping the registry docker"
docker stop so-dockerregistry
docker rm so-dockerregistry
echo "Copying the new dockers over"
tar xvf $AGDOCKER/registry.tar -C /nsm/docker-registry/docker
echo "Add Registry back"
docker load -i $AGDOCKER/registry_image.tar
fi
fi
}
update_registry() {
docker stop so-dockerregistry
docker rm so-dockerregistry
salt-call state.apply registry queue=True
}
check_airgap() { check_airgap() {
# See if this is an airgap install # See if this is an airgap install
AIRGAP=$(cat /opt/so/saltstack/local/pillar/global.sls | grep airgap | awk '{print $2}') AIRGAP=$(cat /opt/so/saltstack/local/pillar/global.sls | grep airgap | awk '{print $2}')
@@ -92,6 +114,12 @@ check_airgap() {
fi fi
} }
check_sudoers() {
if grep -q "so-setup" /etc/sudoers; then
echo "There is an entry for so-setup in the sudoers file, this can be safely deleted using \"visudo\"."
fi
}
clean_dockers() { clean_dockers() {
# Place Holder for cleaning up old docker images # Place Holder for cleaning up old docker images
echo "Trying to clean up old dockers." echo "Trying to clean up old dockers."
@@ -100,7 +128,6 @@ clean_dockers() {
} }
clone_to_tmp() { clone_to_tmp() {
# TODO Need to add a air gap option
# Clean old files # Clean old files
rm -rf /tmp/sogh rm -rf /tmp/sogh
# Make a temp location for the files # Make a temp location for the files
@@ -128,21 +155,9 @@ copy_new_files() {
cd /tmp cd /tmp
} }
detect_os() {
# Detect Base OS
echo "Determining Base OS." >> "$SOUP_LOG" 2>&1
if [ -f /etc/redhat-release ]; then
OS="centos"
elif [ -f /etc/os-release ]; then
OS="ubuntu"
fi
echo "Found OS: $OS" >> "$SOUP_LOG" 2>&1
}
highstate() { highstate() {
# Run a highstate but first cancel a running one. # Run a highstate.
salt-call saltutil.kill_all_jobs salt-call state.highstate -l info queue=True
salt-call state.highstate -l info
} }
masterlock() { masterlock() {
@@ -182,7 +197,6 @@ pillar_changes() {
[[ "$INSTALLEDVERSION" =~ rc.1 ]] && rc1_to_rc2 [[ "$INSTALLEDVERSION" =~ rc.1 ]] && rc1_to_rc2
[[ "$INSTALLEDVERSION" =~ rc.2 ]] && rc2_to_rc3 [[ "$INSTALLEDVERSION" =~ rc.2 ]] && rc2_to_rc3
[[ "$INSTALLEDVERSION" =~ rc.3 ]] && rc3_to_2.3.0 [[ "$INSTALLEDVERSION" =~ rc.3 ]] && rc3_to_2.3.0
} }
rc1_to_rc2() { rc1_to_rc2() {
@@ -283,113 +297,15 @@ unmount_update() {
umount /tmp/soagupdate umount /tmp/soagupdate
} }
update_centos_repo() { update_centos_repo() {
# Update the files in the repo # Update the files in the repo
echo "Syncing new updates to /nsm/repo" echo "Syncing new updates to /nsm/repo"
rsync -a $AGDOCKER/repo /nsm/repo rsync -av $AGREPO/* /nsm/repo/
echo "Creating repo" echo "Creating repo"
createrepo /nsm/repo createrepo /nsm/repo
} }
update_dockers() {
if [ $is_airgap -eq 0 ]; then
# Let's copy the tarball
if [ ! -f $AGDOCKER/registry.tar ]; then
echo "Unable to locate registry. Exiting"
exit 0
else
echo "Stopping the registry docker"
docker stop so-dockerregistry
docker rm so-dockerregistry
echo "Copying the new dockers over"
tar xvf $AGDOCKER/registry.tar -C /nsm/docker-registry/docker
fi
else
# List all the containers
if [ $MANAGERCHECK == 'so-import' ]; then
TRUSTED_CONTAINERS=( \
"so-idstools" \
"so-nginx" \
"so-filebeat" \
"so-suricata" \
"so-soc" \
"so-elasticsearch" \
"so-kibana" \
"so-kratos" \
"so-suricata" \
"so-registry" \
"so-pcaptools" \
"so-zeek" )
elif [ $MANAGERCHECK != 'so-helix' ]; then
TRUSTED_CONTAINERS=( \
"so-acng" \
"so-thehive-cortex" \
"so-curator" \
"so-domainstats" \
"so-elastalert" \
"so-elasticsearch" \
"so-filebeat" \
"so-fleet" \
"so-fleet-launcher" \
"so-freqserver" \
"so-grafana" \
"so-idstools" \
"so-influxdb" \
"so-kibana" \
"so-kratos" \
"so-logstash" \
"so-minio" \
"so-mysql" \
"so-nginx" \
"so-pcaptools" \
"so-playbook" \
"so-redis" \
"so-soc" \
"so-soctopus" \
"so-steno" \
"so-strelka-frontend" \
"so-strelka-manager" \
"so-strelka-backend" \
"so-strelka-filestream" \
"so-suricata" \
"so-telegraf" \
"so-thehive" \
"so-thehive-es" \
"so-wazuh" \
"so-zeek" )
else
TRUSTED_CONTAINERS=( \
"so-filebeat" \
"so-idstools" \
"so-logstash" \
"so-nginx" \
"so-redis" \
"so-steno" \
"so-suricata" \
"so-telegraf" \
"so-zeek" )
fi
# Download the containers from the interwebs
for i in "${TRUSTED_CONTAINERS[@]}"
do
# Pull down the trusted docker image
echo "Downloading $i:$NEWVERSION"
docker pull --disable-content-trust=false docker.io/$IMAGEREPO/$i:$NEWVERSION
# Tag it with the new registry destination
docker tag $IMAGEREPO/$i:$NEWVERSION $HOSTNAME:5000/$IMAGEREPO/$i:$NEWVERSION
docker push $HOSTNAME:5000/$IMAGEREPO/$i:$NEWVERSION
done
fi
# Cleanup on Aisle 4
clean_dockers
echo "Add Registry back if airgap"
if [ $is_airgap -eq 0 ]; then
docker load -i $AGDOCKER/registry_image.tar
fi
}
update_version() { update_version() {
# Update the version to the latest # Update the version to the latest
echo "Updating the Security Onion version file." echo "Updating the Security Onion version file."
@@ -411,6 +327,10 @@ upgrade_check_salt() {
if [ "$INSTALLEDSALTVERSION" == "$NEWSALTVERSION" ]; then if [ "$INSTALLEDSALTVERSION" == "$NEWSALTVERSION" ]; then
echo "You are already running the correct version of Salt for Security Onion." echo "You are already running the correct version of Salt for Security Onion."
else else
UPGRADESALT=1
fi
}
upgrade_salt() {
SALTUPGRADED=True SALTUPGRADED=True
echo "Performing upgrade of Salt from $INSTALLEDSALTVERSION to $NEWSALTVERSION." echo "Performing upgrade of Salt from $INSTALLEDSALTVERSION to $NEWSALTVERSION."
echo "" echo ""
@@ -421,7 +341,11 @@ upgrade_check_salt() {
yum versionlock delete "salt-*" yum versionlock delete "salt-*"
echo "Updating Salt packages and restarting services." echo "Updating Salt packages and restarting services."
echo "" echo ""
sh $UPDATE_DIR/salt/salt/scripts/bootstrap-salt.sh -F -M -x python3 stable "$NEWSALTVERSION" if [ $is_airgap -eq 0 ]; then
sh $UPDATE_DIR/salt/salt/scripts/bootstrap-salt.sh -r -F -M -x python3 stable "$NEWSALTVERSION"
else
sh $UPDATE_DIR/salt/salt/scripts/bootstrap-salt.sh -F -M -x python3 stable "$NEWSALTVERSION"
fi
echo "Applying yum versionlock for Salt." echo "Applying yum versionlock for Salt."
echo "" echo ""
yum versionlock add "salt-*" yum versionlock add "salt-*"
@@ -441,7 +365,6 @@ upgrade_check_salt() {
apt-mark hold "salt-master" apt-mark hold "salt-master"
apt-mark hold "salt-minion" apt-mark hold "salt-minion"
fi fi
fi
} }
verify_latest_update_script() { verify_latest_update_script() {
@@ -478,13 +401,14 @@ done
echo "Checking to see if this is a manager." echo "Checking to see if this is a manager."
echo "" echo ""
manager_check require_manager
set_minionid
echo "Checking to see if this is an airgap install" echo "Checking to see if this is an airgap install"
echo "" echo ""
check_airgap check_airgap
echo "Found that Security Onion $INSTALLEDVERSION is currently installed." echo "Found that Security Onion $INSTALLEDVERSION is currently installed."
echo "" echo ""
detect_os set_os
echo "" echo ""
if [ $is_airgap -eq 0 ]; then if [ $is_airgap -eq 0 ]; then
# Let's mount the ISO since this is airgap # Let's mount the ISO since this is airgap
@@ -493,6 +417,12 @@ else
echo "Cloning Security Onion github repo into $UPDATE_DIR." echo "Cloning Security Onion github repo into $UPDATE_DIR."
clone_to_tmp clone_to_tmp
fi fi
if [ -f /usr/sbin/so-image-common ]; then
. /usr/sbin/so-image-common
else
add_common
fi
echo "" echo ""
echo "Verifying we have the latest soup script." echo "Verifying we have the latest soup script."
verify_latest_update_script verify_latest_update_script
@@ -502,29 +432,60 @@ echo "Let's see if we need to update Security Onion."
upgrade_check upgrade_check
space_check space_check
echo "Checking for Salt Master and Minion updates."
upgrade_check_salt
echo "" echo ""
echo "Performing upgrade from Security Onion $INSTALLEDVERSION to Security Onion $NEWVERSION." echo "Performing upgrade from Security Onion $INSTALLEDVERSION to Security Onion $NEWVERSION."
echo "" echo ""
echo "Updating dockers to $NEWVERSION."
if [ $is_airgap -eq 0 ]; then
airgap_update_dockers
else
update_registry
update_docker_containers "soup"
fi
echo ""
echo "Stopping Salt Minion service." echo "Stopping Salt Minion service."
systemctl stop salt-minion systemctl stop salt-minion
echo "Killing any remaining Salt Minion processes."
pkill -9 -ef /usr/bin/salt-minion
echo "" echo ""
echo "Stopping Salt Master service." echo "Stopping Salt Master service."
systemctl stop salt-master systemctl stop salt-master
echo "" echo ""
echo "Checking for Salt Master and Minion updates."
upgrade_check_salt
# Does salt need upgraded. If so update it.
if [ "$UPGRADESALT" == "1" ]; then
echo "Upgrading Salt"
# Update the repo files so it can actually upgrade
if [ $is_airgap -eq 0 ]; then
update_centos_repo
yum clean all
fi
upgrade_salt
fi
echo "Checking if Salt was upgraded."
echo ""
# Check that Salt was upgraded
if [[ $(salt --versions-report | grep Salt: | awk {'print $2'}) != "$NEWSALTVERSION" ]]; then
echo "Salt upgrade failed. Check of indicators of failure in $SOUP_LOG."
echo "Once the issue is resolved, run soup again."
echo "Exiting."
echo ""
exit 1
else
echo "Salt upgrade success."
echo ""
fi
echo "Making pillar changes." echo "Making pillar changes."
pillar_changes pillar_changes
echo "" echo ""
echo ""
echo "Updating dockers to $NEWVERSION."
update_dockers
# Only update the repo if its airgap # Only update the repo if its airgap
if [ $is_airgap -eq 0 ]; then if [[ $is_airgap -eq 0 ]] && [[ "$UPGRADESALT" != "1" ]]; then
update_centos_repo update_centos_repo
fi fi
@@ -542,9 +503,19 @@ echo ""
echo "Starting Salt Master service." echo "Starting Salt Master service."
systemctl start salt-master systemctl start salt-master
# Only regenerate osquery packages if Fleet is enabled
FLEET_MANAGER=$(lookup_pillar fleet_manager)
FLEET_NODE=$(lookup_pillar fleet_node)
if [[ "$FLEET_MANAGER" == "True" || "$FLEET_NODE" == "True" ]]; then
echo ""
echo "Regenerating Osquery Packages.... This will take several minutes."
salt-call state.apply fleet.event_gen-packages -l info queue=True
echo ""
fi
echo "" echo ""
echo "Running a highstate to complete the Security Onion upgrade on this manager. This could take several minutes." echo "Running a highstate to complete the Security Onion upgrade on this manager. This could take several minutes."
highstate salt-call state.highstate -l info queue=True
echo "" echo ""
echo "Upgrade from $INSTALLEDVERSION to $NEWVERSION complete." echo "Upgrade from $INSTALLEDVERSION to $NEWVERSION complete."
@@ -557,18 +528,23 @@ masterunlock
echo "" echo ""
echo "Starting Salt Master service." echo "Starting Salt Master service."
systemctl start salt-master systemctl start salt-master
highstate echo "Running a highstate. This could take several minutes."
salt-call state.highstate -l info queue=True
playbook playbook
unmount_update unmount_update
SALTUPGRADED="True" if [ "$UPGRADESALT" == "1" ]; then
if [[ "$SALTUPGRADED" == "True" ]]; then
echo "" echo ""
echo "Upgrading Salt on the remaining Security Onion nodes from $INSTALLEDSALTVERSION to $NEWSALTVERSION." echo "Upgrading Salt on the remaining Security Onion nodes from $INSTALLEDSALTVERSION to $NEWSALTVERSION."
salt -C 'not *_eval and not *_helix and not *_manager and not *_managersearch and not *_standalone' -b $BATCHSIZE state.apply salt.minion if [ $is_airgap -eq 0 ]; then
salt -C 'not *_eval and not *_helix and not *_manager and not *_managersearch and not *_standalone' cmd.run "yum clean all"
fi
salt -C 'not *_eval and not *_helix and not *_manager and not *_managersearch and not *_standalone' -b $BATCHSIZE state.apply salt.minion queue=True
echo "" echo ""
fi fi
check_sudoers
} }
main "$@" | tee /dev/fd/3 main "$@" | tee /dev/fd/3
+25
View File
@@ -1,2 +1,27 @@
#!/bin/bash #!/bin/bash
#
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
APP=close
lf=/tmp/$APP-pidLockFile
# create empty lock file if none exists
cat /dev/null >> $lf
read lastPID < $lf
# if lastPID is not null and a process with that pid exists , exit
[ ! -z "$lastPID" -a -d /proc/$lastPID ] && exit
echo $$ > $lf
/usr/sbin/so-curator-closed-delete > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-zeek-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-beats-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-firewall-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-ids-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-import-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-osquery-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-ossec-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-strelka-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-syslog-close.yml > /dev/null 2>&1 /usr/sbin/so-curator-closed-delete > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-zeek-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-beats-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-firewall-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-ids-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-import-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-osquery-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-ossec-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-strelka-close.yml > /dev/null 2>&1; docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/so-syslog-close.yml > /dev/null 2>&1
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
# Copyright 2014,2015,2016,2017,2018 Security Onion Solutions, LLC # Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -34,6 +34,13 @@
#fi #fi
# Avoid starting multiple instances # Avoid starting multiple instances
if ! pgrep -f "so-curator-closed-delete-delete" >/dev/null; then APP=closeddelete
/usr/sbin/so-curator-closed-delete-delete lf=/tmp/$APP-pidLockFile
fi # create empty lock file if none exists
cat /dev/null >> $lf
read lastPID < $lf
# if lastPID is not null and a process with that pid exists , exit
[ ! -z "$lastPID" -a -d /proc/$lastPID ] && exit
echo $$ > $lf
/usr/sbin/so-curator-closed-delete-delete
@@ -11,7 +11,7 @@
{%- set LOG_SIZE_LIMIT = salt['pillar.get']('manager:log_size_limit', '') -%} {%- set LOG_SIZE_LIMIT = salt['pillar.get']('manager:log_size_limit', '') -%}
{%- endif -%} {%- endif -%}
# Copyright 2014,2015,2016,2017,2018 Security Onion Solutions, LLC # Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -26,29 +26,36 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
#. /usr/sbin/so-elastic-common
#. /etc/nsm/securityonion.conf
LOG="/opt/so/log/curator/so-curator-closed-delete.log" LOG="/opt/so/log/curator/so-curator-closed-delete.log"
overlimit() {
[[ $(du -hs --block-size=1GB /nsm/elasticsearch/nodes | awk '{print $1}' ) -gt "{{LOG_SIZE_LIMIT}}" ]]
}
closedindices() {
INDICES=$(curl -s -k {% if grains['role'] in ['so-node','so-heavynode'] %}https://{% endif %}{{ELASTICSEARCH_HOST}}:{{ELASTICSEARCH_PORT}}/_cat/indices?h=index\&expand_wildcards=closed 2> /dev/null)
[ $? -eq 1 ] && return false
echo ${INDICES} | grep -q -E "(logstash-|so-)"
}
# Check for 2 conditions: # Check for 2 conditions:
# 1. Are Elasticsearch indices using more disk space than LOG_SIZE_LIMIT? # 1. Are Elasticsearch indices using more disk space than LOG_SIZE_LIMIT?
# 2. Are there any closed logstash-, or so- indices that we can delete? # 2. Are there any closed indices that we can delete?
# If both conditions are true, keep on looping until one of the conditions is false. # If both conditions are true, keep on looping until one of the conditions is false.
while [[ $(du -hs --block-size=1GB /nsm/elasticsearch/nodes | awk '{print $1}' ) -gt "{{LOG_SIZE_LIMIT}}" ]] && while overlimit && closedindices; do
curl -s {{ELASTICSEARCH_HOST}}:{{ELASTICSEARCH_PORT}}/_cat/indices | grep -E "^ close (logstash-|so-)" > /dev/null; do
# We need to determine OLDEST_INDEX. # We need to determine OLDEST_INDEX:
# First, get the list of closed indices that are prefixed with "logstash-" or "so-". # First, get the list of closed indices using _cat/indices?h=index\&expand_wildcards=closed.
# For example: logstash-ids-YYYY.MM.DD
# Then, sort by date by telling sort to use hyphen as delimiter and then sort on the third field. # Then, sort by date by telling sort to use hyphen as delimiter and then sort on the third field.
# Finally, select the first entry in that sorted list. # Finally, select the first entry in that sorted list.
OLDEST_INDEX=$(curl -s {{ELASTICSEARCH_HOST}}:{{ELASTICSEARCH_PORT}}/_cat/indices | grep -E "^ close (logstash-|so-)" | awk '{print $2}' | sort -t- -k3 | head -1) OLDEST_INDEX=$(curl -s -k {% if grains['role'] in ['so-node','so-heavynode'] %}https://{% endif %}{{ELASTICSEARCH_HOST}}:{{ELASTICSEARCH_PORT}}/_cat/indices?h=index\&expand_wildcards=closed | grep -E "(logstash-|so-)" | sort -t- -k3 | head -1)
# Now that we've determined OLDEST_INDEX, ask Elasticsearch to delete it. # Now that we've determined OLDEST_INDEX, ask Elasticsearch to delete it.
curl -XDELETE {{ELASTICSEARCH_HOST}}:{{ELASTICSEARCH_PORT}}/${OLDEST_INDEX} curl -XDELETE -k {% if grains['role'] in ['so-node','so-heavynode'] %}https://{% endif %}{{ELASTICSEARCH_HOST}}:{{ELASTICSEARCH_PORT}}/${OLDEST_INDEX}
# Finally, write a log entry that says we deleted it. # Finally, write a log entry that says we deleted it.
echo "$(date) - Used disk space exceeds LOG_SIZE_LIMIT ({{LOG_SIZE_LIMIT}} GB) - Index ${OLDEST_INDEX} deleted ..." >> ${LOG} echo "$(date) - Used disk space exceeds LOG_SIZE_LIMIT ({{LOG_SIZE_LIMIT}} GB) - Index ${OLDEST_INDEX} deleted ..." >> ${LOG}
done done
+25
View File
@@ -1,2 +1,27 @@
#!/bin/bash #!/bin/bash
#
# Copyright 2014,2015,2016,2017,2018,2019,2020 Security Onion Solutions, LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
APP=delete
lf=/tmp/$APP-pidLockFile
# create empty lock file if none exists
cat /dev/null >> $lf
read lastPID < $lf
# if lastPID is not null and a process with that pid exists , exit
[ ! -z "$lastPID" -a -d /proc/$lastPID ] && exit
echo $$ > $lf
docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/delete.yml > /dev/null 2>&1 docker exec so-curator curator --config /etc/curator/config/curator.yml /etc/curator/action/delete.yml > /dev/null 2>&1
+2 -2
View File
@@ -12,11 +12,11 @@ client:
- {{elasticsearch}} - {{elasticsearch}}
port: 9200 port: 9200
url_prefix: url_prefix:
use_ssl: False {% if grains['role'] in ['so-node', 'so-heavynode'] %} use_ssl: True{% else %} use_ssl: False{% endif %}
certificate: certificate:
client_cert: client_cert:
client_key: client_key:
ssl_no_validate: False {% if grains['role'] in ['so-node', 'so-heavynode'] %} ssl_no_validate: True{% else %} ssl_no_validate: False{% endif %}
http_auth: http_auth:
timeout: 30 timeout: 30
master_only: False master_only: False
+6
View File
@@ -127,6 +127,12 @@ so-curator:
- /opt/so/conf/curator/curator.yml:/etc/curator/config/curator.yml:ro - /opt/so/conf/curator/curator.yml:/etc/curator/config/curator.yml:ro
- /opt/so/conf/curator/action/:/etc/curator/action:ro - /opt/so/conf/curator/action/:/etc/curator/action:ro
- /opt/so/log/curator:/var/log/curator:rw - /opt/so/log/curator:/var/log/curator:rw
append_so-curator_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-curator
# Begin Curator Cron Jobs # Begin Curator Cron Jobs
# Close # Close
+2 -2
View File
@@ -1,6 +1,6 @@
{% set IMAGEREPO = salt['pillar.get']('global:imagerepo') %} {% set IMAGEREPO = salt['pillar.get']('global:imagerepo') %}
{% set MANAGER = salt['grains.get']('master') %} {% set MANAGER = salt['grains.get']('master') %}
{% set OLDVERSIONS = ['2.0.0-rc.1','2.0.1-rc.1','2.0.2-rc.1','2.0.3-rc.1','2.1.0-rc.2','2.2.0-rc.3']%} {% set OLDVERSIONS = ['2.0.0-rc.1','2.0.1-rc.1','2.0.2-rc.1','2.0.3-rc.1','2.1.0-rc.2','2.2.0-rc.3','2.3.0','2.3.1']%}
{% for VERSION in OLDVERSIONS %} {% for VERSION in OLDVERSIONS %}
remove_images_{{ VERSION }}: remove_images_{{ VERSION }}:
@@ -42,4 +42,4 @@ remove_images_{{ VERSION }}:
- '{{ MANAGER }}:5000/{{ IMAGEREPO }}/so-thehive-es:{{ VERSION }}' - '{{ MANAGER }}:5000/{{ IMAGEREPO }}/so-thehive-es:{{ VERSION }}'
- '{{ MANAGER }}:5000/{{ IMAGEREPO }}/so-wazuh:{{ VERSION }}' - '{{ MANAGER }}:5000/{{ IMAGEREPO }}/so-wazuh:{{ VERSION }}'
- '{{ MANAGER }}:5000/{{ IMAGEREPO }}/so-zeek:{{ VERSION }}' - '{{ MANAGER }}:5000/{{ IMAGEREPO }}/so-zeek:{{ VERSION }}'
{% endfor %} {% endfor %}
+7 -2
View File
@@ -43,19 +43,24 @@ dstatslogdir:
so-domainstatsimage: so-domainstatsimage:
cmd.run: cmd.run:
- name: docker pull --disable-content-trust=false docker.io/{{ IMAGEREPO }}/so-domainstats:HH1.0.3 - name: docker pull {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-domainstats:{{ VERSION }}
so-domainstats: so-domainstats:
docker_container.running: docker_container.running:
- require: - require:
- so-domainstatsimage - so-domainstatsimage
- image: docker.io/{{ IMAGEREPO }}/so-domainstats:HH1.0.3 - image: {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-domainstats:{{ VERSION }}
- hostname: domainstats - hostname: domainstats
- name: so-domainstats - name: so-domainstats
- user: domainstats - user: domainstats
- binds: - binds:
- /opt/so/log/domainstats:/var/log/domain_stats - /opt/so/log/domainstats:/var/log/domain_stats
append_so-domainstats_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-domainstats
{% else %} {% else %}
domainstats_state_not_allowed: domainstats_state_not_allowed:
@@ -16,7 +16,7 @@ class PlaybookESAlerter(Alerter):
today = strftime("%Y.%m.%d", gmtime()) today = strftime("%Y.%m.%d", gmtime())
timestamp = strftime("%Y-%m-%d"'T'"%H:%M:%S", gmtime()) timestamp = strftime("%Y-%m-%d"'T'"%H:%M:%S", gmtime())
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
payload = {"rule": { "name": self.rule['play_title'],"uuid": self.rule['play_id'],"category": self.rule['rule.category']},"event":{ "severity": self.rule['event.severity'],"module": self.rule['event.module'],"dataset": self.rule['event.dataset'],"severity_label": self.rule['sigma_level']},"kibana_pivot": self.rule['kibana_pivot'],"soc_pivot": self.rule['soc_pivot'],"play_url": self.rule['play_url'],"sigma_level": self.rule['sigma_level'],"event_data": match, "@timestamp": timestamp} payload = {"rule": { "name": self.rule['play_title'],"case_template": self.rule['play_id'],"uuid": self.rule['play_id'],"category": self.rule['rule.category']},"event":{ "severity": self.rule['event.severity'],"module": self.rule['event.module'],"dataset": self.rule['event.dataset'],"severity_label": self.rule['sigma_level']},"kibana_pivot": self.rule['kibana_pivot'],"soc_pivot": self.rule['soc_pivot'],"play_url": self.rule['play_url'],"sigma_level": self.rule['sigma_level'],"event_data": match, "@timestamp": timestamp}
url = f"http://{self.rule['elasticsearch_host']}/so-playbook-alerts-{today}/_doc/" url = f"http://{self.rule['elasticsearch_host']}/so-playbook-alerts-{today}/_doc/"
requests.post(url, data=json.dumps(payload), headers=headers, verify=False) requests.post(url, data=json.dumps(payload), headers=headers, verify=False)
+6
View File
@@ -121,6 +121,12 @@ so-elastalert:
- {{MANAGER_URL}}:{{MANAGER_IP}} - {{MANAGER_URL}}:{{MANAGER_IP}}
- require: - require:
- module: wait_for_elasticsearch - module: wait_for_elasticsearch
append_so-elastalert_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-elastalert
{% endif %} {% endif %}
{% else %} {% else %}
+1 -3
View File
@@ -37,7 +37,7 @@
{ "convert": { "field": "log.id.uid", "type": "string", "ignore_failure": true, "ignore_missing": true } }, { "convert": { "field": "log.id.uid", "type": "string", "ignore_failure": true, "ignore_missing": true } },
{ "convert": { "field": "agent.id", "type": "string", "ignore_failure": true, "ignore_missing": true } }, { "convert": { "field": "agent.id", "type": "string", "ignore_failure": true, "ignore_missing": true } },
{ "convert": { "field": "event.severity", "type": "integer", "ignore_failure": true, "ignore_missing": true } }, { "convert": { "field": "event.severity", "type": "integer", "ignore_failure": true, "ignore_missing": true } },
{ "remove": { "field": [ "message2", "type", "fields" ], "ignore_failure": true } }, { "remove": { "field": [ "message2", "type", "fields", "category", "module", "dataset" ], "ignore_missing": true, "ignore_failure": true } },
{ {
"date_index_name": { "date_index_name": {
"field": "@timestamp", "field": "@timestamp",
@@ -48,6 +48,4 @@
} }
} }
] ]
}
]
} }
+1 -1
View File
@@ -6,7 +6,7 @@
{ "set": { "if": "ctx.rule?.uuid > 1999999", "field": "rule.reference", "value": "https://doc.emergingthreats.net/{{rule.uuid}}" } }, { "set": { "if": "ctx.rule?.uuid > 1999999", "field": "rule.reference", "value": "https://doc.emergingthreats.net/{{rule.uuid}}" } },
{ "convert": { "if": "ctx.rule.uuid != null", "field": "rule.uuid", "type": "string" } }, { "convert": { "if": "ctx.rule.uuid != null", "field": "rule.uuid", "type": "string" } },
{ "dissect": { "if": "ctx.rule.name != null", "field": "rule.name", "pattern" : "%{rule_type} %{rest_of_rulename} ", "ignore_failure": true } }, { "dissect": { "if": "ctx.rule.name != null", "field": "rule.name", "pattern" : "%{rule_type} %{rest_of_rulename} ", "ignore_failure": true } },
{ "set": { "if": "ctx.rule_type == 'GPL'", "field": "rule_ruleset", "value": "Snort GPL" } }, { "set": { "if": "ctx.rule_type == 'GPL'", "field": "rule.ruleset", "value": "Snort GPL" } },
{ "set": { "if": "ctx.rule_type == 'ET'", "field": "rule.ruleset", "value": "Emerging Threats" } }, { "set": { "if": "ctx.rule_type == 'ET'", "field": "rule.ruleset", "value": "Emerging Threats" } },
{ "set": { "if": "ctx.rule.severity == 3", "field": "event.severity", "value": 1, "override": true } }, { "set": { "if": "ctx.rule.severity == 3", "field": "event.severity", "value": 1, "override": true } },
{ "set": { "if": "ctx.rule.severity == 2", "field": "event.severity", "value": 2, "override": true } }, { "set": { "if": "ctx.rule.severity == 2", "field": "event.severity", "value": 2, "override": true } },
@@ -6,7 +6,7 @@
{ "gsub": { "field": "message2.columns.data", "pattern": "\\\\xC2\\\\xAE", "replacement": "", "ignore_missing": true } }, { "gsub": { "field": "message2.columns.data", "pattern": "\\\\xC2\\\\xAE", "replacement": "", "ignore_missing": true } },
{ "rename": { "if": "ctx.message2.columns?.eventid != null", "field": "message2.columns", "target_field": "winlog", "ignore_missing": true } }, { "rename": { "if": "ctx.message2.columns?.eventid != null", "field": "message2.columns", "target_field": "winlog", "ignore_missing": true } },
{ "json": { "field": "winlog.data", "target_field": "temp", "ignore_failure": true } }, { "json": { "field": "winlog.data", "target_field": "temp", "ignore_failure": true } },
{ "rename": { "field": "temp.Data", "target_field": "winlog.event_data", "ignore_missing": true } }, { "rename": { "field": "temp.EventData", "target_field": "winlog.event_data", "ignore_missing": true } },
{ "rename": { "field": "winlog.source", "target_field": "winlog.channel", "ignore_missing": true } }, { "rename": { "field": "winlog.source", "target_field": "winlog.channel", "ignore_missing": true } },
{ "rename": { "field": "winlog.eventid", "target_field": "winlog.event_id", "ignore_missing": true } }, { "rename": { "field": "winlog.eventid", "target_field": "winlog.event_id", "ignore_missing": true } },
{ "pipeline": { "if": "ctx.winlog?.channel == 'Microsoft-Windows-Sysmon/Operational'", "name": "sysmon" } }, { "pipeline": { "if": "ctx.winlog?.channel == 'Microsoft-Windows-Sysmon/Operational'", "name": "sysmon" } },
@@ -22,4 +22,4 @@
{ "set": { "field": "event.dataset", "value": "{{osquery.result.name}}", "override": false} }, { "set": { "field": "event.dataset", "value": "{{osquery.result.name}}", "override": false} },
{ "pipeline": { "name": "common" } } { "pipeline": { "name": "common" } }
] ]
} }
+28 -7
View File
@@ -6,15 +6,27 @@
{ "rename": { "field": "message2.scan", "target_field": "scan", "ignore_missing": true } }, { "rename": { "field": "message2.scan", "target_field": "scan", "ignore_missing": true } },
{ "rename": { "field": "message2.request", "target_field": "request", "ignore_missing": true } }, { "rename": { "field": "message2.request", "target_field": "request", "ignore_missing": true } },
{ "rename": { "field": "scan.hash", "target_field": "hash", "ignore_missing": true } }, { "rename": { "field": "scan.hash", "target_field": "hash", "ignore_missing": true } },
{ "rename": { "field": "scan.exiftool", "target_field": "exiftool", "ignore_missing": true } },
{ "grok": { "if": "ctx.request?.attributes?.filename != null", "field": "request.attributes.filename", "patterns": ["-%{WORD:log.id.fuid}-"], "ignore_failure": true } }, { "grok": { "if": "ctx.request?.attributes?.filename != null", "field": "request.attributes.filename", "patterns": ["-%{WORD:log.id.fuid}-"], "ignore_failure": true } },
{ "foreach": { "foreach":
{ {
"if": "ctx.scan?.exiftool?.keys !=null", "if": "ctx.exiftool?.keys !=null",
"field": "scan.exiftool.keys", "field": "exiftool.keys",
"processor":{ "processor": {
"append": {
"field": "scan.exiftool",
"value": "{{_ingest._value.key}}={{_ingest._value.value}}"
}
}
}
},
{ "foreach":
{
"if": "ctx.exiftool?.keys !=null",
"field": "exiftool.keys",
"processor": {
"set": { "set": {
"field": "scan.exiftool.{{_ingest._value.key}}", "field": "exiftool.{{_ingest._value.key}}",
"value": "{{_ingest._value.value}}" "value": "{{_ingest._value.value}}"
} }
} }
@@ -32,9 +44,17 @@
} }
} }
}, },
{ "set": { "if": "ctx.exiftool?.SourceFile != null", "field": "file.source", "value": "{{exiftool.SourceFile}}", "ignore_failure": true }},
{ "set": { "if": "ctx.exiftool?.FilePermissions != null", "field": "file.permissions", "value": "{{exiftool.FilePermissions}}", "ignore_failure": true }},
{ "set": { "if": "ctx.exiftool?.FileName != null", "field": "file.name", "value": "{{exiftool.FileName}}", "ignore_failure": true }},
{ "set": { "if": "ctx.exiftool?.FileModifyDate != null", "field": "file.mtime", "value": "{{exiftool.FileModifyDate}}", "ignore_failure": true }},
{ "set": { "if": "ctx.exiftool?.FileAccessDate != null", "field": "file.accessed", "value": "{{exiftool.FileAccessDate}}", "ignore_failure": true }},
{ "set": { "if": "ctx.exiftool?.FileInodeChangeDate != null", "field": "file.ctime", "value": "{{exiftool.FileInodeChangeDate}}", "ignore_failure": true }},
{ "set": { "if": "ctx.exiftool?.FileDirectory != null", "field": "file.directory", "value": "{{exiftool.FileDirectory}}", "ignore_failure": true }},
{ "set": { "if": "ctx.exiftool?.Subsystem != null", "field": "host.subsystem", "value": "{{exiftool.Subsystem}}", "ignore_failure": true }},
{ "set": { "if": "ctx.scan?.yara?.matches != null", "field": "rule.name", "value": "{{scan.yara.matches.0}}" }}, { "set": { "if": "ctx.scan?.yara?.matches != null", "field": "rule.name", "value": "{{scan.yara.matches.0}}" }},
{ "set": { "if": "ctx.scan?.yara?.matches != null", "field": "dataset", "value": "alert", "override": true }}, { "set": { "if": "ctx.scan?.yara?.matches != null", "field": "dataset", "value": "alert", "override": true }},
{ "rename": { "field": "scan.hash", "target_field": "", "ignore_missing": true } }, { "rename": { "field": "file.flavors.mime", "target_field": "file.mime_type", "ignore_missing": true }},
{ "set": { "if": "ctx.rule?.name != null && ctx.rule?.score == null", "field": "event.severity", "value": 3, "override": true } }, { "set": { "if": "ctx.rule?.name != null && ctx.rule?.score == null", "field": "event.severity", "value": 3, "override": true } },
{ "convert" : { "if": "ctx.rule?.score != null", "field" : "rule.score","type": "integer"}}, { "convert" : { "if": "ctx.rule?.score != null", "field" : "rule.score","type": "integer"}},
{ "set": { "if": "ctx.rule?.score != null && ctx.rule?.score >= 0 && ctx.rule?.score <= 49", "field": "event.severity", "value": 1, "override": true } }, { "set": { "if": "ctx.rule?.score != null && ctx.rule?.score >= 0 && ctx.rule?.score <= 49", "field": "event.severity", "value": 1, "override": true } },
@@ -42,7 +62,8 @@
{ "set": { "if": "ctx.rule?.score != null && ctx.rule?.score >= 70 && ctx.rule?.score <=89", "field": "event.severity", "value": 3, "override": true } }, { "set": { "if": "ctx.rule?.score != null && ctx.rule?.score >= 70 && ctx.rule?.score <=89", "field": "event.severity", "value": 3, "override": true } },
{ "set": { "if": "ctx.rule?.score != null && ctx.rule?.score >= 90", "field": "event.severity", "value": 4, "override": true } }, { "set": { "if": "ctx.rule?.score != null && ctx.rule?.score >= 90", "field": "event.severity", "value": 4, "override": true } },
{ "set": { "field": "observer.name", "value": "{{agent.name}}" }}, { "set": { "field": "observer.name", "value": "{{agent.name}}" }},
{ "remove": { "field": ["host", "path", "message", "scan.exiftool.keys", "scan.yara.meta"], "ignore_missing": true } }, { "convert" : { "field" : "scan.exiftool","type": "string", "ignore_missing":true }},
{ "remove": { "field": ["host", "path", "message", "exiftool", "scan.yara.meta"], "ignore_missing": true } },
{ "pipeline": { "name": "common" } } { "pipeline": { "name": "common" } }
] ]
} }
+19 -3
View File
@@ -12,9 +12,25 @@
"ignore_failure": true "ignore_failure": true
} }
}, },
{ "grok": { "field": "message", "patterns": ["<%{INT:syslog.priority}>%{DATA:syslog.timestamp} %{WORD:source.application}: %{GREEDYDATA:real_message}"], "ignore_failure": false } }, {
{ "set": { "if": "ctx.source.application == 'filterlog'", "field": "dataset", "value": "firewall" } }, "grok":
{ "pipeline": { "if": "ctx.dataset == 'firewall'", "name": "filterlog" } }, {
"field": "message",
"patterns": [
"^<%{INT:syslog.priority}>%{DATA:syslog.timestamp} %{WORD:source.application}: %{GREEDYDATA:real_message}$",
"^%{SYSLOGTIMESTAMP:syslog.timestamp} %{SYSLOGHOST:syslog.host} %{SYSLOGPROG:syslog.program}: CEF:0\\|%{DATA:vendor}\\|%{DATA:product}\\|%{GREEDYDATA:message2}$"
],
"ignore_failure": true
}
},
{ "set": { "if": "ctx.source?.application == 'filterlog'", "field": "dataset", "value": "firewall", "ignore_failure": true } },
{ "set": { "if": "ctx.vendor != null", "field": "module", "value": "{{ vendor }}", "ignore_failure": true } },
{ "set": { "if": "ctx.product != null", "field": "dataset", "value": "{{ product }}", "ignore_failure": true } },
{ "set": { "field": "ingest.timestamp", "value": "{{ @timestamp }}" } },
{ "date": { "if": "ctx.syslog?.timestamp != null", "field": "syslog.timestamp", "target_field": "@timestamp", "formats": ["MMM d HH:mm:ss", "MMM dd HH:mm:ss", "ISO8601", "UNIX"], "ignore_failure": true } },
{ "remove": { "field": ["pid", "program"], "ignore_missing": true, "ignore_failure": true } },
{ "pipeline": { "if": "ctx.vendor != null && ctx.product != null", "name": "{{ vendor }}.{{ product }}", "ignore_failure": true } },
{ "pipeline": { "if": "ctx.dataset == 'firewall'", "name": "filterlog", "ignore_failure": true } },
{ "pipeline": { "name": "common" } } { "pipeline": { "name": "common" } }
] ]
} }
+17 -17
View File
@@ -30,40 +30,40 @@
{ "rename": { "field": "winlog.event_data.DestinationHostname", "target_field": "destination.hostname", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.DestinationHostname", "target_field": "destination.hostname", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.DestinationIp", "target_field": "destination.ip", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.DestinationIp", "target_field": "destination.ip", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.DestinationPort", "target_field": "destination.port", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.DestinationPort", "target_field": "destination.port", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.image", "target_field": "process.executable", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.image", "target_field": "process.executable", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.Image", "target_field": "process.executable", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.Image", "target_field": "process.executable", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.processID", "target_field": "process.pid", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.processID", "target_field": "process.pid", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.ProcessID", "target_field": "process.pid", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.ProcessId", "target_field": "process.pid", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.processGuid", "target_field": "process.entity_id", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.processGuid", "target_field": "process.entity_id", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.ProcessGuid", "target_field": "process.entity_id", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.ProcessGuid", "target_field": "process.entity_id", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.commandLine", "target_field": "process.command_line", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.commandLine", "target_field": "process.command_line", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.CommandLine", "target_field": "process.command_line", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.CommandLine", "target_field": "process.command_line", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.currentDirectory", "target_field": "process.working_directory", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.currentDirectory", "target_field": "process.working_directory", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.CurrentDirectory", "target_field": "process.working_directory", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.CurrentDirectory", "target_field": "process.working_directory", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.description", "target_field": "process.pe.description", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.description", "target_field": "process.pe.description", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.Description", "target_field": "process.pe.description", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.Description", "target_field": "process.pe.description", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.product", "target_field": "process.pe.product", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.product", "target_field": "process.pe.product", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.Product", "target_field": "process.pe.product", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.Product", "target_field": "process.pe.product", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.company", "target_field": "process.pe.company", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.company", "target_field": "process.pe.company", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.Company", "target_field": "process.pe.company", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.Company", "target_field": "process.pe.company", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.originalFileName", "target_field": "process.pe.original_file_name", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.originalFileName", "target_field": "process.pe.original_file_name", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.OriginalFileName", "target_field": "process.pe.original_file_name", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.OriginalFileName", "target_field": "process.pe.original_file_name", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.fileVersion", "target_field": "process.pe.file_version", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.fileVersion", "target_field": "process.pe.file_version", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.FileVersion", "target_field": "process.pe.file_version", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.FileVersion", "target_field": "process.pe.file_version", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.parentCommandLine", "target_field": "process.parent.command_line", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.parentCommandLine", "target_field": "process.parent.command_line", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.ParentCommandLine", "target_field": "process.parent.command_line", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.ParentCommandLine", "target_field": "process.parent.command_line", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.parentImage", "target_field": "process.parent.executable", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.parentImage", "target_field": "process.parent.executable", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.ParentImage", "target_field": "process.parent.executable", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.ParentImage", "target_field": "process.parent.executable", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.parentProcessGuid", "target_field": "process.parent.entity_id", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.parentProcessGuid", "target_field": "process.parent.entity_id", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.ParentProcessGuid", "target_field": "process.parent.entity_id", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.ParentProcessGuid", "target_field": "process.parent.entity_id", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.parentProcessId", "target_field": "process.ppid", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.parentProcessId", "target_field": "process.ppid", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.ParentProcessId", "target_field": "process.ppid", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.ParentProcessId", "target_field": "process.ppid", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.Protocol", "target_field": "network.transport", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.Protocol", "target_field": "network.transport", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.User", "target_field": "user.name", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.User", "target_field": "user.name", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.SourceHostname", "target_field": "source.hostname", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.SourceHostname", "target_field": "source.hostname", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.SourceIp", "target_field": "source.ip", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.SourceIp", "target_field": "source.ip", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.SourcePort", "target_field": "source.port", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.SourcePort", "target_field": "source.port", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.targetFilename", "target_field": "file.target", "ignore_missing": true } }, { "rename": { "field": "winlog.event_data.targetFilename", "target_field": "file.target", "ignore_missing": true } },
{ "rename": { "field": "winlog.event_data.TargetFilename", "target_field": "file.target", "ignore_missing": true } } { "rename": { "field": "winlog.event_data.TargetFilename", "target_field": "file.target", "ignore_missing": true } }
] ]
} }
+2 -1
View File
@@ -1,7 +1,8 @@
{ {
"description" : "zeek.common", "description" : "zeek.common",
"processors" : [ "processors" : [
{ "rename": { "field": "@timestamp", "target_field": "ingest.timestamp", "ignore_missing": true } }, { "rename": { "if": "ctx.message2?.ts != null", "field": "@timestamp", "target_field": "ingest.timestamp", "ignore_missing": true } },
{ "set": { "if": "ctx.message2?.ts == null", "field": "ingest.timestamp", "value": "{{ @timestamp }}" } },
{ "rename": { "field": "message2.uid", "target_field": "log.id.uid", "ignore_missing": true } }, { "rename": { "field": "message2.uid", "target_field": "log.id.uid", "ignore_missing": true } },
{ "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } }, { "dot_expander": { "field": "id.orig_h", "path": "message2", "ignore_failure": true } },
{ "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } }, { "dot_expander": { "field": "id.orig_p", "path": "message2", "ignore_failure": true } },
@@ -28,9 +28,9 @@ COUNT=0
ELASTICSEARCH_CONNECTED="no" ELASTICSEARCH_CONNECTED="no"
while [[ "$COUNT" -le 240 ]]; do while [[ "$COUNT" -le 240 ]]; do
{% if grains['role'] in ['so-node','so-heavynode'] %} {% if grains['role'] in ['so-node','so-heavynode'] %}
curl ${ELASTICSEARCH_AUTH} -k --output /dev/null --silent --head --fail https://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT" curl ${ELASTICSEARCH_AUTH} -k --output /dev/null --silent --head --fail -L https://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT"
{% else %} {% else %}
curl ${ELASTICSEARCH_AUTH} --output /dev/null --silent --head --fail http://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT" curl ${ELASTICSEARCH_AUTH} --output /dev/null --silent --head --fail -L http://"$ELASTICSEARCH_HOST":"$ELASTICSEARCH_PORT"
{% endif %} {% endif %}
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
ELASTICSEARCH_CONNECTED="yes" ELASTICSEARCH_CONNECTED="yes"
@@ -52,9 +52,9 @@ cd ${ELASTICSEARCH_INGEST_PIPELINES}
echo "Loading pipelines..." echo "Loading pipelines..."
{% if grains['role'] in ['so-node','so-heavynode'] %} {% if grains['role'] in ['so-node','so-heavynode'] %}
for i in *; do echo $i; RESPONSE=$(curl ${ELASTICSEARCH_AUTH} -k -XPUT https://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_ingest/pipeline/$i -H 'Content-Type: application/json' -d@$i 2>/dev/null); echo $RESPONSE; if [[ "$RESPONSE" == *"error"* ]]; then RETURN_CODE=1; fi; done for i in *; do echo $i; RESPONSE=$(curl ${ELASTICSEARCH_AUTH} -k -XPUT -L https://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_ingest/pipeline/$i -H 'Content-Type: application/json' -d@$i 2>/dev/null); echo $RESPONSE; if [[ "$RESPONSE" == *"error"* ]]; then RETURN_CODE=1; fi; done
{% else %} {% else %}
for i in *; do echo $i; RESPONSE=$(curl ${ELASTICSEARCH_AUTH} -XPUT http://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_ingest/pipeline/$i -H 'Content-Type: application/json' -d@$i 2>/dev/null); echo $RESPONSE; if [[ "$RESPONSE" == *"error"* ]]; then RETURN_CODE=1; fi; done for i in *; do echo $i; RESPONSE=$(curl ${ELASTICSEARCH_AUTH} -XPUT -L http://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/_ingest/pipeline/$i -H 'Content-Type: application/json' -d@$i 2>/dev/null); echo $RESPONSE; if [[ "$RESPONSE" == *"error"* ]]; then RETURN_CODE=1; fi; done
{% endif %} {% endif %}
echo echo
+5 -1
View File
@@ -215,13 +215,17 @@ so-elasticsearch:
- /etc/pki/ca.crt:/usr/share/elasticsearch/config/ca.crt:ro - /etc/pki/ca.crt:/usr/share/elasticsearch/config/ca.crt:ro
- /etc/pki/elasticsearch.p12:/usr/share/elasticsearch/config/elasticsearch.p12:ro - /etc/pki/elasticsearch.p12:/usr/share/elasticsearch/config/elasticsearch.p12:ro
- /opt/so/conf/elasticsearch/sotls.yml:/usr/share/elasticsearch/config/sotls.yml:ro - /opt/so/conf/elasticsearch/sotls.yml:/usr/share/elasticsearch/config/sotls.yml:ro
- watch: - watch:
- file: cacertz - file: cacertz
- file: esyml - file: esyml
- file: esingestconf - file: esingestconf
- file: so-elasticsearch-pipelines-file - file: so-elasticsearch-pipelines-file
append_so-elasticsearch_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-elasticsearch
so-elasticsearch-pipelines-file: so-elasticsearch-pipelines-file:
file.managed: file.managed:
- name: /opt/so/conf/elasticsearch/so-elasticsearch-pipelines - name: /opt/so/conf/elasticsearch/so-elasticsearch-pipelines
@@ -253,6 +253,20 @@
"type":"object", "type":"object",
"dynamic": true "dynamic": true
}, },
"intel":{
"type":"object",
"dynamic": true,
"properties":{
"indicator":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword"
}
}
}
}
},
"interface":{ "interface":{
"type":"object", "type":"object",
"dynamic": true "dynamic": true
@@ -365,9 +379,14 @@
} }
} }
}, },
"scan":{ "scan":{
"type":"object", "type":"object",
"dynamic": true "dynamic": true,
"properties":{
"exiftool":{
"type":"text"
}
}
}, },
"server":{ "server":{
"type":"object", "type":"object",
@@ -474,6 +493,9 @@
}, },
"event_data":{ "event_data":{
"type":"object" "type":"object"
},
"version":{
"type":"long"
} }
} }
}, },
+11 -10
View File
@@ -74,7 +74,6 @@ filebeat.modules:
# List of prospectors to fetch data. # List of prospectors to fetch data.
filebeat.inputs: filebeat.inputs:
#------------------------------ Log prospector -------------------------------- #------------------------------ Log prospector --------------------------------
{%- if grains['role'] in ['so-sensor', "so-eval", "so-helix", "so-heavynode", "so-standalone", "so-import"] %}
- type: udp - type: udp
enabled: true enabled: true
host: "0.0.0.0:514" host: "0.0.0.0:514"
@@ -82,7 +81,7 @@ filebeat.inputs:
module: syslog module: syslog
dataset: syslog dataset: syslog
pipeline: "syslog" pipeline: "syslog"
index: "so-syslog-%{+yyyy.MM.dd}" index: "so-syslog"
processors: processors:
- drop_fields: - drop_fields:
fields: ["source", "prospector", "input", "offset", "beat"] fields: ["source", "prospector", "input", "offset", "beat"]
@@ -95,11 +94,13 @@ filebeat.inputs:
module: syslog module: syslog
dataset: syslog dataset: syslog
pipeline: "syslog" pipeline: "syslog"
index: "so-syslog-%{+yyyy.MM.dd}" index: "so-syslog"
processors: processors:
- drop_fields: - drop_fields:
fields: ["source", "prospector", "input", "offset", "beat"] fields: ["source", "prospector", "input", "offset", "beat"]
fields_under_root: true fields_under_root: true
{%- if grains['role'] in ['so-eval', 'so-standalone', 'so-sensor', 'so-helix', 'so-heavynode', 'so-import'] %}
{%- if ZEEKVER != 'SURICATA' %} {%- if ZEEKVER != 'SURICATA' %}
{%- for LOGNAME in salt['pillar.get']('zeeklogs:enabled', '') %} {%- for LOGNAME in salt['pillar.get']('zeeklogs:enabled', '') %}
- type: log - type: log
@@ -114,7 +115,7 @@ filebeat.inputs:
fields: ["source", "prospector", "input", "offset", "beat"] fields: ["source", "prospector", "input", "offset", "beat"]
fields_under_root: true fields_under_root: true
clean_removed: false clean_removed: true
close_removed: false close_removed: false
- type: log - type: log
@@ -259,22 +260,22 @@ output.elasticsearch:
pipelines: pipelines:
- pipeline: "%{[module]}.%{[dataset]}" - pipeline: "%{[module]}.%{[dataset]}"
indices: indices:
- index: "so-import-%{+yyyy.MM.dd}" - index: "so-import"
when.contains: when.contains:
tags: "import" tags: "import"
- index: "so-zeek-%{+yyyy.MM.dd}" - index: "so-zeek"
when.contains: when.contains:
module: "zeek" module: "zeek"
- index: "so-ids-%{+yyyy.MM.dd}" - index: "so-ids"
when.contains: when.contains:
module: "suricata" module: "suricata"
- index: "so-ossec-%{+yyyy.MM.dd}" - index: "so-ossec"
when.contains: when.contains:
module: "ossec" module: "ossec"
- index: "so-osquery-%{+yyyy.MM.dd}" - index: "so-osquery"
when.contains: when.contains:
module: "osquery" module: "osquery"
- index: "so-strelka-%{+yyyy.MM.dd}" - index: "so-strelka"
when.contains: when.contains:
module: "strelka" module: "strelka"
+12 -3
View File
@@ -18,6 +18,9 @@
{% set VERSION = salt['pillar.get']('global:soversion', 'HH1.2.2') %} {% set VERSION = salt['pillar.get']('global:soversion', 'HH1.2.2') %}
{% set IMAGEREPO = salt['pillar.get']('global:imagerepo') %} {% set IMAGEREPO = salt['pillar.get']('global:imagerepo') %}
{% set LOCALHOSTNAME = salt['grains.get']('host') %}
{% set MAININT = salt['pillar.get']('host:mainint') %}
{% set LOCALHOSTIP = salt['grains.get']('ip_interfaces').get(MAININT)[0] %}
{% set MANAGER = salt['grains.get']('master') %} {% set MANAGER = salt['grains.get']('master') %}
{% set MANAGERIP = salt['pillar.get']('global:managerip', '') %} {% set MANAGERIP = salt['pillar.get']('global:managerip', '') %}
{% set FEATURES = salt['pillar.get']('elastic:features', False) %} {% set FEATURES = salt['pillar.get']('elastic:features', False) %}
@@ -55,8 +58,8 @@ filebeatconfsync:
file.managed: file.managed:
- name: /opt/so/conf/filebeat/etc/filebeat.yml - name: /opt/so/conf/filebeat/etc/filebeat.yml
- source: salt://filebeat/etc/filebeat.yml - source: salt://filebeat/etc/filebeat.yml
- user: 0 - user: root
- group: 0 - group: root
- template: jinja - template: jinja
- defaults: - defaults:
INPUTS: {{ salt['pillar.get']('filebeat:config:inputs', {}) }} INPUTS: {{ salt['pillar.get']('filebeat:config:inputs', {}) }}
@@ -66,7 +69,7 @@ so-filebeat:
- image: {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-filebeat:{{ VERSION }}{{ FEATURES }} - image: {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-filebeat:{{ VERSION }}{{ FEATURES }}
- hostname: so-filebeat - hostname: so-filebeat
- user: root - user: root
- extra_hosts: {{ MANAGER }}:{{ MANAGERIP }} - extra_hosts: {{ MANAGER }}:{{ MANAGERIP }},{{ LOCALHOSTNAME }}:{{ LOCALHOSTIP }}
- binds: - binds:
- /nsm:/nsm:ro - /nsm:/nsm:ro
- /opt/so/log/filebeat:/usr/share/filebeat/logs:rw - /opt/so/log/filebeat:/usr/share/filebeat/logs:rw
@@ -79,9 +82,15 @@ so-filebeat:
- /etc/ssl/certs/intca.crt:/usr/share/filebeat/intraca.crt:ro - /etc/ssl/certs/intca.crt:/usr/share/filebeat/intraca.crt:ro
- port_bindings: - port_bindings:
- 0.0.0.0:514:514/udp - 0.0.0.0:514:514/udp
- 0.0.0.0:514:514/tcp
- watch: - watch:
- file: /opt/so/conf/filebeat/etc/filebeat.yml - file: /opt/so/conf/filebeat/etc/filebeat.yml
append_so-filebeat_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-filebeat
{% else %} {% else %}
filebeat_state_not_allowed: filebeat_state_not_allowed:
+12 -3
View File
@@ -134,6 +134,7 @@ role:
- {{ portgroups.redis }} - {{ portgroups.redis }}
- {{ portgroups.minio }} - {{ portgroups.minio }}
- {{ portgroups.elasticsearch_node }} - {{ portgroups.elasticsearch_node }}
- {{ portgroups.beats_5644 }}
self: self:
portgroups: portgroups:
- {{ portgroups.syslog}} - {{ portgroups.syslog}}
@@ -424,6 +425,9 @@ role:
elasticsearch_rest: elasticsearch_rest:
portgroups: portgroups:
- {{ portgroups.elasticsearch_rest }} - {{ portgroups.elasticsearch_rest }}
self:
portgroups:
- {{ portgroups.syslog}}
INPUT: INPUT:
hostgroups: hostgroups:
anywhere: anywhere:
@@ -437,6 +441,11 @@ role:
- {{ portgroups.all }} - {{ portgroups.all }}
sensor: sensor:
chain: chain:
DOCKER-USER:
hostgroups:
self:
portgroups:
- {{ portgroups.syslog}}
INPUT: INPUT:
hostgroups: hostgroups:
anywhere: anywhere:
@@ -463,6 +472,9 @@ role:
elasticsearch_rest: elasticsearch_rest:
portgroups: portgroups:
- {{ portgroups.elasticsearch_rest }} - {{ portgroups.elasticsearch_rest }}
self:
portgroups:
- {{ portgroups.syslog}}
INPUT: INPUT:
hostgroups: hostgroups:
anywhere: anywhere:
@@ -530,9 +542,6 @@ role:
portgroups: portgroups:
- {{ portgroups.redis }} - {{ portgroups.redis }}
- {{ portgroups.elasticsearch_node }} - {{ portgroups.elasticsearch_node }}
self:
portgroups:
- {{ portgroups.syslog}}
beats_endpoint: beats_endpoint:
portgroups: portgroups:
- {{ portgroups.beats_5044 }} - {{ portgroups.beats_5044 }}
+2 -1
View File
@@ -1,3 +1,4 @@
{%- set DNET = salt['pillar.get']('global:dockernet', '172.17.0.0') %}
firewall: firewall:
hostgroups: hostgroups:
anywhere: anywhere:
@@ -9,7 +10,7 @@ firewall:
ips: ips:
delete: delete:
insert: insert:
- 172.17.0.0/24 - {{ DNET }}/24
localhost: localhost:
ips: ips:
delete: delete:
+1 -3
View File
@@ -1,4 +1,3 @@
{% set ENROLLSECRET = salt['cmd.run']('docker exec so-fleet fleetctl get enroll-secret default') %}
{% set MAININT = salt['pillar.get']('host:mainint') %} {% set MAININT = salt['pillar.get']('host:mainint') %}
{% set MAINIP = salt['grains.get']('ip_interfaces').get(MAININT)[0] %} {% set MAINIP = salt['grains.get']('ip_interfaces').get(MAININT)[0] %}
@@ -8,5 +7,4 @@ so/fleet:
action: 'enablefleet' action: 'enablefleet'
hostname: {{ grains.host }} hostname: {{ grains.host }}
mainip: {{ MAINIP }} mainip: {{ MAINIP }}
role: {{ grains.role }} role: {{ grains.role }}
enroll-secret: {{ ENROLLSECRET }}
@@ -0,0 +1,7 @@
{% set ENROLLSECRET = salt['cmd.run']('docker exec so-fleet fleetctl get enroll-secret default') %}
so/fleet:
event.send:
- data:
action: 'update-enrollsecret'
enroll-secret: {{ ENROLLSECRET }}
+9 -2
View File
@@ -12,6 +12,8 @@
{% else %} {% else %}
{% set MAINIP = salt['pillar.get']('global:managerip') %} {% set MAINIP = salt['pillar.get']('global:managerip') %}
{% endif %} {% endif %}
{% set DNET = salt['pillar.get']('global:dockernet', '172.17.0.0') %}
include: include:
- mysql - mysql
@@ -71,7 +73,7 @@ fleetdb:
fleetdbuser: fleetdbuser:
mysql_user.present: mysql_user.present:
- host: 172.17.0.0/255.255.0.0 - host: {{ DNET }}/255.255.0.0
- password: {{ FLEETPASS }} - password: {{ FLEETPASS }}
- connection_host: {{ MAINIP }} - connection_host: {{ MAINIP }}
- connection_port: 3306 - connection_port: 3306
@@ -85,7 +87,7 @@ fleetdbpriv:
- grant: all privileges - grant: all privileges
- database: fleet.* - database: fleet.*
- user: fleetdbuser - user: fleetdbuser
- host: 172.17.0.0/255.255.0.0 - host: {{ DNET }}/255.255.0.0
- connection_host: {{ MAINIP }} - connection_host: {{ MAINIP }}
- connection_port: 3306 - connection_port: 3306
- connection_user: root - connection_user: root
@@ -132,4 +134,9 @@ so-fleet:
- watch: - watch:
- /opt/so/conf/fleet/etc - /opt/so/conf/fleet/etc
append_so-fleet_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-fleet
{% endif %} {% endif %}
+7 -2
View File
@@ -43,19 +43,24 @@ freqlogdir:
so-freqimage: so-freqimage:
cmd.run: cmd.run:
- name: docker pull --disable-content-trust=false docker.io/{{ IMAGEREPO }}/so-freqserver:HH1.0.3 - name: docker pull {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-freqserver:{{ VERSION }}
so-freq: so-freq:
docker_container.running: docker_container.running:
- require: - require:
- so-freqimage - so-freqimage
- image: docker.io/{{ IMAGEREPO }}/so-freqserver:HH1.0.3 - image: {{ MANAGER }}:5000/{{ IMAGEREPO }}/so-freqserver:{{ VERSION }}
- hostname: freqserver - hostname: freqserver
- name: so-freqserver - name: so-freqserver
- user: freqserver - user: freqserver
- binds: - binds:
- /opt/so/log/freq_server:/var/log/freq_server:rw - /opt/so/log/freq_server:/var/log/freq_server:rw
append_so-freq_so-status.conf:
file.append:
- name: /opt/so/conf/so-status/so-status.conf
- text: so-freq
{% else %} {% else %}
freqserver_state_not_allowed: freqserver_state_not_allowed:
+14 -14
View File
@@ -918,11 +918,11 @@
}, },
{ {
"color": "rgba(237, 129, 40, 0.89)", "color": "rgba(237, 129, 40, 0.89)",
"value": "{{ ROOTFS * '.80'|float }}" "value": "{{ NSMFS * '.80'|float }}"
}, },
{ {
"color": "rgba(245, 54, 54, 0.9)", "color": "rgba(245, 54, 54, 0.9)",
"value": "{{ ROOTFS * '.90'|float }}" "value": "{{ NSMFS * '.90'|float }}"
} }
] ]
}, },
@@ -3565,7 +3565,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -3636,7 +3636,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -3656,7 +3656,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -4036,7 +4036,7 @@
}, },
{ {
"params": [], "params": [],
"type": "difference" "type": "non_negative_difference"
} }
] ]
], ],
@@ -4084,7 +4084,7 @@
}, },
{ {
"params": [], "params": [],
"type": "difference" "type": "non_negative_difference"
} }
] ]
], ],
@@ -4143,7 +4143,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -4214,7 +4214,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -4234,7 +4234,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -4278,7 +4278,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -4298,7 +4298,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -4621,6 +4621,6 @@
}, },
"timezone": "browser", "timezone": "browser",
"title": "Evaluation Mode - {{ SERVERNAME }} Overview", "title": "Evaluation Mode - {{ SERVERNAME }} Overview",
"uid": "so_overview", "uid": "{{ UID }}",
"version": 6 "version": 6
} }
+23 -23
View File
@@ -1795,7 +1795,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -1860,7 +1860,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -1880,7 +1880,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -1924,7 +1924,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -1944,7 +1944,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -2459,7 +2459,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -2524,7 +2524,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -2544,7 +2544,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -2588,7 +2588,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -2608,7 +2608,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3168,7 +3168,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -3233,7 +3233,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -3253,7 +3253,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3297,7 +3297,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -3317,7 +3317,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3463,7 +3463,7 @@
}, },
{ {
"params": [], "params": [],
"type": "difference" "type": "non_negative_difference"
} }
] ]
], ],
@@ -3510,7 +3510,7 @@
}, },
{ {
"params": [], "params": [],
"type": "difference" "type": "non_negative_difference"
} }
] ]
], ],
@@ -3700,7 +3700,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -3765,7 +3765,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -3785,7 +3785,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3829,7 +3829,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -3849,7 +3849,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -4168,5 +4168,5 @@
"timezone": "browser", "timezone": "browser",
"title": "Manager Node - {{ SERVERNAME }} Overview", "title": "Manager Node - {{ SERVERNAME }} Overview",
"uid": "{{ UID }}", "uid": "{{ UID }}",
"version": 3 "version": 1
} }
@@ -1799,7 +1799,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -1864,7 +1864,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -1884,7 +1884,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -1928,7 +1928,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -1948,7 +1948,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -2546,7 +2546,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -2611,7 +2611,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -2631,7 +2631,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -2675,7 +2675,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -2695,7 +2695,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3299,7 +3299,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT derivative(mean(\"rx_bytes\"), 1s) *8 FROM \"docker_container_net\" WHERE (\"host\" = '{{ SERVERNAME }}' AND \"container_name\" = 'so-influxdb') AND $timeFilter GROUP BY time($__interval) fill(null)", "query": "SELECT non_negative_derivative(mean(\"rx_bytes\"), 1s) *8 FROM \"docker_container_net\" WHERE (\"host\" = '{{ SERVERNAME }}' AND \"container_name\" = 'so-influxdb') AND $timeFilter GROUP BY time($__interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -3319,7 +3319,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3380,7 +3380,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3785,7 +3785,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3846,7 +3846,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -4164,7 +4164,7 @@
}, },
{ {
"params": [], "params": [],
"type": "difference" "type": "non_negative_difference"
} }
] ]
], ],
@@ -4211,7 +4211,7 @@
}, },
{ {
"params": [], "params": [],
"type": "difference" "type": "non_negative_difference"
} }
] ]
], ],
@@ -4912,7 +4912,7 @@
] ]
}, },
"timezone": "browser", "timezone": "browser",
"title": "Search Node - {{ SERVERNAME }} Overview", "title": "ManagerSearch Node - {{ SERVERNAME }} Overview",
"uid": "{{ UID }}", "uid": "{{ UID }}",
"variables": { "variables": {
"list": [] "list": []
@@ -2135,7 +2135,7 @@
}, },
{ {
"params": [], "params": [],
"type": "difference" "type": "non_negative_difference"
} }
] ]
], ],
@@ -2182,7 +2182,7 @@
}, },
{ {
"params": [], "params": [],
"type": "difference" "type": "non_negative_difference"
} }
] ]
], ],
@@ -2781,7 +2781,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -2846,7 +2846,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -2866,7 +2866,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -2910,7 +2910,7 @@
"measurement": "net", "measurement": "net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -2930,7 +2930,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3353,7 +3353,7 @@
"aliasColors": { "aliasColors": {
"InBound": "#629E51", "InBound": "#629E51",
"OutBound": "#5195CE", "OutBound": "#5195CE",
"net.derivative": "#1F78C1" "net.non_negative_derivative": "#1F78C1"
}, },
"bars": false, "bars": false,
"dashLength": 10, "dashLength": 10,
@@ -3418,7 +3418,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_recv\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "A", "refId": "A",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -3438,7 +3438,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [
@@ -3482,7 +3482,7 @@
"measurement": "docker_container_net", "measurement": "docker_container_net",
"orderByTime": "ASC", "orderByTime": "ASC",
"policy": "default", "policy": "default",
"query": "SELECT 8 * derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)", "query": "SELECT 8 * non_negative_derivative(mean(\"bytes_sent\"),1s) FROM \"net\" WHERE \"host\" = 'JumpHost' AND \"interface\" = 'eth0' AND $timeFilter GROUP BY time($interval) fill(null)",
"rawQuery": false, "rawQuery": false,
"refId": "B", "refId": "B",
"resultFormat": "time_series", "resultFormat": "time_series",
@@ -3502,7 +3502,7 @@
"params": [ "params": [
"1s" "1s"
], ],
"type": "derivative" "type": "non_negative_derivative"
}, },
{ {
"params": [ "params": [

Some files were not shown because too many files have changed in this diff Show More