fix conflict in salt/top.sls

This commit is contained in:
m0duspwnens
2020-04-01 13:09:23 -04:00
36 changed files with 1455 additions and 899 deletions

View File

@@ -17,10 +17,9 @@ eval:
- so-grafana
{% endif %}
- so-dockerregistry
- so-sensoroni
- so-soc
- so-kratos
- so-idstools
- so-auth-api
- so-auth-ui
{% if OSQUERY != '0' %}
- so-mysql
- so-fleet
@@ -89,12 +88,11 @@ master_search:
containers:
- so-core
- so-telegraf
- so-sensoroni
- so-soc
- so-kratos
- so-acng
- so-idstools
- so-redis
- so-auth-api
- so-auth-ui
- so-logstash
- so-elasticsearch
- so-curator
@@ -135,12 +133,11 @@ master:
- so-influxdb
- so-grafana
{% endif %}
- so-sensoroni
- so-soc
- so-kratos
- so-acng
- so-idstools
- so-redis
- so-auth-api
- so-auth-ui
- so-elasticsearch
- so-logstash
- so-kibana

View File

@@ -21,7 +21,6 @@ base:
- static
- firewall.*
- data.*
- auth
- minions.{{ grains.id }}
'*_master':
@@ -33,7 +32,6 @@ base:
- firewall.*
- data.*
- brologs
- auth
- logstash
- logstash.eval
- healthcheck.eval
@@ -63,5 +61,4 @@ base:
- static
- firewall.*
- data.*
- auth
- minions.{{ grains.id }}

View File

@@ -100,13 +100,6 @@ nginxconf:
- template: jinja
- source: salt://common/nginx/nginx.conf.{{ grains.role }}
copyindex:
file.managed:
- name: /opt/so/conf/nginx/index.html
- user: 939
- group: 939
- source: salt://common/nginx/index.html
nginxlogdir:
file.directory:
- name: /opt/so/log/nginx/
@@ -129,7 +122,6 @@ so-core:
- binds:
- /opt/so:/opt/so:rw
- /opt/so/conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- /opt/so/conf/nginx/index.html:/opt/socore/html/index.html:ro
- /opt/so/log/nginx/:/var/log/nginx:rw
- /opt/so/tmp/nginx/:/var/lib/nginx:rw
- /opt/so/tmp/nginx/:/run:rw

View File

