chore(build): add github action

* update documentation

  * fix report parser option and defaults

  * fixes #28

  * fixes #31
This commit is contained in:
Robert Schumann
2023-01-07 23:04:11 +01:00
parent aab0d17980
commit 8981d3afbf
4 changed files with 142 additions and 82 deletions

45
.github/workflows/docker-image.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: Docker Image CI
on:
push:
branches:
- master
tags:
- "v*"
pull_request:
branches:
- master
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: gutmensch/dmarc-report
flavor: latest=true
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
- name: Login to DockerHub
if: github.ref_type == 'tag'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
file: Dockerfile
push: ${{ github.ref_type == 'tag' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -5,7 +5,7 @@ FROM $UPSTREAM_IMAGE
LABEL maintainer="Robert Schumann <rs@n-os.org>" LABEL maintainer="Robert Schumann <rs@n-os.org>"
ENV REPORT_PARSER_SOURCE="https://github.com/techsneeze/dmarcts-report-parser/archive/master.zip" \ ENV REPORT_PARSER_SOURCE="https://github.com/techsneeze/dmarcts-report-parser/archive/master.zip" \
REPORT_VIEWER_SOURCE="https://github.com/techsneeze/dmarcts-report-viewer/archive/master.zip" REPORT_VIEWER_SOURCE="https://github.com/techsneeze/dmarcts-report-viewer/archive/master.zip"
USER root USER root
@@ -14,62 +14,62 @@ WORKDIR /
COPY ./manifest/ / COPY ./manifest/ /
RUN set -x \ RUN set -x \
&& apk add -U \ && apk add -U \
bash \ bash \
expat-dev \ expat-dev \
g++ \ g++ \
gzip \ gzip \
libpq \ libpq \
libpq-dev \ libpq-dev \
make \ make \
mariadb-client \ mariadb-client \
mariadb-connector-c \ mariadb-connector-c \
mariadb-dev \ mariadb-dev \
musl-obstack \ musl-obstack \
musl-obstack-dev \ musl-obstack-dev \
openssl \ openssl \
openssl-dev \ openssl-dev \
perl-dev \ perl-dev \
perl-utils \ perl-utils \
php81-pdo \ php81-pdo \
php81-pdo_mysql \ php81-pdo_mysql \
php81-pdo_pgsql \ php81-pdo_pgsql \
tzdata \ tzdata \
wget \ wget \
&& wget -4 -q --no-check-certificate -O parser.zip $REPORT_PARSER_SOURCE \ && wget -4 -q --no-check-certificate -O parser.zip $REPORT_PARSER_SOURCE \
&& wget -4 -q --no-check-certificate -O viewer.zip $REPORT_VIEWER_SOURCE \ && wget -4 -q --no-check-certificate -O viewer.zip $REPORT_VIEWER_SOURCE \
&& unzip parser.zip && cp -av dmarcts-report-parser-master/* /usr/bin/ && rm -vf parser.zip && rm -rvf dmarcts-report-parser-master \ && unzip parser.zip && cp -av dmarcts-report-parser-master/* /usr/bin/ && rm -vf parser.zip && rm -rvf dmarcts-report-parser-master \
&& unzip viewer.zip && cp -av dmarcts-report-viewer-master/* /var/www/viewer/ && rm -vf viewer.zip && rm -rvf dmarcts-report-viewer-master \ && unzip viewer.zip && cp -av dmarcts-report-viewer-master/* /var/www/viewer/ && rm -vf viewer.zip && rm -rvf dmarcts-report-viewer-master \
&& sed -i "1s/^/body { font-family: Sans-Serif; }\n/" /var/www/viewer/default.css \ && sed -i "1s/^/body { font-family: Sans-Serif; }\n/" /var/www/viewer/default.css \
&& sed -i 's%.*listen [::]:8080 default_server;% listen [::]:80 default_server;%g' /etc/nginx/nginx.conf \ && sed -i 's%.*listen [::]:8080 default_server;% listen [::]:80 default_server;%g' /etc/nginx/nginx.conf \
&& sed -i 's%.*listen 8080 default_server;% listen 80 default_server;%g' /etc/nginx/nginx.conf \ && sed -i 's%.*listen 8080 default_server;% listen 80 default_server;%g' /etc/nginx/nginx.conf \
&& sed -i 's%.*root /var/www/html;% root /var/www/viewer;%g' /etc/nginx/nginx.conf \ && sed -i 's%.*root /var/www/html;% root /var/www/viewer;%g' /etc/nginx/nginx.conf \
&& sed -i 's/.*index index.php index.html;/ index dmarcts-report-viewer.php;/g' /etc/nginx/nginx.conf \ && sed -i 's/.*index index.php index.html;/ index dmarcts-report-viewer.php;/g' /etc/nginx/nginx.conf \
&& sed -i 's%files = /etc/supervisor.d/\*.ini%files = /etc/supervisor/conf.d/*.conf%g' /etc/supervisord.conf \ && sed -i 's%files = /etc/supervisor.d/\*.ini%files = /etc/supervisor/conf.d/*.conf%g' /etc/supervisord.conf \
&& (echo y;echo o conf prerequisites_policy follow;echo o conf commit)|cpan \ && (echo y;echo o conf prerequisites_policy follow;echo o conf commit)|cpan \
&& for i in \ && for i in \
IO::Socket::SSL \ IO::Socket::SSL \
CPAN \ CPAN \
CPAN::DistnameInfo \ CPAN::DistnameInfo \
File::MimeInfo \ File::MimeInfo \
IO::Compress::Gzip \ IO::Compress::Gzip \
Getopt::Long \ Getopt::Long \
Mail::IMAPClient \ Mail::IMAPClient \
Mail::Mbox::MessageParser \ Mail::Mbox::MessageParser \
MIME::Base64 \ MIME::Base64 \
MIME::Words \ MIME::Words \
MIME::Parser \ MIME::Parser \
MIME::Parser::Filer \ MIME::Parser::Filer \
XML::Parser \ XML::Parser \
XML::Simple \ XML::Simple \
DBI \ DBI \
DBD::mysql \ DBD::mysql \
DBD::Pg \ DBD::Pg \
Socket \ Socket \
Socket6 \ Socket6 \
PerlIO::gzip \ PerlIO::gzip \
; do cpan install $i; done \ ; do cpan install $i; done \
&& apk del mariadb-dev expat-dev openssl-dev perl-dev g++ make musl-obstack-dev libpq-dev && apk del mariadb-dev expat-dev openssl-dev perl-dev g++ make musl-obstack-dev libpq-dev
HEALTHCHECK --interval=1m --timeout=3s CMD curl --silent --fail http://127.0.0.1:80/fpm-ping HEALTHCHECK --interval=1m --timeout=3s CMD curl --silent --fail http://127.0.0.1:80/fpm-ping

View File

@@ -5,37 +5,47 @@ This image is intended to combine a dmarc report parser (see https://github.com/
It fetches dmarc report mails regularly from an IMAP server, stores them into a MySQL DB and visualizes them via Webserver/PHP module. It fetches dmarc report mails regularly from an IMAP server, stores them into a MySQL DB and visualizes them via Webserver/PHP module.
## Howto ## Howto
1. Create a _dmarc.example.com TXT DNS record for your domain, containg an IMAP postbox, e.g.
``` 1. Create a \_dmarc.example.com TXT DNS record for your domain, containg an IMAP postbox, e.g.
```bash
17:18 $ dig TXT _dmarc.schumann.link +short 17:18 $ dig TXT _dmarc.schumann.link +short
"v=DMARC1\; p=quarantine\; fo=1\; rua=mailto:dmarc@schumann.link\; ruf=mailto:dmarc@schumann.link\; adkim=s\; aspf=s\;" "v=DMARC1\; p=quarantine\; fo=1\; rua=mailto:dmarc@schumann.link\; ruf=mailto:dmarc@schumann.link\; adkim=s\; aspf=s\;"
``` ```
2. Create a MySQL Database and a user for this service
3. Run this docker image with below mentioned env vars 1. Create a MySQL Database and a user for this service
4. Access port 80 on the container (or 443) or put it behind a reverse proxy to view reports
``` 1. Run this docker image with below mentioned env vars
1. Access port 80 on the container (or 443) or put it behind a reverse proxy to view reports
```bash
docker pull gutmensch/dmarc-report docker pull gutmensch/dmarc-report
docker run -e ... -ti gutmensch/dmarc-report docker run -e ... -ti gutmensch/dmarc-report
``` ```
New dmarc reports will be fetched every 15 minutes past the hour, every hour. Therefore it can take up to one hour for the first report to be fetched. New dmarc reports will be fetched every 15 minutes past the hour, every hour. Therefore it can take up to one hour for the first report to be fetched.
## Versions for last build latest and docker image tag 1.3 ## Versions for last build latest and docker image tag 1.4
dmarcts report viewer: 2022-08-10
dmarcts report parser: 2022-08-10 dmarcts report viewer: 2023-01-07
dmarcts report parser: 2023-01-07
CAUTION: The old gutmensch/dmarc-report:latest image (older alpine, php5, etc.) is available still as gutmensch/dmarc-report:0.5. The current latest (and 1.0) uses the latest alpine version, newer MySQL client libraries, newer OpenSSL, etc. and improves compatibilitiy with MySQL 8+. CAUTION: The old gutmensch/dmarc-report:latest image (older alpine, php5, etc.) is available still as gutmensch/dmarc-report:0.5. The current latest (and 1.0) uses the latest alpine version, newer MySQL client libraries, newer OpenSSL, etc. and improves compatibilitiy with MySQL 8+.
## Frontend Screenshot ## Frontend Screenshot
![DMARC Report Viewer](https://github.com/gutmensch/docker-dmarc-report/blob/master/screenshot.png?raw=true) ![DMARC Report Viewer](https://github.com/gutmensch/docker-dmarc-report/blob/master/screenshot.png?raw=true)
## Sample docker compose / Environment variables ## Sample docker compose / Environment variables
The variables should be self-explanatory. Make sure to create the IMAP folders before the cron job runs! The variables should be self-explanatory. Make sure to create the IMAP folders before the cron job runs!
**docker-compose.yml** **docker-compose.yml**
```yaml ```yaml
version: '3.6' version: "3.6"
services: services:
dmarc-report: dmarc-report:
@@ -71,17 +81,22 @@ services:
``` ```
## Optional extended configuration ## Optional extended configuration
Use SSL instead of default TLS. Set both to 0 to turn off encryption. (not recommended) Use SSL instead of default TLS. Set both to 0 to turn off encryption. (not recommended)
```yaml ```yaml
- "PARSER_IMAP_SSL=1" - "PARSER_IMAP_SSL=1"
- "PARSER_IMAP_TLS=0" - "PARSER_IMAP_TLS=0"
```
Ignore ERROR: message_string() issue experienced with Exchange Online.
```yaml
- "PARSER_IMAP_IGNORE_ERROR=1"
```
Parser and Viewer support Postgres now too (default is mysql)
```yaml
- "REPORT_DB_TYPE=pgsql"
``` ```
Ignore ERROR: message_string() issue experienced with Exchange Online.
```yaml
- "PARSER_IMAP_IGNORE_ERROR=1"
```
Parser and Viewer support Postgres now too (default is mysql)
```yaml
- "REPORT_DB_TYPE=Pg"
```

View File

@@ -12,8 +12,8 @@ $dbname = $ENV{'REPORT_DB_NAME'};
$dbuser = $ENV{'REPORT_DB_USER'}; $dbuser = $ENV{'REPORT_DB_USER'};
$dbpass = $ENV{'REPORT_DB_PASS'}; $dbpass = $ENV{'REPORT_DB_PASS'};
$dbhost = $ENV{'REPORT_DB_HOST'}; # Set the hostname if we can't connect to the local socket. $dbhost = $ENV{'REPORT_DB_HOST'}; # Set the hostname if we can't connect to the local socket.
$dbport = $ENV{'REPORT_DB_PORT'} || 3306; $dbport = $ENV{'REPORT_DB_PORT'} // 3306;
$dbtype = $ENV{'REPORT_DB_TYPE'} || 'mysql'; $dbtype = $ENV{'REPORT_DB_TYPE'} // 'mysql';
if(exists $ENV{PARSER_IMAP_SERVER_WITH_PORT} && defined $ENV{PARSER_IMAP_SERVER_WITH_PORT}) { if(exists $ENV{PARSER_IMAP_SERVER_WITH_PORT} && defined $ENV{PARSER_IMAP_SERVER_WITH_PORT}) {
my @server_attr = split ':', $ENV{PARSER_IMAP_SERVER_WITH_PORT}; my @server_attr = split ':', $ENV{PARSER_IMAP_SERVER_WITH_PORT};
@@ -41,12 +41,12 @@ $imapmovefolder = $ENV{'PARSER_IMAP_MOVE_FOLDER'};
$imapmovefoldererr = $ENV{'PARSER_IMAP_MOVE_FOLDER_ERR'}; $imapmovefoldererr = $ENV{'PARSER_IMAP_MOVE_FOLDER_ERR'};
# maximum size of XML files to store in database, long files can cause transaction aborts # maximum size of XML files to store in database, long files can cause transaction aborts
$maxsize_xml = 50000; $maxsize_xml = $ENV{'PARSER_XML_MAXSIZE'} // 50000;
# store XML as base64 encopded gzip in database (save space, harder usable) # store XML as base64 encopded gzip in database (save space, harder usable)
$compress_xml = 0; $compress_xml = $ENV{'PARSER_XML_COMPRESS'} // 0;
# if there was an error during file processing (message does not contain XML or ZIP parts, # if there was an error during file processing (message does not contain XML or ZIP parts,
# or a database error) the parser reports an error and does not delete the file, even if # or a database error) the parser reports an error and does not delete the file, even if
# delete_reports is set (or --delete is given). Deletion can be enforced by delete_failed, # delete_reports is set (or --delete is given). Deletion can be enforced by delete_failed,
# however not for database errors. # however not for database errors.
$delete_failed = 0; $delete_failed = $ENV{'PARSER_DELETE_FAILED'} // 0;