Compare commits
58
Commits
master
...
135-scirius
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
566b41069b | ||
|
|
d212963631 | ||
|
|
f603b1e737 | ||
|
|
7a112ef00c | ||
|
|
2cb465eb10 | ||
|
|
d84ca0df84 | ||
|
|
025a0840a0 | ||
|
|
2b33a37a64 | ||
|
|
83119cb9b8 | ||
|
|
4dac62d221 | ||
|
|
bd6197ab36 | ||
|
|
be3c349e75 | ||
|
|
921e91883b | ||
|
|
83eb2d7364 | ||
|
|
3432b7983c | ||
|
|
d22ebd58b7 | ||
|
|
bb37ed0646 | ||
|
|
544073213b | ||
|
|
a528b84f7c | ||
|
|
87f375098a | ||
|
|
7d5dd57b60 | ||
|
|
3968000c89 | ||
|
|
0c65407388 | ||
|
|
83a01d7e0a | ||
|
|
f1df9079f2 | ||
|
|
646aaaefe6 | ||
|
|
c26e8c58d6 | ||
|
|
9f4b6f589b | ||
|
|
ecedd62a8a | ||
|
|
60b50d07ad | ||
|
|
c6df470ce2 | ||
|
|
99c05d8125 | ||
|
|
ea367a72dd | ||
|
|
af5d614a15 | ||
|
|
dc8931beb0 | ||
|
|
366c961482 | ||
|
|
06cda76326 | ||
|
|
d4b21e1e75 | ||
|
|
487101d685 | ||
|
|
6061d0598b | ||
|
|
59b216e9dd | ||
|
|
a12a3d21e3 | ||
|
|
1869f9e4e0 | ||
|
|
622ffdd654 | ||
|
|
45ee4c7150 | ||
|
|
38b089c5d2 | ||
|
|
5d497b7ab9 | ||
|
|
70d7e2831f | ||
|
|
c4a2696a3e | ||
|
|
4459f24980 | ||
|
|
bec07eca9a | ||
|
|
7faf9f3e09 | ||
|
|
cc8032e6ce | ||
|
|
4e27a0c261 | ||
|
|
a58bee261a | ||
|
|
ef6c8f4c2c | ||
|
|
d6eec3c7a3 | ||
|
|
0b85a98e5e |
@@ -0,0 +1,72 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
scirius:
|
||||
container_name: mistborn_production_scirius
|
||||
image: "cyber5k/scirius:${MISTBORN_TAG}"
|
||||
#environment:
|
||||
# - SECRET_KEY: <SECRET KEY>
|
||||
env_file:
|
||||
- ../.envs/.production/.wazuh
|
||||
- ../.envs/.production/.scirius
|
||||
volumes:
|
||||
- /var/log/suricata:/logs
|
||||
- /etc/suricata/rules:/etc/suricata/rules
|
||||
- ../../mistborn_volumes/extra/scirius/static:/static
|
||||
- ../../mistborn_volumes/extra/scirius/data:/data
|
||||
- /var/run:/var/run:ro
|
||||
- /var/run/suricata/suricata-command.socket:/var/run/suricata/suricata-command.socket:ro
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.scirius-http.rule=Host(`scirius.mistborn`)"
|
||||
- "traefik.http.routers.scirius-http.entrypoints=web"
|
||||
- "traefik.http.routers.scirius-http.middlewares=mistborn_auth@file"
|
||||
- "traefik.http.routers.scirius-https.rule=Host(`scirius.mistborn`)"
|
||||
- "traefik.http.routers.scirius-https.entrypoints=websecure"
|
||||
- "traefik.http.routers.scirius-https.middlewares=mistborn_auth@file"
|
||||
- "traefik.http.routers.scirius-https.tls.certresolver=basic"
|
||||
- "traefik.http.services.scirius-service.loadbalancer.server.port=8000"
|
||||
restart: unless-stopped
|
||||
|
||||
# filebeat:
|
||||
# image: docker.elastic.co/beats/filebeat:${ELASTIC_VERSION:-7.9.1}
|
||||
# # https://github.com/docker/swarmkit/issues/1951
|
||||
# hostname: "{{.Node.Hostname}}-filebeat"
|
||||
# # Need to override user so we can access the log files, and docker.sock
|
||||
# user: root
|
||||
# configs:
|
||||
# - source: fb_config
|
||||
# target: /usr/share/filebeat/filebeat.yml
|
||||
# volumes:
|
||||
# - filebeat:/usr/share/filebeat/data
|
||||
# - /var/run/docker.sock:/var/run/docker.sock
|
||||
# # This is needed for filebeat to load container log path as specified in filebeat.yml
|
||||
# - /var/lib/docker/containers/:/var/lib/docker/containers/:ro
|
||||
|
||||
# # # This is needed for filebeat to load jenkins build log path as specified in filebeat.yml
|
||||
# # - /var/lib/docker/volumes/jenkins_home/_data/jobs/:/var/lib/docker/volumes/jenkins_home/_data/jobs/:ro
|
||||
|
||||
# # This is needed for filebeat to load logs for system and auth modules
|
||||
# - /var/log/:/var/log/:ro
|
||||
# # This is needed for filebeat to load logs for auditd module. you might have to install audit system
|
||||
# # on ubuntu first (sudo apt-get install -y auditd audispd-plugins)
|
||||
# - /var/log/audit/:/var/log/audit/:ro
|
||||
# environment:
|
||||
# - ELASTICSEARCH_HOST=${ELASTICSEARCH_HOST}
|
||||
# - KIBANA_HOST=${KIBANA_HOST}
|
||||
# - ELASTICSEARCH_USERNAME=${ELASTICSEARCH_USERNAME}
|
||||
# - ELASTICSEARCH_PASSWORD=${ELASTICSEARCH_PASSWORD}
|
||||
# # disable strict permission checks
|
||||
# command: ["--strict.perms=false"]
|
||||
|
||||
# volumes:
|
||||
# filebeat:
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: mistborn_default
|
||||
|
||||
# configs:
|
||||
# fb_config:
|
||||
# file: /opt/mistborn_volumes/scirius/init/filebeat.docker.yml
|
||||
@@ -0,0 +1,27 @@
|
||||
[Unit]
|
||||
Description=Mistborn Scirius Service
|
||||
Requires=Mistborn-wazuh.service
|
||||
After=Mistborn-wazuh.service
|
||||
PartOf=Mistborn-base.service
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=15
|
||||
User=root
|
||||
Group=docker
|
||||
PermissionsStartOnly=true
|
||||
# Shutdown container (if running) when unit is stopped
|
||||
ExecStartPre=/opt/mistborn/scripts/wrappers/mistborn_docker.sh wazuh,scirius docker-compose -f /opt/mistborn/extra/scirius.yml down
|
||||
|
||||
# Start container when unit is started
|
||||
ExecStart=/opt/mistborn/scripts/wrappers/mistborn_docker.sh wazuh,scirius docker-compose -f /opt/mistborn/extra/scirius.yml up --build
|
||||
# Suricata
|
||||
ExecStartPost=/opt/mistborn/scripts/wrappers/mistborn_docker.sh wazuh,scirius /opt/mistborn/scripts/services/scirius/suricata_start.sh
|
||||
|
||||
# Stop container when unit is stopped
|
||||
ExecStop=/opt/mistborn/scripts/wrappers/mistborn_docker.sh wazuh,scirius docker-compose -f /opt/mistborn/extra/scirius.yml down
|
||||
# Post stop
|
||||
ExecStopPost=-/opt/mistborn/scripts/wrappers/mistborn_docker.sh wazuh,scirius /opt/mistborn/scripts/services/scirius/suricata_stop.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=Mistborn-base.service
|
||||
@@ -0,0 +1,6 @@
|
||||
<agent_config>
|
||||
<localfile>
|
||||
<log_format>json</log_format>
|
||||
<location>/var/log/suricata/eve.json</location>
|
||||
</localfile>
|
||||
</agent_config>
|
||||
@@ -0,0 +1,62 @@
|
||||
filebeat.modules:
|
||||
- module: suricata
|
||||
eve:
|
||||
enabled: true
|
||||
var.paths: ["/var/log/suricata/eve.json"]
|
||||
# - module: system
|
||||
# syslog:
|
||||
# enabled: true
|
||||
# auth:
|
||||
# enabled: true
|
||||
# - module: auditd
|
||||
# log:
|
||||
# # - Does not look like Auditd is supported in Alpine linux: https://github.com/linuxkit/linuxkit/issues/52
|
||||
# # - CentOS does not need us to install the audit system, it ships as standard. If you are using Ubuntu, though,
|
||||
# # this is probably something you would want to install. (sudo apt-get install -y auditd audispd-plugins)
|
||||
# enabled: true
|
||||
|
||||
#filebeat.inputs:
|
||||
#- type: container
|
||||
# enabled: true
|
||||
# paths:
|
||||
# -/var/lib/docker/containers/*/*.log
|
||||
# stream: all # can be all, stdout or stderr
|
||||
|
||||
#========================== Filebeat autodiscover ==============================
|
||||
# See this URL on how to run Apache2 Filebeat module: # https://www.elastic.co/guide/en/beats/filebeat/current/running-on-docker.html
|
||||
filebeat.autodiscover:
|
||||
providers:
|
||||
- type: docker
|
||||
# https://www.elastic.co/guide/en/beats/filebeat/current/configuration-autodiscover-hints.html
|
||||
# This URL alos contains instructions on multi-line logs
|
||||
hints.enabled: true
|
||||
|
||||
#================================ Processors ===================================
|
||||
processors:
|
||||
#- add_cloud_metadata: ~
|
||||
- add_docker_metadata: ~
|
||||
- add_locale:
|
||||
format: offset
|
||||
- add_host_metadata:
|
||||
netinfo.enabled: true
|
||||
|
||||
#========================== Elasticsearch output ===============================
|
||||
output.elasticsearch:
|
||||
hosts: ["${ELASTICSEARCH_HOST}:9200"]
|
||||
username: ${ELASTICSEARCH_USERNAME}
|
||||
password: ${ELASTICSEARCH_PASSWORD}
|
||||
|
||||
#============================== Dashboards =====================================
|
||||
setup.dashboards:
|
||||
enabled: true
|
||||
|
||||
#============================== Kibana =========================================
|
||||
setup.kibana:
|
||||
host: "${KIBANA_HOST}:80"
|
||||
username: ${ELASTICSEARCH_USERNAME}
|
||||
password: ${ELASTICSEARCH_PASSWORD}
|
||||
|
||||
#============================== Xpack Monitoring ===============================
|
||||
xpack.monitoring:
|
||||
enabled: true
|
||||
elasticsearch:
|
||||
Executable
+101
@@ -0,0 +1,101 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# detect if suricata is installed
|
||||
if [[ $(dpkg-query -W -f='${Status}' suricata 2>/dev/null | grep -c "ok installed") -eq 1 ]]; then
|
||||
echo "Suricata Installed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
source /opt/mistborn/scripts/subinstallers/platform.sh
|
||||
|
||||
# minimal dependencies
|
||||
sudo -E apt-get -y install libpcre3 libpcre3-dbg libpcre3-dev build-essential libpcap-dev \
|
||||
libyaml-0-2 libyaml-dev pkg-config zlib1g zlib1g-dev \
|
||||
make libmagic-dev libjansson-dev
|
||||
|
||||
## recommended dependencies
|
||||
#sudo -E apt-get -y install libpcre3 libpcre3-dbg libpcre3-dev build-essential libpcap-dev \
|
||||
# libnet1-dev libyaml-0-2 libyaml-dev pkg-config zlib1g zlib1g-dev \
|
||||
# libcap-ng-dev libcap-ng0 make libmagic-dev \
|
||||
# libgeoip-dev liblua5.1-dev libhiredis-dev libevent-dev \
|
||||
# python-yaml rustc cargo
|
||||
|
||||
# iptables/nftables integration
|
||||
sudo -E apt-get -y install libnetfilter-queue-dev libnetfilter-queue1 \
|
||||
libnetfilter-log-dev libnetfilter-log1 \
|
||||
libnfnetlink-dev libnfnetlink0
|
||||
|
||||
|
||||
if [ "$DISTRO" == "ubuntu" ]; then
|
||||
echo "Installing Suricata Ubuntu PPA"
|
||||
sudo -E add-apt-repository -y ppa:oisf/suricata-stable
|
||||
sudo -E apt-get update
|
||||
sudo -E apt-get install -y suricata
|
||||
elif [ "$DISTRO" == "debian" ]; then
|
||||
# retrieve version codename
|
||||
source /etc/os-release
|
||||
echo "deb http://http.debian.net/debian $VERSION_CODENAME-backports main" | \
|
||||
sudo -E tee /etc/apt/sources.list.d/backports.list
|
||||
sudo -E apt-get update
|
||||
sudo -E apt-get install -y suricata -t ${VERSION_CODENAME}-backports
|
||||
else
|
||||
echo "Basic Suricata installation"
|
||||
sudo -E apt-get install -y suricata
|
||||
fi
|
||||
|
||||
# # iptables
|
||||
# sudo iptables -A INPUT -j NFQUEUE
|
||||
# sudo iptables -I FORWARD -j NFQUEUE
|
||||
# sudo iptables -I OUTPUT -j NFQUEUE
|
||||
|
||||
# # rsyslog to create /var/log/suricata.log
|
||||
# sudo cp ./scripts/conf/20-suricata.conf /etc/rsyslog.d/
|
||||
# sudo chown root:root /etc/rsyslog.d/20-suricata.conf
|
||||
# sudo systemctl restart rsyslog
|
||||
|
||||
IFACE=$(ip -o -4 route show to default | awk 'NR==1{print $5}')
|
||||
sudo sed -i "s/eth0/${IFACE}/g" /etc/suricata/suricata.yaml
|
||||
sudo sed -i "s/eth0/${IFACE}/g" /etc/default/suricata
|
||||
|
||||
systemctl restart suricata
|
||||
|
||||
# wait for service to be listening
|
||||
while ! nc -z 10.2.3.1 55000; do
|
||||
WAIT_TIME=10
|
||||
echo "Waiting ${WAIT_TIME} seconds for Wazuh API..."
|
||||
sleep ${WAIT_TIME}
|
||||
done
|
||||
|
||||
# set working directory to mistborn for docker-compose
|
||||
pushd .
|
||||
cd /opt/mistborn
|
||||
|
||||
# ensure group exists
|
||||
sudo docker-compose -f extra/wazuh.yml exec -T wazuh /var/ossec/bin/agent_groups -a -g suricata -q 2>/dev/null
|
||||
|
||||
# add this host to group
|
||||
WAZUH_ID=$(sudo docker-compose -f extra/wazuh.yml exec -T wazuh /var/ossec/bin/manage_agents -l | egrep ^\ *ID | grep $(hostname) | awk '{print $2}' | tr -d ',')
|
||||
sudo docker-compose -f extra/wazuh.yml exec -T wazuh /var/ossec/bin/agent_groups -a -i ${WAZUH_ID} -g suricata -q
|
||||
|
||||
# write agent.conf
|
||||
sudo docker-compose -f extra/wazuh.yml exec -T wazuh bash -c "cat > /var/ossec/etc/shared/suricata/agent.conf << EOF
|
||||
<agent_config>
|
||||
<localfile>
|
||||
<log_format>json</log_format>
|
||||
<location>/var/log/suricata/eve.json</location>
|
||||
</localfile>
|
||||
</agent_config>
|
||||
EOF
|
||||
"
|
||||
|
||||
# restart manager
|
||||
sudo docker-compose -f extra/wazuh.yml restart wazuh
|
||||
|
||||
popd
|
||||
|
||||
|
||||
mkdir -p /opt/mistborn_volumes/extra/scirius/init/ >/dev/null 2>&1
|
||||
chmod -R +x /opt/mistborn_volumes/extra/scirius/init/
|
||||
cp /opt/mistborn/scripts/services/scirius/files/filebeat.docker.yml /opt/mistborn_volumes/extra/scirius/init/
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/python3
|
||||
"""
|
||||
Copyright(C) 2014-2020, Stamus Networks
|
||||
Written by Eric Leblond <eleblond@stamus-networks.com>
|
||||
|
||||
This file is part of Scirius.
|
||||
|
||||
Scirius 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.
|
||||
|
||||
Scirius 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 Scirius. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyinotify
|
||||
import argparse
|
||||
import subprocess
|
||||
import logging
|
||||
import os
|
||||
|
||||
have_daemon = True
|
||||
try:
|
||||
import daemon
|
||||
import daemon.pidfile as pidlockfile
|
||||
except:
|
||||
logging.warning("No daemon support available, install python-daemon if feature is needed")
|
||||
have_daemon = False
|
||||
|
||||
RELOAD_FILE = "scirius.reload"
|
||||
|
||||
parser = argparse.ArgumentParser(description='Suricata reloader')
|
||||
parser.add_argument('-r', '--reload', default=False, action="store_true", help="If set reload Suricata instead of restarting")
|
||||
parser.add_argument('-p', '--path', default='/etc/suricata/rules', help='Directory to monitor for scirius.reload file')
|
||||
parser.add_argument('-l', '--log', default=None, help='File to log output to (default to stdout)')
|
||||
parser.add_argument('-v', '--verbose', default=False, action="count", help="Show verbose output, use multiple times increase verbosity")
|
||||
if have_daemon:
|
||||
parser.add_argument('-D', '--daemon', default=False, action="store_true", help="Run as unix daemon")
|
||||
parser.add_argument('-P', '--pidfile', default='/var/run/suri-reloader.pid', help='PID file for suri-reloader')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.verbose >= 3:
|
||||
loglevel=logging.DEBUG
|
||||
elif args.verbose >= 2:
|
||||
loglevel=logging.INFO
|
||||
elif args.verbose >= 1:
|
||||
loglevel=logging.WARNING
|
||||
else:
|
||||
loglevel=logging.ERROR
|
||||
|
||||
def SuriReload(reload = False):
|
||||
if reload:
|
||||
if subprocess.call(['service', 'suricata', 'reload']):
|
||||
logging.error("Unable to reload suricata")
|
||||
else:
|
||||
logging.info("Reloaded suricata")
|
||||
else:
|
||||
if subprocess.call(['service', 'suricata', 'restart']):
|
||||
logging.error("Unable to restart suricata")
|
||||
else:
|
||||
logging.info("Restarted suricata")
|
||||
|
||||
class EventHandler(pyinotify.ProcessEvent):
|
||||
def process_IN_CLOSE_WRITE(self, event):
|
||||
if not RELOAD_FILE in event.pathname:
|
||||
return
|
||||
SuriReload(self.reload)
|
||||
os.unlink(event.pathname)
|
||||
|
||||
def set_mode(self, mode):
|
||||
if mode == "reload":
|
||||
self.reload = True
|
||||
else:
|
||||
self.reload = False
|
||||
|
||||
def setup_logging(args):
|
||||
if args.log:
|
||||
logging.basicConfig(filename=args.log,
|
||||
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
|
||||
level=loglevel)
|
||||
else:
|
||||
logging.basicConfig(level=loglevel)
|
||||
|
||||
def main_task(args):
|
||||
setup_logging(args)
|
||||
|
||||
reload_file = os.path.join(args.path, RELOAD_FILE)
|
||||
if os.path.isfile(reload_file):
|
||||
SuriReload(args.reload)
|
||||
os.unlink(reload_file)
|
||||
|
||||
handler = EventHandler()
|
||||
if args.reload:
|
||||
handler.set_mode("reload")
|
||||
else:
|
||||
handler.set_mode("restart")
|
||||
|
||||
wm = pyinotify.WatchManager() # Watch Manager
|
||||
mask = pyinotify.IN_CLOSE_WRITE
|
||||
notifier = pyinotify.Notifier(wm, handler)
|
||||
wdd = wm.add_watch(args.path, mask, rec=True)
|
||||
logging.info("Starting filesystem monitoring")
|
||||
notifier.loop()
|
||||
|
||||
if have_daemon and args.daemon:
|
||||
pidfile = pidlockfile.TimeoutPIDLockFile(args.pidfile)
|
||||
with daemon.DaemonContext(pidfile=pidfile):
|
||||
main_task(args)
|
||||
else:
|
||||
main_task(args)
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
systemctl start suricata
|
||||
systemctl enable suricata
|
||||
|
||||
apt-get install -y python-pyinotify
|
||||
python /opt/mistborn/scripts/services/scirius/suri_reloader -p /etc/suricata/rules &
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
systemctl stop suricata
|
||||
systemctl disable suricata
|
||||
|
||||
kill $(pgrep -f suri_reloader) 2>/dev/null
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Scirius
|
||||
SCIRIUS_PROD_FILE="$1"
|
||||
SCIRIUS_SECRET_KEY=$(python3 -c "import secrets; import string; print(f''.join([secrets.choice(string.ascii_letters+string.digits) for x in range(50)]))")
|
||||
echo "SECRET_KEY=$SCIRIUS_SECRET_KEY" > $SCIRIUS_PROD_FILE
|
||||
echo "ALLOWED_HOSTS=scirius.mistborn" >> $SCIRIUS_PROD_FILE
|
||||
echo "DJANGO_SUPERUSER_USERNAME=mistborn" >> $SCIRIUS_PROD_FILE
|
||||
echo "DJANGO_SUPERUSER_EMAIL=mistborn@email.mistborn" >> $SCIRIUS_PROD_FILE
|
||||
|
||||
echo "ELASTICSEARCH_HOST=10.2.3.1" >> $SCIRIUS_PROD_FILE
|
||||
echo "KIBANA_HOST=wazuh.mistborn" >> $SCIRIUS_PROD_FILE
|
||||
|
||||
echo "MISTBORN_DEFAULT_PASSWORD=$MISTBORN_DEFAULT_PASSWORD" >> $SCIRIUS_PROD_FILE
|
||||
|
||||
chmod 600 $SCIRIUS_PROD_FILE
|
||||
Reference in New Issue
Block a user