@@ -4,7 +4,6 @@
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
@@ -107,10 +106,42 @@ http {
# Load configuration files for the default server block.
#include /etc/nginx/default.d/*.conf;
#location / {
# try_files $uri $uri.html /index.html;
# }
location ~* (^/login/|^/js/.*|^/css/.*|^/images/.*) {
proxy_pass http://{{ masterip }}:9822;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
auth_request /auth/sessions/whoami;
proxy_pass http://{{ masterip }}:9822/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /auth/ {
rewrite /auth/(.*) /$1 break;
proxy_pass http://{{ masterip }}:4433/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /grafana/ {
rewrite /grafana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:3000/;
@@ -124,7 +155,7 @@ http {
}
location /kibana/ {
auth_request /so-auth/api/auth/;
auth_request /auth/sessions/whoami;
rewrite /kibana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:5601/;
proxy_read_timeout 90;
@@ -162,7 +193,7 @@ http {
location /navigator/ {
auth_request /so-auth/api/auth/;
auth_request /auth/sessions/whoami;
proxy_pass http://{{ masterip }}:4200/navigator/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
@@ -219,22 +250,8 @@ http {
}
location /sensoroni/ {
auth_request /so-auth/api/auth/;
proxy_pass http://{{ masterip }}:9822/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /kibana/app/sensoroni/ {
rewrite ^/kibana/app/sensoroni/(.*) /sensoroni/$1 permanent;
location /kibana/app/soc/ {
rewrite ^/kibana/app/soc/(.*) /soc/$1 permanent;
}
location /kibana/app/fleet/ {
@@ -255,23 +272,11 @@ http {
proxy_set_header Proxy "";
}
location /so-auth/loginpage/ {
proxy_pass http://{{ masterip }}:4242/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /so-auth/api/ {
proxy_pass http://{{ masterip }}:5656/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
}
error_page 401 = @error401;
location @error401 {
add_header Set-Cookie "NSREDIRECT=http://{{ masterip }}$request_uri;Domain={{ masterip }};Path=/;Max-Age=60000";
return 302 http://{{ masterip }}/so-auth/loginpage/;
return 302 /auth/self-service/browser/flows/login;
}
error_page 404 /404.html;

View File

@@ -4,7 +4,6 @@
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
@@ -59,9 +58,9 @@ http {
# }
#}
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
{% if FLEET_MASTER %}
@@ -107,13 +106,45 @@ http {
# Load configuration files for the default server block.
#include /etc/nginx/default.d/*.conf;
#location / {
# try_files $uri $uri.html /index.html;
# }
location ~* (^/login/|^/js/.*|^/css/.*|^/images/.*) {
proxy_pass http://{{ masterip }}:9822;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
auth_request /auth/sessions/whoami;
proxy_pass http://{{ masterip }}:9822/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /auth/ {
rewrite /auth/(.*) /$1 break;
proxy_pass http://{{ masterip }}:4433/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /grafana/ {
rewrite /grafana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:3000/;
rewrite /grafana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:3000/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -124,9 +155,9 @@ http {
}
location /kibana/ {
auth_request /so-auth/api/auth/;
rewrite /kibana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:5601/;
auth_request /auth/sessions/whoami;
rewrite /kibana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:5601/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -150,7 +181,7 @@ http {
}
location /playbook/ {
proxy_pass http://{{ masterip }}:3200/playbook/;
proxy_pass http://{{ masterip }}:3200/playbook/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -160,9 +191,10 @@ http {
}
location /navigator/ {
auth_request /so-auth/api/auth/;
proxy_pass http://{{ masterip }}:4200/navigator/;
auth_request /auth/sessions/whoami;
proxy_pass http://{{ masterip }}:4200/navigator/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -184,10 +216,10 @@ http {
}
location /thehive/ {
proxy_pass http://{{ masterip }}:9000/thehive/;
proxy_pass http://{{ masterip }}:9000/thehive/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -196,19 +228,19 @@ http {
}
location /cortex/ {
proxy_pass http://{{ masterip }}:9001/cortex/;
proxy_pass http://{{ masterip }}:9001/cortex/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /soctopus/ {
proxy_pass http://{{ masterip }}:7000/;
proxy_pass http://{{ masterip }}:7000/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -218,22 +250,8 @@ http {
}
location /sensoroni/ {
auth_request /so-auth/api/auth/;
proxy_pass http://{{ masterip }}:9822/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /kibana/app/sensoroni/ {
rewrite ^/kibana/app/sensoroni/(.*) /sensoroni/$1 permanent;
location /kibana/app/soc/ {
rewrite ^/kibana/app/soc/(.*) /soc/$1 permanent;
}
location /kibana/app/fleet/ {
@@ -244,36 +262,21 @@ http {
rewrite ^/kibana/app/soctopus/(.*) /soctopus/$1 permanent;
}
location /sensoroniagents/ {
proxy_pass http://{{ masterip }}:9822/;
proxy_pass http://{{ masterip }}:9822/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /so-auth/loginpage/ {
proxy_pass http://{{ masterip }}:4242/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /so-auth/api/ {
proxy_pass http://{{ masterip }}:5656/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
}
error_page 401 = @error401;
location @error401 {
add_header Set-Cookie "NSREDIRECT=http://{{ masterip }}$request_uri;Domain={{ masterip }};Path=/;Max-Age=60000";
return 302 http://{{ masterip }}/so-auth/loginpage/;
return 302 /auth/self-service/browser/flows/login;
}
error_page 404 /404.html;

View File

@@ -4,7 +4,6 @@
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
@@ -59,9 +58,9 @@ http {
# }
#}
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
{% if FLEET_MASTER %}
@@ -107,13 +106,45 @@ http {
# Load configuration files for the default server block.
#include /etc/nginx/default.d/*.conf;
#location / {
# try_files $uri $uri.html /index.html;
# }
location ~* (^/login/|^/js/.*|^/css/.*|^/images/.*) {
proxy_pass http://{{ masterip }}:9822;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
auth_request /auth/sessions/whoami;
proxy_pass http://{{ masterip }}:9822/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /auth/ {
rewrite /auth/(.*) /$1 break;
proxy_pass http://{{ masterip }}:4433/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /grafana/ {
rewrite /grafana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:3000/;
rewrite /grafana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:3000/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -124,9 +155,9 @@ http {
}
location /kibana/ {
auth_request /so-auth/api/auth/;
rewrite /kibana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:5601/;
auth_request /auth/sessions/whoami;
rewrite /kibana/(.*) /$1 break;
proxy_pass http://{{ masterip }}:5601/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -136,8 +167,21 @@ http {
}
location /playbook/ {
proxy_pass http://{{ masterip }}:3200/playbook/;
location /nodered/ {
proxy_pass http://{{ masterip }}:1880/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Proxy "";
}
location /playbook/ {
proxy_pass http://{{ masterip }}:3200/playbook/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -147,9 +191,10 @@ http {
}
location /navigator/ {
auth_request /so-auth/api/auth/;
proxy_pass http://{{ masterip }}:4200/navigator/;
auth_request /auth/sessions/whoami;
proxy_pass http://{{ masterip }}:4200/navigator/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -171,10 +216,10 @@ http {
}
location /thehive/ {
proxy_pass http://{{ masterip }}:9000/thehive/;
proxy_pass http://{{ masterip }}:9000/thehive/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -183,31 +228,19 @@ http {
}
location /cortex/ {
proxy_pass http://{{ masterip }}:9001/cortex/;
proxy_pass http://{{ masterip }}:9001/cortex/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /cyberchef/ {
proxy_pass http://{{ masterip }}:9080/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_http_version 1.1; # this is essential for chunked responses to work
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /soctopus/ {
proxy_pass http://{{ masterip }}:7000/;
proxy_pass http://{{ masterip }}:7000/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
@@ -217,22 +250,8 @@ http {
}
location /sensoroni/ {
auth_request /so-auth/api/auth/;
proxy_pass http://{{ masterip }}:9822/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /kibana/app/sensoroni/ {
rewrite ^/kibana/app/sensoroni/(.*) /sensoroni/$1 permanent;
location /kibana/app/soc/ {
rewrite ^/kibana/app/soc/(.*) /soc/$1 permanent;
}
location /kibana/app/fleet/ {
@@ -243,36 +262,21 @@ http {
rewrite ^/kibana/app/soctopus/(.*) /soctopus/$1 permanent;
}
location /sensoroniagents/ {
proxy_pass http://{{ masterip }}:9822/;
proxy_pass http://{{ masterip }}:9822/;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy "";
}
location /so-auth/loginpage/ {
proxy_pass http://{{ masterip }}:4242/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /so-auth/api/ {
proxy_pass http://{{ masterip }}:5656/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
}
error_page 401 = @error401;
location @error401 {
add_header Set-Cookie "NSREDIRECT=http://{{ masterip }}$request_uri;Domain={{ masterip }};Path=/;Max-Age=60000";
return 302 http://{{ masterip }}/so-auth/loginpage/;
return 302 /auth/self-service/browser/flows/login;
}
error_page 404 /404.html;
@@ -284,4 +288,4 @@ http {
}
}
}
}

View File

@@ -17,4 +17,4 @@
. /usr/sbin/so-common
docker exec so-soctopus python3 playbook_play-sync.py
docker exec so-soctopus python3 playbook_play-sync.py >> /opt/so/log/soctopus/so-playbook-sync.log 2>&1

201
salt/common/tools/sbin/so-user Executable file
View File

@@ -0,0 +1,201 @@
#!/bin/bash
# Copyright 2020 Security Onion Solutions. All rights reserved.
#
# This program is distributed under the terms of version 2 of the
# GNU General Public License. See LICENSE for further details.
#
# 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.
got_root() {
# Make sure you are root
if [ "$(id -u)" -ne 0 ]; then
echo "This script must be run using sudo!"
exit 1
fi
}
# Make sure the user is root
got_root
if [[ $# < 1 || $# > 2 ]]; then
echo "Usage: $0 <list|add|update|delete|checkpw> [email]"
echo "Note that checkpw only checks that the given password meets the minimum requirements, it does not test that it matches for an existing user."
exit 1
fi
operation=$1
email=$2
kratosUrl=${KRATOS_URL:-http://127.0.0.1:4434}
databasePath=${KRATOS_DB_PATH:-/opt/so/conf/kratos/db/db.sqlite}
argon2Iterations=${ARGON2_ITERATIONS:-3}
argon2Memory=${ARGON2_MEMORY:-14}
argon2Parallelism=${ARGON2_PARALLELISM:-2}
argon2HashSize=${ARGON2_HASH_SIZE:-32}
function fail() {
msg=$1
echo "$1"
exit 1
}
function require() {
cmd=$1
which "$1" 2>&1 > /dev/null
[[ $? != 0 ]] && fail "This script requires the following command be installed: ${cmd}"
}
# Verify this environment is capable of running this script
require "argon2"
require "jq"
require "curl"
require "openssl"
require "sqlite3"
[[ ! -f $databasePath ]] && fail "Unable to find database file; specify path via KRATOS_DB_PATH environment variable"
response=$(curl -Ss ${kratosUrl}/)
[[ "$response" != "404 page not found" ]] && fail "Unable to communicate with Kratos; specify URL via KRATOS_URL environment variable"
function findIdByEmail() {
email=$1
response=$(curl -Ss ${kratosUrl}/identities)
identityId=$(echo "${response}" | jq ".[] | select(.addresses[0].value == \"$email\") | .id")
echo $identityId
}
function validatePassword() {
password=$1
len=$(expr length "$password")
if [[ $len -lt 6 ]]; then
echo "Password does not meet the minimum requirements"
exit 2
fi
}
function updatePassword() {
identityId=$1
# Read password from stdin (show prompt only if no stdin was piped in)
test -t 0
if [[ $? == 0 ]]; then
echo "Enter new password:"
fi
read -s password
validatePassword "$password"
if [[ -n $identityId ]]; then
# Generate password hash
salt=$(openssl rand -hex 8)
passwordHash=$(echo "${password}" | argon2 ${salt} -id -t $argon2Iterations -m $argon2Memory -p $argon2Parallelism -l $argon2HashSize -e)
# Update DB with new hash
echo "update identity_credentials set config=CAST('{\"hashed_password\":\"${passwordHash}\"}' as BLOB) where identity_id=${identityId};" | sqlite3 "$databasePath"
[[ $? != 0 ]] && fail "Unable to update password"
fi
}
function listUsers() {
response=$(curl -Ss ${kratosUrl}/identities)
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
echo "${response}" | jq -r ".[] | .addresses[0].value" | sort
}
function createUser() {
email=$1
now=$(date -u +%FT%TZ)
addUserJson=$(cat <<EOF
{
"addresses": [
{
"expires_at": "2099-01-31T12:00:00Z",
"value": "${email}",
"verified": true,
"verified_at": "${now}",
"via": "so-add-user"
}
],
"traits": {"email":"${email}"},
"traits_schema_id": "default"
}
EOF
)
response=$(curl -Ss ${kratosUrl}/identities -d "$addUserJson")
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
identityId=$(echo "${response}" | jq ".id")
if [[ ${identityId} == "null" ]]; then
code=$(echo "${response}" | jq ".error.code")
[[ "${code}" == "409" ]] && fail "User already exists"
reason=$(echo "${response}" | jq ".error.message")
[[ $? == 0 ]] && fail "Unable to add user: ${reason}"
fi
updatePassword $identityId
}
function updateUser() {
email=$1
identityId=$(findIdByEmail "$email")
[[ ${identityId} == "" ]] && fail "User not found"
updatePassword $identityId
}
function deleteUser() {
email=$1
identityId=$(findIdByEmail "$email")
[[ ${identityId} == "" ]] && fail "User not found"
response=$(curl -Ss -XDELETE "${kratosUrl}/identities/$identityId")
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
}
case "${operation}" in
"add")
[[ "$email" == "" ]] && fail "Email address must be provided"
createUser "$email"
echo "Successfully added new user"
;;
"list")
listUsers
;;
"update")
[[ "$email" == "" ]] && fail "Email address must be provided"
updateUser "$email"
echo "Successfully updated user"
;;
"delete")
[[ "$email" == "" ]] && fail "Email address must be provided"
deleteUser "$email"
echo "Successfully deleted user"
;;
"checkpw")
updatePassword
echo "Password is acceptable"
;;
*)
fail "Unsupported operation: $operation"
;;
esac
exit 0

View File

@@ -1,17 +1,2 @@
#!/bin/bash
USERNAME=$1
# Make sure a username is provided
[ $# -eq 0 ] && { echo "Usage: $0 username"; exit 1; }
# If the file is there already lets create it otherwise add the user
if [ ! -f /opt/so/conf/nginx/.htpasswd ]; then
# Create the password file
htpasswd -c /opt/so/conf/nginx/.htpasswd $USERNAME
else
htpasswd /opt/so/conf/nginx/.htpasswd $USERNAME
fi
so-user add $*

View File

@@ -34,8 +34,6 @@
#fi
# Avoid starting multiple instances
if pgrep -f "so-curator-closed-delete-delete" >/dev/null; then
echo "Script is already running."
else
if ! pgrep -f "so-curator-closed-delete-delete" >/dev/null; then
/usr/sbin/so-curator-closed-delete-delete
fi

View File

@@ -37,9 +37,11 @@
},
{ "rename": { "field": "module", "target_field": "event.module", "ignore_missing": true } },
{ "rename": { "field": "dataset", "target_field": "event.dataset", "ignore_missing": true } },
{ "rename": { "field": "category", "target_field": "event.category", "ignore_missing": true } },
{ "rename": { "field": "message2.community_id", "target_field": "network.community_id", "ignore_missing": true } },
{
"remove": {
"field": [ "index_name_prefix"],
"field": [ "index_name_prefix", "message2"],
"ignore_failure": false
}
}

View File

@@ -0,0 +1,26 @@
{
"description" : "osquery",
"processors" : [
{ "json": { "field": "message", "target_field": "message2", "ignore_failure": true } },
{
"script": {
"lang": "painless",
"source": "def dict = ['result': new HashMap()]; for (entry in ctx['message2'].entrySet()) { dict['result'][entry.getKey()] = entry.getValue(); } ctx['osquery'] = dict; "
}
},
{ "rename": { "field": "osquery.result.hostIdentifier", "target_field": "osquery.result.host_identifier", "ignore_missing": true } },
{ "rename": { "field": "osquery.result.calendarTime", "target_field": "osquery.result.calendar_time", "ignore_missing": true } },
{ "rename": { "field": "osquery.result.unixTime", "target_field": "osquery.result.unix_time", "ignore_missing": true } },
{ "json": { "field": "message", "target_field": "message3", "ignore_failure": true } },
{ "rename": { "field": "message3.columns.username", "target_field": "user.name", "ignore_missing": true } },
{ "rename": { "field": "message3.columns.uid", "target_field": "user.uid", "ignore_missing": true } },
{ "rename": { "field": "message3.columns.gid", "target_field": "user.gid", "ignore_missing": true } },
{ "rename": { "field": "message3.columns.shell", "target_field": "user.shell", "ignore_missing": true } },
{ "rename": { "field": "message3.columns.cmdline", "target_field": "process.command_line", "ignore_missing": true } },
{ "rename": { "field": "message3.columns.pid", "target_field": "process.pid", "ignore_missing": true } },
{ "rename": { "field": "message3.columns.parent", "target_field": "process.ppid", "ignore_missing": true } },
{ "rename": { "field": "message3.columns.cwd", "target_field": "process.working_directory", "ignore_missing": true } },
{ "remove": { "field": [ "message3"], "ignore_failure": false } },
{ "pipeline": { "name": "common" } }
]
}

View File

@@ -30,9 +30,9 @@
{ "rename": { "field": "data.win.eventdata.user", "target_field": "user.name", "ignore_missing": true } },
{ "rename": { "field": "data.win.system.eventID", "target_field": "event.code", "ignore_missing": true } },
{ "rename": { "field": "predecoder.program_name", "target_field": "process.name", "ignore_missing": true } },
{ "set": { "if": "ctx.rule.level == 1", "field": "category", "value": "None" } },
{ "set": { "if": "ctx.rule.level == 2", "field": "category", "value": "System low priority notification" } },
{ "set": { "if": "ctx.rule.level == 3", "field": "category", "value": "Successful/authorized event" } },
{ "set": { "if": "ctx.rule.level == 1", "field": "rule.category", "value": "None" } },
{ "set": { "if": "ctx.rule.level == 2", "field": "rule.category", "value": "System low priority notification" } },
{ "set": { "if": "ctx.rule.level == 3", "field": "rule.category", "value": "Successful/authorized event" } },
{ "set": { "if": "ctx.rule.level == 4", "field": "rule.category", "value": "System low priority error" } },
{ "set": { "if": "ctx.rule.level == 5", "field": "rule.category", "value": "User generated error" } },
{ "set": { "if": "ctx.rule.level == 6", "field": "rule.category", "value": "Low relevance attack" } },

View File

@@ -3,12 +3,12 @@
"processors" : [
{ "rename":{ "field": "message2.proto", "target_field": "network.transport", "ignore_failure": true } },
{ "rename":{ "field": "message2.flow_id", "target_field": "event.id", "ignore_failure": true } },
{ "rename":{ "field": "message2.comunity_id", "target_field": "network.comunity_id", "ignore_failure": true } },
{ "rename":{ "field": "message2.src_ip", "target_field": "source.ip", "ignore_failure": true } },
{ "rename":{ "field": "message2.src_port", "target_field": "source.port", "ignore_failure": true } },
{ "rename":{ "field": "message2.dest_ip", "target_field": "destination.ip", "ignore_failure": true } },
{ "rename":{ "field": "message2.dest_port", "target_field": "destination.port", "ignore_failure": true } },
{ "remove": { "field": ["message2", "agent"], "ignore_failure": true } },
{ "rename": { "field": "message2.community_id", "target_field": "network.community_id", "ignore_missing": true } },
{ "remove": { "field": ["agent"], "ignore_failure": true } },
{ "pipeline": { "name": "common" } }
]
}

View File

@@ -16,7 +16,7 @@
{ "rename": { "field": "message2.id.resp_p", "target_field": "destination.port", "ignore_missing": true } },
{ "set": { "field": "server.port", "value": "{{destination.port}}" } },
{ "date": { "field": "message2.ts", "target_field": "@timestamp", "formats": ["ISO8601", "UNIX"], "ignore_failure": true } },
{ "remove": { "field": ["message2.ts", "path", "agent"], "ignore_failure": true } },
{ "remove": { "field": ["agent"], "ignore_failure": true } },
{ "pipeline": { "name": "common" } }
]
}

View File

@@ -2,6 +2,7 @@
"description" : "zeek.weird",
"processors" : [
{ "remove": { "field": ["host"], "ignore_failure": true } },
{ "json": { "field": "message", "target_field": "message2", "ignore_failure": true } },
{ "rename": { "field": "message2.name", "target_field": "weird.name", "ignore_missing": true } },
{ "rename": { "field": "message2.addl", "target_field": "weird.additional_info", "ignore_missing": true } },
{ "rename": { "field": "message2.notice", "target_field": "weird.notice", "ignore_missing": true } },

View File

@@ -20,7 +20,7 @@ name: {{ HOSTNAME }}
# Sets log level. The default log level is info.
# Available log levels are: error, warning, info, debug
logging.level: error
logging.level: warning
# Enable debug output for selected components. To enable all selectors use ["*"]
# Other available selectors are "beat", "publish", "service"
@@ -82,7 +82,8 @@ filebeat.inputs:
- /nsm/zeek/logs/current/{{ LOGNAME }}.log
fields:
module: zeek
dataset: {{ LOGNAME }}
dataset: {{ LOGNAME }}
category: network
processors:
- drop_fields:
fields: ["source", "prospector", "input", "offset", "beat"]
@@ -100,6 +101,7 @@ filebeat.inputs:
fields:
module: suricata
dataset: alert
category: network
processors:
- drop_fields:
@@ -118,7 +120,7 @@ filebeat.inputs:
fields:
module: ossec
dataset: alert
category: host
processors:
- drop_fields:
fields: ["source", "prospector", "input", "offset", "beat"]
@@ -144,7 +146,9 @@ filebeat.inputs:
paths:
- /nsm/osquery/fleet/result.log
fields:
type: osquery
module: osquery
dataset: query_result
category: host
processors:
- drop_fields:
@@ -160,9 +164,10 @@ filebeat.inputs:
- type: log
paths:
- /opt/so/log/strelka/strelka.log
- /nsm/strelka/log/strelka.log
fields:
module: strelka
category: file
dataset: file
processors:
@@ -190,6 +195,12 @@ output.elasticsearch:
- index: "so-ossec-%{+yyyy.MM.dd}"
when.contains:
module: "ossec"
- index: "so-osquery-%{+yyyy.MM.dd}"
when.contains:
module: "osquery"
- index: "so-strelka-%{+yyyy.MM.dd}"
when.contains:
module: "strelka"
#output.logstash:
# Boolean flag to enable or disable the output module.

View File

@@ -56,10 +56,11 @@ so-filebeat:
- /opt/so/log/filebeat:/usr/share/filebeat/logs:rw
- /opt/so/conf/filebeat/etc/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /nsm/zeek:/nsm/zeek:ro
- /nsm/strelka/log:/nsm/strelka/log:ro
- /opt/so/log/suricata:/suricata:ro
- /opt/so/wazuh/logs/alerts:/wazuh/alerts:ro
- /opt/so/wazuh/logs/archives:/wazuh/archives:ro
- /nsm/osquery/fleet/:/osquery/logs:ro
- /nsm/osquery/fleet/:/nsm/osquery/fleet:ro
- /opt/so/conf/filebeat/etc/pki/filebeat.crt:/usr/share/filebeat/filebeat.crt:ro
- /opt/so/conf/filebeat/etc/pki/filebeat.key:/usr/share/filebeat/filebeat.key:ro
- /etc/ssl/certs/intca.crt:/usr/share/filebeat/intraca.crt:ro

View File

@@ -1,133 +0,0 @@
{%- set PACKAGESTS = salt['pillar.get']('static:fleet_packages-timestamp:', 'N/A') -%}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Security Onion - Hybrid Hunter</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />
<style>
* {
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
padding-left: 30px;
padding-right: 30px;
}
body {
font-family: Arial, Helvetica, sans-serif;
background-color: #2a2a2a;
}
a {
color: #f2f2f2;
text-align: left;
padding: 0px;
}
.center-content {
margin: 0 auto;
}
/* Style the top navigation bar */
.topnav {
overflow: hidden;
background-color: #333;
width: 1080px;
display: flex;
align-content: center;
}
/* Style the topnav links */
.topnav a {
margin: auto;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
/* Change color on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
/* Style the content */
.content {
background-color: #2a2a2a;
padding: 10px;
padding-top: 20px;
padding-left: 60px;
color: #E3DBCC;
width: 1080px;
}
/* Style the footer */
.footer {
background-color: #2a2a2a;
padding: 60px;
color: #E3DBCC;
width: 1080px;
}
</style>
</head>
<body>
<div class="center-content">
<div class="topnav center-content">
<a href="/so-auth/loginpage/create-user" target="_blank">Create New User</a>
<a href="/kibana/" target="_blank">Kibana</a>
<a href="/grafana/" target="_blank">Grafana</a>
<a href="/sensoroni/" target="_blank">Sensoroni</a>
<a href="/playbook/" target="_blank">Playbook</a>
<a href="/fleet/" target="_blank">Fleet</a>
<a href="/thehive/" target="_blank">TheHive</a>
<a href="/packages/" target="_blank">Osquery Packages</a>
<a href="https://github.com/Security-Onion-Solutions/securityonion-saltstack/wiki/FAQ" target="_blank">FAQ</a>
<a href="https://www.securityonionsolutions.com" target="_blank">Security Onion Solutions</a>
<a href="https://blog.securityonion.net" target="_blank">Blog</a>
</div>
<div class="content center-content">
<p>
<div style="text-align: center;">
<h1>Osquery Packages</h1>
</div>
<br/>
<h2>Notes</h2>
<ul>
<li>These packages are customized for this specific Fleet install and will only be generated after the Fleet setup script has been run. If you want vanilla osquery packages, you can get them directly from <a href="https://osquery.io/downloads">osquery.io</a></li>
<li>Packages are not signed.</li>
</ul>
<br/>
<h2>Downloads</h2>
<div>
Generated: {{ PACKAGESTS }}
<br/>
<br/>
Packages:
<ul>
<li><a href="/packages/launcher.msi" download="msi-launcher.msi">MSI (Windows)</a></li>
<li><a href="/packages/launcher.deb" download="deb-launcher.deb">DEB (Debian)</a></li>
<li><a href="/packages/launcher.rpm" download="rpm-launcher.rpm">RPM (RPM)</a></li>
<li><a href="/packages/launcher.pkg" download="pkg-launcher.pkg">PKG (MacOS)</a></li>
</ul>
<br/>
<br/>
Config Files:
<ul>
<li><a href="/packages/launcher.flags" download="launcher.flags.txt">RPM & DEB Flag File</a></li>
<li><a href="/packages/launcher-msi.flags" download="launcher-msi.flags.txt">MSI Flag File</a></li>
</ul>
</div>
<br/>
<h2>Known Issues</h2>
<ul>
<li>None</li>
</ul>
</p>
</div>
</div>
</body>
</html>

View File

@@ -5,11 +5,11 @@ spec:
decorators:
always:
- SELECT codename FROM os_version;
- SELECT uuid AS LiveQuery FROM system_info;
- SELECT address AS EndpointIP1 FROM interface_addresses where address not
- SELECT uuid AS live_query FROM system_info;
- SELECT address AS endpoint_ip1 FROM interface_addresses where address not
like '%:%' and address not like '127%' and address not like '169%' order by
interface desc limit 1;
- SELECT address AS EndpointIP2 FROM interface_addresses where address not
- SELECT address AS endpoint_ip2 FROM interface_addresses where address not
like '%:%' and address not like '127%' and address not like '169%' order by
interface asc limit 1;
- SELECT hardware_serial FROM system_info;

View File

@@ -30,4 +30,4 @@ cp /opt/so/conf/fleet/packages/launcher.* /opt/so/saltstack/salt/launcher/packag
#Update timestamp on packages webpage
sed -i "s@.*Generated.*@Generated: $(date '+%m%d%Y')@g" /opt/so/conf/fleet/packages/index.html
sed -i "s@.*Generated.*@Generated: $(date '+%m%d%Y')@g" /opt/so/saltstack/salt/fleet/osquery-packages.html
sed -i "s@.*Generated.*@Generated: $(date '+%m%d%Y')@g" /opt/so/saltstack/salt/fleet/files/dedicated-index.html

View File

@@ -50,7 +50,7 @@ fleetpacksync:
- user: 939
- group: 939
fleetpackagessync:
fleetpackagessync:
file.recurse:
- name: /opt/so/conf/fleet/packages
- source: salt://fleet/packages/
@@ -76,11 +76,7 @@ fleetsetupscripts:
osquerypackageswebpage:
file.managed:
- name: /opt/so/conf/fleet/packages/index.html
{% if FLEETARCH == "so-fleet" %}
- source: salt://fleet/files/dedicated-index.html
{% else %}
- source: salt://fleet/files/osquery-packages.html
{% endif %}
- template: jinja
fleetdb:

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
{
"index_patterns": ["so-ids-*", "so-firewall-*", "so-syslog-*", "so-zeek-*", "so-import-*", "so-ossec-*", "so-strelka-*", "so-beats-*"],
"index_patterns": ["so-ids-*", "so-firewall-*", "so-syslog-*", "so-zeek-*", "so-import-*", "so-ossec-*", "so-strelka-*", "so-beats-*", "so-osquery-*"],
"version":50001,
"order" : 10,
"settings":{
@@ -252,6 +252,10 @@
"type":"object",
"dynamic": true
},
"request":{
"type":"object",
"dynamic": true
},
"rfb":{
"type":"object",
"dynamic": true
@@ -260,6 +264,10 @@
"type":"object",
"dynamic": true
},
"scan":{
"type":"object",
"dynamic": true
},
"server":{
"type":"object",
"dynamic": true

View File

@@ -1,12 +1,13 @@
#!/bin/bash
MASTER={{ MASTER }}
VERSION="HH1.1.4"
VERSION="HH1.2.1"
TRUSTED_CONTAINERS=( \
"so-core:$VERSION" \
"so-cyberchef:$VERSION" \
"so-acng:$VERSION" \
"so-sensoroni:$VERSION" \
"so-soc:$VERSION" \
"so-kratos:$VERSION" \
"so-fleet:$VERSION" \
"so-soctopus:$VERSION" \
"so-steno:$VERSION" \

View File

@@ -0,0 +1,78 @@
{%- set WEBACCESS = salt['pillar.get']('kratos:redirect', '') -%}
{%- set KRATOSKEY = salt['pillar.get']('kratos:kratoskey', '') -%}
selfservice:
strategies:
password:
enabled: true
verify:
return_to: https://{{ WEBACCESS }}/
logout:
redirect_to: https://{{ WEBACCESS }}/login/
login:
request_lifespan: 10m
after:
password:
-
job: session
-
job: redirect
config:
default_redirect_url: https://{{ WEBACCESS }}/
allow_user_defined_redirect: true
registration:
request_lifespan: 10m
after:
password:
-
job: verify
-
job: session
-
job: redirect
config:
default_redirect_url: https://{{ WEBACCESS }}/
allow_user_defined_redirect: true
log:
level: debug
format: json
secrets:
session:
- {{ KRATOSKEY }}
urls:
login_ui: https://{{ WEBACCESS }}/login/
registration_ui: https://{{ WEBACCESS }}/login/
error_ui: https://{{ WEBACCESS }}/login/
profile_ui: https://{{ WEBACCESS }}/
verify_ui: https://{{ WEBACCESS }}/
mfa_ui: https://{{ WEBACCESS }}/
self:
public: https://{{ WEBACCESS }}/auth/
admin: https://{{ WEBACCESS }}/kratos/
default_return_to: https://{{ WEBACCESS }}/
whitelisted_return_to_domains:
- http://127.0.0.1
hashers:
argon2:
parallelism: 2
memory: 16384
iterations: 3
salt_length: 16
key_length: 32
identity:
traits:
default_schema_url: file:///kratos-conf/schema.json
courier:
smtp:
connection_uri: smtps://{{ WEBACCESS }}:25

View File

@@ -0,0 +1,28 @@
{
"$id": "securityonion.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"title": "E-Mail",
"minLength": 6,
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
}
},
"verification": {
"via": "email"
}
}
}
},
"required": [
"email"
],
"additionalProperties": false
}

View File

@@ -0,0 +1,23 @@
{
"title": "Introducing Hybrid Hunter 1.2.1 Beta",
"changes": [
{ "summary": "New authentication framework" },
{ "summary": "New Logstash pipeline setup. Now uses multiple pipelines." },
{ "summary": "New Master + Search node type and well as a Heavy Node type in the install." },
{ "summary": "Change all nodes to point to the docker registry on the Master. This cuts down on the calls to dockerhub." },
{ "summary": "Upgraded to Zeek 3.0" },
{ "summary": "Upgraded to Elastic 7.6" },
{ "summary": "New SO Start | Stop | Restart scripts for all components (eg. `so-playbook-restart`)." },
{ "summary": "BPF support for Suricata (NIDS), Steno (PCAP) & Zeek (<a target='new' href='https://github.com/Security-Onion-Solutions/securityonion-saltstack/wiki/BPF'>More Info</a>)." },
{ "summary": "Updated Domain Stats & Frequency Server containers to Python3 & created new Salt states for them." },
{ "summary": "Added so-status script which gives an easy to read look at container status." },
{ "summary": "Manage threshold.conf for Suricata using the thresholding pillar." },
{ "summary": "The ISO now includes all the docker containers for faster install speeds." },
{ "summary": "You now set the password for the onion account during the iso install. This account is temporary and will be removed after so-setup." },
{ "summary": "Updated Helix parsers for better compatibility." },
{ "summary": "Updated telegraf docker to include curl and jq." },
{ "summary": "CVE-2020-0601 Zeek Detection Script." },
{ "summary": "ISO Install now prompts you to create a password for the onion user during imaging. This account gets disabled during setup." },
{ "summary": "Check out the Hybrid Hunter Quick Start Guide." }
]
}

View File

@@ -0,0 +1,26 @@
{%- set MASTERIP = salt['pillar.get']('static:masterip', '') -%}
{%- set SENSORONIKEY = salt['pillar.get']('static:sensoronikey', '') -%}
{
"logFilename": "/opt/sensoroni/logs/sensoroni-server.log",
"server": {
"bindAddress": "0.0.0.0:9822",
"baseUrl": "/",
"maxPacketCount": 5000,
"htmlDir": "html",
"modules": {
"filedatastore": {
"jobDir": "jobs"
},
"securityonion": {
"elasticsearchHost": "http://{{ MASTERIP }}:9200",
"elasticsearchUsername": "",
"elasticsearchPassword": "",
"elasticsearchVerifyCert": false
},
"statickeyauth": {
"anonymousCidr": "172.17.0.0/24",
"apiKey": "{{ SENSORONIKEY }}"
}
}
}
}

97
salt/soc/init.sls Normal file
View File

@@ -0,0 +1,97 @@
{% set VERSION = salt['pillar.get']('static:soversion', 'HH1.2.1') %}
{% set MASTER = salt['grains.get']('master') %}
socdir:
file.directory:
- name: /opt/so/conf/soc
- user: 939
- group: 939
- makedirs: True
socdatadir:
file.directory:
- name: /nsm/soc/jobs
- user: 939
- group: 939
- makedirs: True
soclogdir:
file.directory:
- name: /opt/so/log/soc
- user: 939
- group: 939
- makedirs: True
socsync:
file.recurse:
- name: /opt/so/conf/soc
- source: salt://soc/files/soc
- user: 939
- group: 939
- template: jinja
so-soc:
docker_container.running:
- image: {{ MASTER }}:5000/soshybridhunter/so-soc:{{ VERSION }}
- hostname: soc
- name: so-soc
- binds:
- /nsm/soc/jobs:/opt/sensoroni/jobs:rw
- /opt/so/conf/soc/soc.json:/opt/sensoroni/sensoroni.json:ro
- /opt/so/conf/soc/changes.json:/opt/sensoroni/html/changes.json:ro
- /opt/so/log/soc/:/opt/sensoroni/logs/:rw
- port_bindings:
- 0.0.0.0:9822:9822
- watch:
- file: /opt/so/conf/soc
# Add Kratos Group
kratosgroup:
group.present:
- name: kratos
- gid: 928
# Add Kratos user
kratos:
user.present:
- uid: 928
- gid: 928
- home: /opt/so/conf/kratos
kratosdir:
file.directory:
- name: /opt/so/conf/kratos/db
- user: 928
- group: 928
- makedirs: True
kratoslogdir:
file.directory:
- name: /opt/so/log/kratos
- user: 928
- group: 928
- makedirs: True
kratossync:
file.recurse:
- name: /opt/so/conf/kratos
- source: salt://soc/files/kratos
- user: 928
- group: 928
- template: jinja
so-kratos:
docker_container.running:
- image: {{ MASTER }}:5000/soshybridhunter/so-kratos:{{ VERSION }}
- hostname: kratos
- name: so-kratos
- binds:
- /opt/so/conf/kratos/schema.json:/kratos-conf/schema.json:ro
- /opt/so/conf/kratos/kratos.yaml:/kratos-conf/kratos.yaml:ro
- /opt/so/log/kratos/:/kratos-log:rw
- /opt/so/conf/kratos/db:/kratos-data:rw
- port_bindings:
- 0.0.0.0:4433:4433
- 0.0.0.0:4434:4434
- watch:
- file: /opt/so/conf/kratos

View File

@@ -23,14 +23,6 @@ strelkaconfdir:
- group: 939
- makedirs: True
# Strelka logs
strelkalogdir:
file.directory:
- name: /opt/so/log/strelka
- user: 939
- group: 939
- makedirs: True
# Sync dynamic config to conf dir
strelkasync:
file.recurse:
@@ -47,6 +39,13 @@ strelkadatadir:
- group: 939
- makedirs: True
strelkalogdir:
file.directory:
- name: /nsm/strelka/log
- user: 939
- group: 939
- makedirs: True
strelkastagedir:
file.directory:
- name: /nsm/strelka/processed
@@ -75,7 +74,7 @@ strelka_frontend:
- image: soshybridhunter/so-strelka-frontend:HH1.2.1
- binds:
- /opt/so/conf/strelka/frontend/:/etc/strelka/:ro
- /opt/so/log/strelka/:/var/log/strelka/:rw
- /nsm/strelka/log/:/var/log/strelka/:rw
- privileged: True
- name: so-strelka-frontend
- command: strelka-frontend

View File

@@ -6,6 +6,7 @@
{%- set DOMAINSTATS = salt['pillar.get']('master:domainstats', '0') -%}
{%- set FLEETMASTER = salt['pillar.get']('static:fleet_master', False) -%}
{%- set FLEETNODE = salt['pillar.get']('static:fleet_node', False) -%}
{%- set STRELKA = salt['pillar.get']('master:strelka', '1') -%}
base:
@@ -53,7 +54,7 @@ base:
- registry
- master
- common
- sensoroni
- soc
- firewall
- idstools
- auth
@@ -65,11 +66,14 @@ base:
- wazuh
{%- endif %}
- elasticsearch
- filebeat
- kibana
- pcap
- suricata
- zeek
{%- if STRELKA %}
- strelka
{%- endif %}
- filebeat
- curator
- elastalert
{%- if FLEETMASTER or FLEETNODE %}
@@ -99,12 +103,11 @@ base:
- ssl
- registry
- common
- sensoroni
- soc
- firewall
- master
- idstools
- redis
- auth
{%- if FLEETMASTER or FLEETNODE %}
- mysql
{%- endif %}
@@ -193,7 +196,6 @@ base:
- firewall
- sensor
- master
- auth
{%- if FLEETMASTER or FLEETNODE %}
- fleet.install_package
{%- endif %}
@@ -204,13 +206,11 @@ base:
- ssl
- registry
- common
- sensoroni
- auth
- soc
- firewall
- master
- idstools
- redis
- auth
{%- if FLEETMASTER or FLEETNODE %}
- mysql
{%- endif %}

View File

@@ -78,6 +78,29 @@ add_socore_user_notmaster() {
}
wait_for_identity_db_to_exist() {
MAXATTEMPTS=30
attempts=0
while [[ $attempts -lt $MAXATTEMPTS ]]; do
# Check and see if the DB file is in there
if [ -f /opt/so/conf/kratos/db/db.sqlite ]; then
echo "Database file exists at $(date)"
attempts=$MAXATTEMPTS
else
echo "Identity database does not yet exist; waiting 5 seconds and will check again ($attempts/$MAXATTEMPTS)..."
sleep 5
attempts=$((attempts+1))
fi
done
}
add_web_user() {
wait_for_identity_db_to_exist
echo "Attempting to add administrator user for web interface..."
echo "$WEBPASSWD1" | /usr/sbin/so-user add $WEBUSER
echo "Add user result: $?"
}
# Create an auth pillar so that passwords survive re-install
auth_pillar(){
@@ -219,6 +242,16 @@ check_socore_pass() {
}
check_web_pass() {
if [ $WEBPASSWD1 == $WEBPASSWD2 ]; then
WPMATCH=yes
else
whiptail_passwords_dont_match
fi
}
checkin_at_boot() {
echo "Enabling checkin at boot" >> $SETUPLOG 2>&1
echo "startup_states: highstate" >> /etc/salt/minion
@@ -539,7 +572,8 @@ docker_seed_registry() {
"so-navigator:$VERSION" \
"so-playbook:$VERSION" \
"so-redis:$VERSION" \
"so-sensoroni:$VERSION" \
"so-soc:$VERSION" \
"so-kratos:$VERSION" \
"so-soctopus:$VERSION" \
"so-steno:$VERSION" \
#"so-strelka:$VERSION" \
@@ -556,7 +590,7 @@ docker_seed_registry() {
"so-idstools:$VERSION" \
"so-logstash:$VERSION" \
"so-redis:$VERSION" \
"so-sensoroni:$VERSION" \
#"so-sensoroni:$VERSION" \
"so-steno:$VERSION" \
"so-suricata:$VERSION" \
"so-telegraf:$VERSION" \
@@ -651,6 +685,7 @@ generate_passwords(){
CORTEXKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)
CORTEXORGUSERKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)
SENSORONIKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)
KRATOSKEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1)
}
get_filesystem_nsm(){
@@ -690,6 +725,14 @@ get_main_ip() {
}
get_redirect() {
whiptail_set_redirect_info
whiptail_set_redirect
if [ $REDIRECTINFO == 'OTHER' ]; then
whiptail_set_redirect_host
fi
}
got_root() {
# Make sure you are root
@@ -800,7 +843,20 @@ master_pillar() {
echo " wazuh: $WAZUH" >> $PILLARFILE
echo " thehive: $THEHIVE" >> $PILLARFILE
echo " playbook: $PLAYBOOK" >> $PILLARFILE
echo " strelka: $STRELKA" >> $PILLARFILE
echo "" >> $PILLARFILE
echo "kratos:" >> $PILLARFILE
if [[ $REDIRECTINFO == 'OTHER' ]]; then
REDIRECTIT=$REDIRECT
elif [[ $REDIRECTINFO == 'IP' ]]; then
REDIRECTIT=$MAINIP
elif [[ $REDIRECTINFO == 'HOSTNAME' ]]; then
REDIRECTIT=$HOSTNAME
fi
echo " kratoskey: $KRATOSKEY" >> $PILLARFILE
echo " redirect: $REDIRECTIT" >> $PILLARFILE
echo "" >> $PILLARFILE
}
@@ -938,6 +994,7 @@ process_components() {
WAZUH=0
THEHIVE=0
PLAYBOOK=0
STRELKA=0
IFS=$' '
for item in $(echo "$CLEAN"); do
@@ -949,6 +1006,7 @@ process_components() {
reserve_group_ids() {
# This is a hack to fix CentOS from taking group IDs that we need
groupadd -g 928 kratos
groupadd -g 930 elasticsearch
groupadd -g 931 logstash
groupadd -g 932 kibana
@@ -974,6 +1032,7 @@ saltify() {
yum -y install wget https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest-2.el7.noarch.rpm
cp /etc/yum.repos.d/salt-py3-latest.repo /etc/yum.repos.d/salt-py3-2019-2.repo
sed -i 's/latest/2019.2/g' /etc/yum.repos.d/salt-py3-2019-2.repo
yum -y install sqlite3 argon2 curl jq openssl
# Download Ubuntu Keys in case master updates = 1
mkdir -p /opt/so/gpg
wget --inet4-only -O /opt/so/gpg/SALTSTACK-GPG-KEY.pub https://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest/SALTSTACK-GPG-KEY.pub
@@ -1191,11 +1250,11 @@ EOF
# Initialize the new repos
apt-get update >> $SETUPLOG 2>&1
if [ $OSVER != "xenial" ]; then
apt-get -y install salt-minion=2019.2.3+ds-1 salt-common=2019.2.3+ds-1 python3-dateutil python3-m2crypto >> $SETUPLOG 2>&1
apt-get -y install salt-minion=2019.2.3+ds-1 salt-common=2019.2.3+ds-1 python3-dateutil python3-m2crypto sqlite3 argon2 curl jq openssl >> $SETUPLOG 2>&1
apt-mark hold salt-minion salt-common
else
# Need to add python packages here
apt-get -y install salt-minion=2019.2.3+ds-1 salt-common=2019.2.3+ds-1 python-dateutil python-m2crypto >> $SETUPLOG 2>&1
apt-get -y install salt-minion=2019.2.3+ds-1 salt-common=2019.2.3+ds-1 python-dateutil python-m2crypto sqlite3 argon2 curl jq openssl >> $SETUPLOG 2>&1
apt-mark hold salt-minion salt-common
fi
else

View File

@@ -300,6 +300,15 @@ if (whiptail_you_sure) ; then
check_socore_pass
done
# Get a password for the web admin user
whiptail_create_web_user
WPMATCH=no
while [ $WPMATCH != yes ]; do
whiptail_create_web_user_password1
whiptail_create_web_user_password2
check_web_pass
done
get_redirect
# Last Chance to back out
whiptail_make_changes
set_hostname
@@ -376,21 +385,23 @@ if (whiptail_you_sure) ; then
docker_seed_registry >> $SETUPLOG 2>&1
echo -e "XXX\n43\nInstalling Common Components... \nXXX"
salt-call state.apply common >> $SETUPLOG 2>&1
echo -e "XXX\n44\nInstalling SOC... \nXXX"
salt-call state.apply soc >> $SETUPLOG 2>&1
echo -e "XXX\n45\nApplying firewall rules... \nXXX"
salt-call state.apply firewall >> $SETUPLOG 2>&1
salt-call state.apply master >> $SETUPLOG 2>&1
salt-call state.apply idstools >> $SETUPLOG 2>&1
echo -e "XXX\n40\nInstalling Redis... \nXXX"
echo -e "XXX\n46\nInstalling Redis... \nXXX"
salt-call state.apply redis >> $SETUPLOG 2>&1
if [[ $OSQUERY == '1' ]]; then
echo -e "XXX\n41\nInstalling MySQL... \nXXX"
echo -e "XXX\n48\nInstalling MySQL... \nXXX"
salt-call state.apply mysql >> $SETUPLOG 2>&1
fi
if [[ $WAZUH == '1' ]]; then
echo -e "XXX\n68\nInstalling Wazuh... \nXXX"
echo -e "XXX\n48\nInstalling Wazuh... \nXXX"
salt-call state.apply wazuh >> $SETUPLOG 2>&1
fi
echo -e "XXX\n45\nInstalling Elastic Components... \nXXX"
echo -e "XXX\n49\nInstalling Elastic Components... \nXXX"
salt-call state.apply elasticsearch >> $SETUPLOG 2>&1
salt-call state.apply logstash >> $SETUPLOG 2>&1
salt-call state.apply kibana >> $SETUPLOG 2>&1
@@ -419,7 +430,9 @@ if (whiptail_you_sure) ; then
echo -e "XX\n97\nFinishing touches... \nXXX"
filter_unused_nics >> $SETUPLOG 2>&1
network_setup >> $SETUPLOG 2>&1
echo -e "XXX\n98\nVerifying Setup... \nXXX"
echo -e "XXX\n98\nAdding user to SOC... \nXXX"
add_web_user >> $SETUPLOG 2>&1
echo -e "XXX\n99\nVerifying Setup... \nXXX"
salt-call state.highstate >> $SETUPLOG 2>&1
} |whiptail --title "Hybrid Hunter Install" --gauge "Please wait while installing" 6 60 0
GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}')
@@ -570,6 +583,15 @@ if (whiptail_you_sure) ; then
check_socore_pass
done
fi
# Get a password for the web admin user
whiptail_create_web_user
WPMATCH=no
while [ $WPMATCH != yes ]; do
whiptail_create_web_user_password1
whiptail_create_web_user_password2
check_web_pass
done
get_redirect
whiptail_make_changes
set_hostname
set_version
@@ -616,14 +638,10 @@ if (whiptail_you_sure) ; then
master_pillar >> $SETUPLOG 2>&1
echo "** Generating the patch pillar **" >> $SETUPLOG
patch_pillar >> $SETUPLOG 2>&1
echo -e "XXX\n7\nConfiguring minion... \nXXX"
configure_minion $TYPE >> $SETUPLOG 2>&1
echo -e "XXX\n7\nSetting the node type to $TYPE... \nXXX"
set_node_type >> $SETUPLOG 2>&1
echo -e "XXX\n7\nSearch node pillar... \nXXX"
node_pillar >> $SETUPLOG 2>&1
echo -e "XXX\n8\nCreating firewall policies... \nXXX"
@@ -650,12 +668,13 @@ if (whiptail_you_sure) ; then
echo -e "XXX\n25\nInstalling master components... \nXXX"
salt-call state.apply master >> $SETUPLOG 2>&1
salt-call state.apply idstools >> $SETUPLOG 2>&1
echo -e "XXX\n26\nInstalling SOC... \nXXX"
salt-call state.apply soc >> $SETUPLOG 2>&1
if [[ $OSQUERY == '1' ]]; then
salt-call state.apply mysql >> $SETUPLOG 2>&1
fi
if [[ $WAZUH == '1' ]]; then
echo -e "XXX\n65\nInstalling Wazuh components... \nXXX"
echo -e "XXX\n27\nInstalling Wazuh components... \nXXX"
salt-call state.apply wazuh >> $SETUPLOG 2>&1
fi
echo -e "XXX\n35\nInstalling ElasticSearch... \nXXX"
@@ -697,13 +716,18 @@ if (whiptail_you_sure) ; then
echo -e "XXX\n93\nInstalling Playbook... \nXXX"
salt-call state.apply playbook >> $SETUPLOG 2>&1
fi
if [[ $STRELKA == '1' ]]; then
echo -e "XXX\n95\nInstalling Strelka... \nXXX"
salt-call state.apply strelka >> $SETUPLOG 2>&1
fi
echo -e "XXX\n95\nSetting checkin to run on boot... \nXXX"
checkin_at_boot >> $SETUPLOG 2>&1
echo -e "XX\n97\nFinishing touches... \nXXX"
salt-call state.apply auth >> $SETUPLOG 2>&1
filter_unused_nics >> $SETUPLOG 2>&1
network_setup >> $SETUPLOG 2>&1
echo -e "XXX\n98\nVerifying Setup... \nXXX"
echo -e "XXX\n98\nAdding user to SOC... \nXXX"
add_web_user >> $SETUPLOG 2>&1
echo -e "XXX\n99\nVerifying Setup... \nXXX"
salt-call state.highstate >> $SETUPLOG 2>&1
} |whiptail --title "Hybrid Hunter Install" --gauge "Please wait while installing" 6 60 0
GOODSETUP=$(tail -10 $SETUPLOG | grep Failed | awk '{ print $2}')

View File

@@ -158,6 +158,34 @@ whiptail_create_socore_user_password2() {
}
whiptail_create_web_user() {
WEBUSER=$(whiptail --title "Security Onion Install" --inputbox \
"Please enter an email address to create an administrator account for the web interface." 10 60 3>&1 1>&2 2>&3)
}
whiptail_create_web_user_password1() {
WEBPASSWD1=$(whiptail --title "Security Onion Install" --passwordbox \
"Enter a password for $WEBUSER" 10 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_create_web_user_password2() {
WEBPASSWD2=$(whiptail --title "Security Onion Install" --passwordbox \
"Re-enter a password for $WEBUSER" 10 60 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_cur_close_days() {
CURCLOSEDAYS=$(whiptail --title "Security Onion Setup" --inputbox \
@@ -186,7 +214,8 @@ whiptail_enable_components() {
"OSQUERY" "Enable Fleet with osquery" ON \
"WAZUH" "Enable Wazuh" ON \
"THEHIVE" "Enable TheHive" ON \
"PLAYBOOK" "Enable Playbook" ON 3>&1 1>&2 2>&3 )
"PLAYBOOK" "Enable Playbook" ON \
"STRELKA" "Enable Strelka" ON 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
@@ -683,6 +712,28 @@ whiptail_set_hostname() {
}
whiptail_set_redirect() {
REDIRECTINFO=$(whiptail --title "Security Onion Setup" --radiolist \
"Choose the access method for the web interface:" 20 75 4 \
"IP" "Use IP to access the web interface" ON \
"HOSTNAME" "Use Hostname ($HOSTNAME) to access the web interface" OFF \
"OTHER" "Use a different name like a FQDN or Load Balancer" OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_set_redirect_host() {
REDIRECTHOST=$(whiptail --title "Security Onion Setup" --inputbox \
"Enter the Hostname or IP you would like to use for the web interface." 10 75 $HOSTNAME 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
}
whiptail_set_redirect_info() {
whiptail --title "Security Onion Setup" --msgbox "The following selection refers to accessing the web interface. \n
For security reasons, we use strict cookie enforcement." 10 75
}
whiptail_setup_complete() {
whiptail --title "Security Onion Setup" --msgbox "Finished installing this as an $INSTALLTYPE. Press Enter to reboot." 8 75

View File

@@ -51,12 +51,13 @@ if [ $MASTERCHECK != 'so-helix' ]; then
"so-idstools:$BUILD$UPDATEVERSION" \
"so-influxdb:$BUILD$UPDATEVERSION" \
"so-kibana:$BUILD$UPDATEVERSION" \
"so-kratos:$BUILD$UPDATEVERSION" \
"so-logstash:$BUILD$UPDATEVERSION" \
"so-mysql:$BUILD$UPDATEVERSION" \
"so-navigator:$BUILD$UPDATEVERSION" \
"so-playbook:$BUILD$UPDATEVERSION" \
"so-redis:$BUILD$UPDATEVERSION" \
"so-sensoroni:$BUILD$UPDATEVERSION" \
"so-soc:$BUILD$UPDATEVERSION" \
"so-soctopus:$BUILD$UPDATEVERSION" \
"so-steno:$BUILD$UPDATEVERSION" \
"so-strelka:$BUILD$UPDATEVERSION" \
@@ -73,7 +74,6 @@ if [ $MASTERCHECK != 'so-helix' ]; then
"so-idstools:$BUILD$UPDATEVERSION" \
"so-logstash:$BUILD$UPDATEVERSION" \
"so-redis:$BUILD$UPDATEVERSION" \
"so-sensoroni:$BUILD$UPDATEVERSION" \
"so-steno:$BUILD$UPDATEVERSION" \
"so-suricata:$BUILD$UPDATEVERSION" \
"so-telegraf:$BUILD$UPDATEVERSION" \