Initial commit
This commit is contained in:
commit
397ddb0e2b
10 changed files with 275 additions and 0 deletions
14
README.md
Normal file
14
README.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# parsedmarc-dockerized
|
||||||
|
**NOT FOR PRODUCTIVE USE**
|
||||||
|
|
||||||
|
To setup:
|
||||||
|
```
|
||||||
|
$ cd /opt/
|
||||||
|
$ git clone https://github.com/patschi/parsedmarc-dockerzied.git
|
||||||
|
# Edit docker-compose.yml and change environment variables below for geoipupdate from maxmind.
|
||||||
|
# Edit data/conf/parsedmarc/config.ini for parsedmarc itself (and change test to False when tested!)
|
||||||
|
$ docker-compose pull
|
||||||
|
$ docker-compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
Then the whole stack is being built, created, started and the corresponding dashboard automatically imported into Kibana. After a while you can access the Kibana dashboard with parsed information by [parsedmarc](https://github.com/domainaware/checkdmarc) under the reverse proxy with an automatically self-signed certificate at `https://IP:9999`.
|
8
data/Dockerfiles/parsedmarc-init/Dockerfile
Normal file
8
data/Dockerfiles/parsedmarc-init/Dockerfile
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
ADD start.sh /start.sh
|
||||||
|
|
||||||
|
RUN apk add --no-cache curl openssl jq bash \
|
||||||
|
&& chmod +x /start.sh
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/start.sh" ]
|
62
data/Dockerfiles/parsedmarc-init/start.sh
Normal file
62
data/Dockerfiles/parsedmarc-init/start.sh
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -x
|
||||||
|
|
||||||
|
echo "## ELASTICSEARCH"
|
||||||
|
echo "Setting permissions..."
|
||||||
|
chmod g+rwx -R /usr/share/elasticsearch/data/
|
||||||
|
chgrp 0 -R /usr/share/elasticsearch/data/
|
||||||
|
|
||||||
|
echo "## NGINX"
|
||||||
|
echo "Checking nginx certs..."
|
||||||
|
cd /etc/nginx/ssl/
|
||||||
|
if [ ! -f "/etc/nginx/ssl/kibana.crt" ] || [ ! -f "/etc/nginx/ssl/kibana.key" ]; then
|
||||||
|
echo "No certs found. Generating..."
|
||||||
|
openssl req -x509 -nodes -days 365 -newkey rsa:3072 -keyout kibana.key -out kibana.crt \
|
||||||
|
-subj "/CN=parsedmarc" -addext "subjectAltName=DNS:parsedmarc"
|
||||||
|
echo "Certs generated."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "## KIBANA"
|
||||||
|
if [ ! -f /etc/parsedmarc/kibana_export.ndjson ]; then
|
||||||
|
# trigger empty file to trigger below update logic.
|
||||||
|
touch /etc/parsedmarc/kibana_export.ndjson
|
||||||
|
fi
|
||||||
|
echo "Downloading dashboard from GitHub..."
|
||||||
|
rm /etc/parsedmarc/kibana_export.ndjson.tmp
|
||||||
|
curl https://raw.githubusercontent.com/domainaware/parsedmarc/master/kibana/export.ndjson \
|
||||||
|
-o /etc/parsedmarc/kibana_export.ndjson.tmp
|
||||||
|
if [ ${?} -ne 0 ]; then
|
||||||
|
echo "Downloading kibana export failed."
|
||||||
|
else
|
||||||
|
fileNew=$(wc -c "/etc/parsedmarc/kibana_export.ndjson.tmp") # always use quoted var
|
||||||
|
fileOld=$(wc -c "/etc/parsedmarc/kibana_export.ndjson")
|
||||||
|
|
||||||
|
if [ $fileNew -eq $fileOld ]; then
|
||||||
|
echo "File size is the same. Not proceeding."
|
||||||
|
else
|
||||||
|
echo "File size is different... updating..."
|
||||||
|
|
||||||
|
while ! curl -s -f -I http://kibana:5601 >/dev/null; do
|
||||||
|
echo "Kibana not responding... waiting 5 secs..."
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Kibana responded. Waiting 10s, then proceeding with dashboard update..."
|
||||||
|
sleep 10
|
||||||
|
rm /etc/parsedmarc/kibana_export.ndjson
|
||||||
|
mv /etc/parsedmarc/kibana_export.ndjson.tmp /etc/parsedmarc/kibana_export.ndjson
|
||||||
|
RES=$(curl -X POST http://kibana:5601/api/saved_objects/_import?overwrite=true \
|
||||||
|
-H "kbn-xsrf: true" --form file=@/etc/parsedmarc/kibana_export.ndjson)
|
||||||
|
echo "Result: $RES"
|
||||||
|
if [ ${?} -ne 0 ]; then
|
||||||
|
echo "[!!!] Import might have failed. Manual check recommended."
|
||||||
|
fi
|
||||||
|
echo "Importing done."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
# Create empty file to let other containers know that we're ready.
|
||||||
|
touch /ready
|
||||||
|
sleep infinity # or while true; do sleep 86400; done
|
||||||
|
exit 0
|
11
data/Dockerfiles/parsedmarc/Dockerfile
Normal file
11
data/Dockerfiles/parsedmarc/Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
FROM pypy:3-slim
|
||||||
|
|
||||||
|
ADD start.sh /start.sh
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y libxslt-dev libz-dev libxml2-dev gcc libemail-outlook-message-perl \
|
||||||
|
&& pip install -U parsedmarc \
|
||||||
|
&& apt-get purge --yes gcc && apt autoremove --yes && apt-get clean \
|
||||||
|
&& rm -Rf /var/lib/{apt,dpkg}/ && rm -Rf /root/.cache/ \
|
||||||
|
&& chmod +x /start.sh
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/start.sh" ]
|
3
data/Dockerfiles/parsedmarc/start.sh
Normal file
3
data/Dockerfiles/parsedmarc/start.sh
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Start parsedmarc
|
||||||
|
parsedmarc -c /etc/parsedmarc/config.ini
|
37
data/conf/nginx/site.conf
Normal file
37
data/conf/nginx/site.conf
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
|
||||||
|
server_name _ default_server;
|
||||||
|
ssl_certificate /etc/nginx/ssl/kibana.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/kibana.key;
|
||||||
|
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_cache shared:SSL:15m;
|
||||||
|
ssl_session_tickets off;
|
||||||
|
|
||||||
|
# modern configuration. tweak to your needs.
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
|
||||||
|
add_header X-Frame-Options SAMEORIGIN;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
|
||||||
|
# Uncomment this next line if you are using a signed, trusted cert
|
||||||
|
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
|
||||||
|
|
||||||
|
#auth_basic "Login required";
|
||||||
|
#auth_basic_user_file /etc/nginx/htpasswd;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://kibana:5601;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
27
data/conf/parsedmarc/config.ini
Normal file
27
data/conf/parsedmarc/config.ini
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# See docs at: domainaware.github.io/parsedmarc/#configuration-file
|
||||||
|
### ADJUST YOUR SETTINGS
|
||||||
|
[general]
|
||||||
|
save_aggregate = True
|
||||||
|
save_forensic = True
|
||||||
|
|
||||||
|
[imap]
|
||||||
|
# IMAP login
|
||||||
|
host = imap.example.com
|
||||||
|
port = 993
|
||||||
|
user = dmarcresports@example.com
|
||||||
|
password = $uperSecure
|
||||||
|
|
||||||
|
# advanced
|
||||||
|
watch = True
|
||||||
|
ssl = True
|
||||||
|
|
||||||
|
archive_folder = Processed
|
||||||
|
delete = False
|
||||||
|
|
||||||
|
# advanced advanced
|
||||||
|
test = True
|
||||||
|
|
||||||
|
### NO EDIT REQURIED DOWN BELOW
|
||||||
|
[elasticsearch]
|
||||||
|
hosts = elasticsearch:9200
|
||||||
|
ssl = False
|
0
data/data/elasticsearch/.gitkeep
Normal file
0
data/data/elasticsearch/.gitkeep
Normal file
0
data/data/geoipupdate/.gitkeep
Normal file
0
data/data/geoipupdate/.gitkeep
Normal file
113
docker-compose.yml
Normal file
113
docker-compose.yml
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
version: '2.4'
|
||||||
|
|
||||||
|
services:
|
||||||
|
parsedmarc-init:
|
||||||
|
build:
|
||||||
|
context: ./data/Dockerfiles/parsedmarc-init/
|
||||||
|
image: parsedmarc-init
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./data/conf/parsedmarc/:/etc/parsedmarc/:rw
|
||||||
|
- ./data/conf/nginx/ssl/:/etc/nginx/ssl/:rw
|
||||||
|
- ./data/data/elasticsearch:/usr/share/elasticsearch/data/:rw
|
||||||
|
networks:
|
||||||
|
- parsedmarc-network
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "test", "-f", "/ready" ]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 9999
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
parsedmarc:
|
||||||
|
build:
|
||||||
|
context: ./data/Dockerfiles/parsedmarc/
|
||||||
|
image: parsedmarc
|
||||||
|
volumes:
|
||||||
|
- ./data/conf/parsedmarc/:/etc/parsedmarc/
|
||||||
|
- ./data/data/geoipupdate/:/usr/share/GeoIP:z,ro
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- parsedmarc-network
|
||||||
|
depends_on:
|
||||||
|
elasticsearch:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
elasticsearch:
|
||||||
|
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.8.1
|
||||||
|
environment:
|
||||||
|
- cluster.name=parsedmarc
|
||||||
|
- discovery.type=single-node
|
||||||
|
- bootstrap.memory_lock=true
|
||||||
|
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||||
|
ulimits:
|
||||||
|
memlock:
|
||||||
|
soft: -1
|
||||||
|
hard: -1
|
||||||
|
volumes:
|
||||||
|
- ./data/data/elasticsearch:/usr/share/elasticsearch/data/
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- parsedmarc-network
|
||||||
|
expose: # only expose docker-internally
|
||||||
|
- 9200
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl","-s" ,"-f", "http://localhost:9200/_cat/health" ]
|
||||||
|
interval: 1m
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
depends_on:
|
||||||
|
parsedmarc-init:
|
||||||
|
condition: service_started
|
||||||
|
|
||||||
|
kibana:
|
||||||
|
image: docker.elastic.co/kibana/kibana-oss:7.8.1
|
||||||
|
environment:
|
||||||
|
- elasticsearch.hosts=http://elasticsearch:9200
|
||||||
|
expose: # only expose docker-internally
|
||||||
|
- 5601
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- parsedmarc-network
|
||||||
|
depends_on:
|
||||||
|
elasticsearch:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl","-s" ,"-f", "http://localhost:5601/" ]
|
||||||
|
interval: 1m
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
|
||||||
|
geoipupdate:
|
||||||
|
image: maxmindinc/geoipupdate
|
||||||
|
environment:
|
||||||
|
- GEOIPUPDATE_ACCOUNT_ID=TO_BE_SET
|
||||||
|
- GEOIPUPDATE_LICENSE_KEY=TO_BE_SET
|
||||||
|
- GEOIPUPDATE_EDITION_IDS=TO_BE_SET
|
||||||
|
- GEOIPUPDATE_FREQUENCY=24
|
||||||
|
- GEOIPUPDATE_PRESERVE_FILE_TIMES=1
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./data/data/geoipupdate/:/usr/share/GeoIP:z,rw
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "9999:443"
|
||||||
|
volumes:
|
||||||
|
- ./data/conf/nginx/site.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
- ./data/conf/nginx/ssl/:/etc/nginx/ssl/:ro
|
||||||
|
networks:
|
||||||
|
- parsedmarc-network
|
||||||
|
depends_on:
|
||||||
|
kibana:
|
||||||
|
condition: service_healthy
|
||||||
|
parsedmarc-init:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
networks:
|
||||||
|
parsedmarc-network:
|
||||||
|
driver: bridge
|
Loading…
Reference in a new issue