├── LICENSE ├── README.md ├── dmarc-imap-downloader ├── dmarc-imap-downloader.pip └── dmarc-imap-downloader.py ├── images ├── architecture.graphml ├── architecture.png └── dashboard.png ├── kibana └── dmarc_statistics.json └── logstash ├── 10.inputs.conf ├── 20.filters.conf └── 30.outputs.conf /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dmarc-elk-stack 2 | 3 | This repository contains logstash config and a kibana dashboard used to analyze DMARC reports. 4 | 5 | The architecure is a classical ELK stack. The only specific part is the python script used to fetch and extract DMARC reports for logstash. 6 | 7 | ![Architecture](/images/architecture.png) 8 | 9 | As said before, the python script `dmarc-imap-downloader.py` fetches DMARC reports over IMAP and extracts them into a specific directory organized by date. A cron task can be preiodicly scheduled: 10 | 11 | ``` 12 | 0,30 * * * * root /var/lib/dmarc-imap-downloader/virtualenv/bin/python /var/lib/dmarc-imap-downloader/dmarc-imap-downloader.py -s -u -p -f -D /var/cache/dmarc-reports -l /var/log/dmarc-imap-downloader.log >/var/log/dmarc-imap-downloader.cron.log 2>&1 13 | ``` 14 | 15 | Then, logstash scans periodicly fo new files in `/var/cache/dmarc-reports`. The new xml files are ingested and: 16 | 17 | * splitted on each record found, 18 | * data type is enforced for date and integers values, 19 | * reverse DNS records are filled, 20 | * geoip localization is added, 21 | * and finally records are sent to the daily index in elasticsearch. 22 | 23 | The kibana dashboard looks like that: 24 | 25 | ![DMARC statistics](/images/dashboard.png) 26 | 27 | # Contribution 28 | 29 | Feel free to reuse and modify as you wish. Contribution is welcomed too. 30 | -------------------------------------------------------------------------------- /dmarc-imap-downloader/dmarc-imap-downloader.pip: -------------------------------------------------------------------------------- 1 | IMAPClient==2.1.0 2 | six==1.12.0 3 | -------------------------------------------------------------------------------- /dmarc-imap-downloader/dmarc-imap-downloader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | import email 5 | import re 6 | import os 7 | import gzip 8 | import zipfile 9 | import io 10 | import logging 11 | import logging.handlers 12 | import argparse 13 | from imapclient import IMAPClient 14 | 15 | # ------------------------------------------------------------------------------ 16 | 17 | LOG = logging.getLogger('logger') 18 | LOG.setLevel(logging.INFO) 19 | DEFAULT_FORMAT = logging.Formatter("%(asctime)s %(levelname)-8s: %(message)s", 20 | "%H:%M:%S") 21 | STDOUT_STREAM_HANDLER = logging.StreamHandler(sys.stdout) 22 | STDOUT_STREAM_HANDLER.setFormatter(DEFAULT_FORMAT) 23 | LOG.addHandler(STDOUT_STREAM_HANDLER) 24 | 25 | # ------------------------------------------------------------------------------ 26 | 27 | 28 | def extract_dmarc_reports(imap_server, user, password, imap_folder, 29 | report_directory): 30 | server = IMAPClient(imap_server, use_uid=True) 31 | server.login(user, password) 32 | select_info = server.select_folder(imap_folder) 33 | LOG.info('{} messages in {}'.format(select_info[b'EXISTS'], imap_folder)) 34 | 35 | messages = server.search([u'UNSEEN']) 36 | LOG.info("{} unseen messages to process".format(len(messages))) 37 | 38 | attachments = [] 39 | valid_message_counter = 0 40 | for msgid, data in server.fetch(messages, ['ENVELOPE', 'RFC822']).items(): 41 | envelope = data[b'ENVELOPE'] 42 | email_message = email.message_from_bytes(data[b'RFC822']) 43 | LOG.debug('ID #{}: "{}" received {} / multipart: {} / disposition: {} / content-type: {}'.format(msgid, envelope.subject.decode(), envelope.date, email_message.is_multipart(), email_message.get_content_disposition(), email_message.get_content_type())) 44 | if email_message.is_multipart(): 45 | for attachement in email_message.get_payload(): 46 | if attachement.get_content_disposition() == 'attachment': 47 | LOG.debug('\t{}: {}'.format(attachement.get_content_type(), attachement.get_filename())) 48 | data = attachement.get_payload(decode=True) 49 | filename = attachement.get_filename() 50 | attachments.append({ 51 | 'filename': filename, 52 | 'data': data, 53 | 'email': email_message, 54 | 'envelope': envelope, 55 | }) 56 | valid_message_counter += 1 57 | elif email_message.get_content_disposition() == 'attachment': 58 | data = email_message.get_payload(decode=True) 59 | filename = email_message.get_filename() 60 | attachments.append({ 61 | 'filename': filename, 62 | 'data': data, 63 | 'email': email_message, 64 | 'envelope': envelope, 65 | }) 66 | valid_message_counter += 1 67 | else: 68 | LOG.warning('skipping invalid email <{} | Subject: {}>'.format(envelope.date, envelope.subject.decode())) 69 | 70 | valid_report_filename_regex = re.compile('^([a-zA-Z0-9\-]+\.?)+!([a-zA-Z0-9\-]+\.?)+!\d{10}!\d{10}(![a-zA-Z0-9\-]+)?\.xml$') 71 | valid_attachment_filename_regex = re.compile('^([a-zA-Z0-9\-]+\.?)+!([a-zA-Z0-9\-]+\.?)+!\d{10}!\d{10}(![a-zA-Z0-9\-]+)?\.(xml|xml\.gz|zip|xml\.zip)$') 72 | dmarc_reports = [] 73 | for attachment in attachments: 74 | filename = attachment['filename'] 75 | email_info = attachment['email'] 76 | data = attachment['data'] 77 | envelope = attachment['envelope'] 78 | if not valid_attachment_filename_regex.match(filename): 79 | LOG.warning("invalid attachment name format <{}> from email <{} | Subject: {}>".format(filename, envelope.date, envelope.subject.decode())) 80 | continue 81 | if filename.endswith('.xml.gz'): 82 | report_filename = filename[:-3] 83 | xml_data = gzip.decompress(data).decode() 84 | dmarc_reports.append({ 85 | 'attachment_infos': attachment, 86 | 'xml': xml_data.strip(), 87 | 'report_filename': report_filename, 88 | }) 89 | elif filename.endswith('.zip'): 90 | zip_data = io.BytesIO(data) 91 | if not zipfile.is_zipfile(zip_data): 92 | LOG.warning("invalid zip file <{}> from email <{} | Subject: {}>".format(filename, envelope.date, envelope.subject.decode())) 93 | continue 94 | with zipfile.ZipFile(zip_data) as zip_file: 95 | for report_filename in zip_file.namelist(): 96 | if not valid_report_filename_regex.match(report_filename): 97 | LOG.warning("invalid report filename <{}> in attachment <{}> from email <{} | Subject: {}>".format(report_filename, filename, envelope.date, envelope.subject.decode())) 98 | continue 99 | xml_data = zip_file.read(report_filename).decode() 100 | dmarc_reports.append({ 101 | 'attachment_infos': attachment, 102 | 'xml': xml_data.strip(), 103 | 'report_filename': report_filename, 104 | }) 105 | elif filename.endswith('.xml'): 106 | dmarc_reports.append({ 107 | 'attachment_infos': attachment, 108 | 'xml': data.strip(), 109 | 'report_filename': filename, 110 | }) 111 | 112 | if not os.path.isdir(report_directory): 113 | raise Exception('Directory <{}> does not exists'.format(report_directory)) 114 | 115 | already_exist_counter = 0 116 | for report in dmarc_reports: 117 | report_filename = report['report_filename'] 118 | xml_data = report['xml'] 119 | envelope = report['attachment_infos']['envelope'] 120 | reception_daystamp = envelope.date.strftime('%Y-%m-%d') 121 | dirpath = os.path.join(report_directory, reception_daystamp) 122 | os.makedirs(dirpath, mode=0o755, exist_ok=True) 123 | filepath = os.path.join(dirpath, report_filename) 124 | if os.path.exists(filepath): 125 | LOG.debug('file <{}> already present'.format(filepath)) 126 | already_exist_counter += 1 127 | continue 128 | with open(filepath, "w") as report_file: 129 | LOG.debug('creating <{}>'.format(filepath)) 130 | report_file.write(xml_data) 131 | 132 | LOG.info('{} reports processed in {} messages - {} reports already exists'.format(len(dmarc_reports), valid_message_counter, already_exist_counter)) 133 | 134 | 135 | if __name__ == '__main__': 136 | PARSER = argparse.ArgumentParser(description="DMARC report imap downloader") 137 | PARSER.add_argument('-d', '--debug', action='store_true', dest='debug') 138 | PARSER.add_argument('-s', '--imap-server', type=str, required=True, 139 | help='imap server address (ex: imap.gmail.com)') 140 | PARSER.add_argument('-u', '--user', type=str, required=True) 141 | PARSER.add_argument('-p', '--password', type=str, required=True) 142 | PARSER.add_argument('-f', '--imap-folder', type=str, required=True, 143 | help='imap folder/google tag where to find reports') 144 | PARSER.add_argument('-D', '--directory', type=str, required=True, 145 | help='where to place downloaded reports') 146 | PARSER.add_argument('-l', '--log-file', type=str, required=False, 147 | help='log to file instead of stdout') 148 | ARGS = PARSER.parse_args() 149 | 150 | LOG_FILE = getattr(ARGS, 'log_file', None) 151 | if LOG_FILE: 152 | ROTATING_FILE_HANDLER = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes=1024*1024*10, backupCount=3) 153 | ROTATING_FILE_HANDLER.setFormatter(DEFAULT_FORMAT) 154 | LOG.removeHandler(STDOUT_STREAM_HANDLER) 155 | LOG.addHandler(ROTATING_FILE_HANDLER) 156 | 157 | if getattr(ARGS, 'debug'): 158 | LOG.setLevel(logging.DEBUG) 159 | LOG.debug(ARGS) 160 | 161 | IMAP_SERVER = getattr(ARGS, 'imap_server') 162 | USER = getattr(ARGS, 'user') 163 | PASSWORD = getattr(ARGS, 'password') 164 | IMAP_FOLDER = getattr(ARGS, 'imap_folder') 165 | REPORT_DIRECTORY = getattr(ARGS, 'directory') 166 | extract_dmarc_reports(IMAP_SERVER, USER, PASSWORD, IMAP_FOLDER, REPORT_DIRECTORY) 167 | -------------------------------------------------------------------------------- /images/architecture.graphml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | DMARC XML 24 | reports 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Asterisk 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Asterisk 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Asterisk 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Asterisk 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | DMARC XML 127 | reports 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | dmarc-imap-downloader.py 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | Mail server 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | IMAP fetch 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 236 80"><defs><style>.cls-1{fill:#00bfb3;}.cls-2{fill:#fec514;}.cls-3{fill:#343741;}</style></defs><title>Logstash Color Lockup</title><rect class="cls-1" x="40" y="48" width="22" height="24"/><path class="cls-2" d="M10,8H8V48H34V32A24,24,0,0,0,10,8Z"/><path class="cls-3" d="M8,48H8A24,24,0,0,0,32,72h2V48Z"/><path d="M83.89,49.18H79.48V20h4.41Z"/><path d="M108.58,38.78c0,3.38-.87,6-2.6,7.93a9.35,9.35,0,0,1-7.26,2.85,10,10,0,0,1-5.14-1.31,8.72,8.72,0,0,1-3.43-3.77,12.85,12.85,0,0,1-1.2-5.7c0-3.37.86-6,2.59-7.88a9.35,9.35,0,0,1,7.29-2.83A9.15,9.15,0,0,1,106,31,11.18,11.18,0,0,1,108.58,38.78Zm-15.09,0q0,7.17,5.3,7.18T104,38.78q0-7.11-5.28-7.11a4.52,4.52,0,0,0-4,1.84A9.35,9.35,0,0,0,93.49,38.78Z"/><path d="M131.16,28.45v2.41l-3.55.66a5.65,5.65,0,0,1,.81,1.61,6.49,6.49,0,0,1,.32,2,6.2,6.2,0,0,1-2.21,5,9.25,9.25,0,0,1-6.1,1.84,9.92,9.92,0,0,1-1.8-.15A2.47,2.47,0,0,0,117.21,44a1.15,1.15,0,0,0,.66,1.07,5.73,5.73,0,0,0,2.45.36h3.62a8,8,0,0,1,5.21,1.46,5.13,5.13,0,0,1,1.78,4.22A6.15,6.15,0,0,1,128,56.5q-2.91,1.91-8.4,1.91a11.57,11.57,0,0,1-6.47-1.5,4.85,4.85,0,0,1-2.23-4.28,4.57,4.57,0,0,1,1.2-3.21,6.52,6.52,0,0,1,3.39-1.81,3.26,3.26,0,0,1-1.45-1.21,3.1,3.1,0,0,1,.08-3.72,7.72,7.72,0,0,1,1.95-1.6,5.77,5.77,0,0,1-2.62-2.26,6.69,6.69,0,0,1-1-3.66,6.56,6.56,0,0,1,2.13-5.23,8.94,8.94,0,0,1,6.07-1.86,14.93,14.93,0,0,1,1.84.12,10.85,10.85,0,0,1,1.46.26Zm-16.3,24a2.41,2.41,0,0,0,1.29,2.19,7.07,7.07,0,0,0,3.61.77,10.88,10.88,0,0,0,5.36-1,3.1,3.1,0,0,0,1.76-2.74,2.05,2.05,0,0,0-1-1.92,7.79,7.79,0,0,0-3.59-.57H119a4.71,4.71,0,0,0-3,.89A2.91,2.91,0,0,0,114.86,52.41Zm1.9-17.25a4.17,4.17,0,0,0,1,3,3.8,3.8,0,0,0,2.88,1.05q3.83,0,3.82-4.09a4.63,4.63,0,0,0-.94-3.12,3.62,3.62,0,0,0-2.88-1.1,3.7,3.7,0,0,0-2.9,1.09A4.54,4.54,0,0,0,116.76,35.16Z"/><path d="M148.93,43.28a5.44,5.44,0,0,1-2.21,4.66,10.62,10.62,0,0,1-6.34,1.62,14.89,14.89,0,0,1-6.65-1.26V44.5a16.35,16.35,0,0,0,6.8,1.68q4.07,0,4.07-2.45a2,2,0,0,0-.45-1.32,5.18,5.18,0,0,0-1.48-1.08,25.2,25.2,0,0,0-2.87-1.28A13.33,13.33,0,0,1,135,37.28a5.17,5.17,0,0,1-1.26-3.6,4.73,4.73,0,0,1,2.14-4.14,10.23,10.23,0,0,1,5.85-1.47,16.47,16.47,0,0,1,6.91,1.48l-1.42,3.32a15.52,15.52,0,0,0-5.64-1.39c-2.33,0-3.49.67-3.49,2a2,2,0,0,0,.91,1.65,20,20,0,0,0,4,1.86,17.65,17.65,0,0,1,3.73,1.82,5.43,5.43,0,0,1,1.73,1.9A5.58,5.58,0,0,1,148.93,43.28Z"/><path d="M161.42,46a10.61,10.61,0,0,0,3.22-.51v3.32a8.65,8.65,0,0,1-1.88.53,12.5,12.5,0,0,1-2.39.22q-6.27,0-6.26-6.6V31.78h-2.83v-2l3-1.61,1.5-4.39h2.72v4.62h5.91v3.33h-5.91v11.1a3.13,3.13,0,0,0,.8,2.36A2.93,2.93,0,0,0,161.42,46Z"/><path d="M181.76,49.18l-.88-2.88h-.15a8.37,8.37,0,0,1-3,2.57,9.46,9.46,0,0,1-3.9.69A6.6,6.6,0,0,1,169,47.91a6.19,6.19,0,0,1-1.71-4.67,5.48,5.48,0,0,1,2.38-4.84q2.37-1.63,7.25-1.78l3.58-.11V35.4a4.24,4.24,0,0,0-.92-3,3.78,3.78,0,0,0-2.88-1,10.08,10.08,0,0,0-3.06.46A25.65,25.65,0,0,0,170.87,33l-1.43-3.15a15.48,15.48,0,0,1,3.7-1.34,16.8,16.8,0,0,1,3.79-.46q3.94,0,6,1.73t2,5.41v14Zm-6.56-3a5.42,5.42,0,0,0,3.85-1.34,4.84,4.84,0,0,0,1.46-3.76v-1.8l-2.67.12a9,9,0,0,0-4.52,1,3.15,3.15,0,0,0-1.42,2.84,2.76,2.76,0,0,0,.83,2.14A3.51,3.51,0,0,0,175.2,46.18Z"/><path d="M205,43.28a5.42,5.42,0,0,1-2.21,4.66,10.6,10.6,0,0,1-6.34,1.62,14.89,14.89,0,0,1-6.65-1.26V44.5a16.38,16.38,0,0,0,6.8,1.68c2.72,0,4.07-.82,4.07-2.45a2,2,0,0,0-.45-1.32,5.18,5.18,0,0,0-1.48-1.08,25.2,25.2,0,0,0-2.87-1.28A13.27,13.27,0,0,1,191,37.28a5.13,5.13,0,0,1-1.27-3.6,4.74,4.74,0,0,1,2.15-4.14,10.2,10.2,0,0,1,5.84-1.47,16.52,16.52,0,0,1,6.92,1.48l-1.43,3.32a15.52,15.52,0,0,0-5.64-1.39c-2.33,0-3.49.67-3.49,2a2,2,0,0,0,.91,1.65A20.21,20.21,0,0,0,199,37a18.17,18.17,0,0,1,3.73,1.82,5.4,5.4,0,0,1,1.72,1.9A5.46,5.46,0,0,1,205,43.28Z"/><path d="M228,49.18h-4.42V36.43a5.6,5.6,0,0,0-1-3.58,3.73,3.73,0,0,0-3.07-1.18,4.83,4.83,0,0,0-4.07,1.66q-1.31,1.66-1.31,5.56V49.18h-4.4V20h4.4v7.4a34.54,34.54,0,0,1-.22,3.81h.28a6.09,6.09,0,0,1,2.5-2.32,8.08,8.08,0,0,1,3.74-.83q7.54,0,7.54,7.59Z"/></svg> 232 | <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 208 80"><defs><style>.cls-1{fill:#343741;}.cls-1,.cls-2,.cls-3{fill-rule:evenodd;}.cls-2{fill:#f04e98;}.cls-3{fill:#00bfb3;}</style></defs><title>Kibana Color Lockup</title><path d="M84.21,40.23l2.49-3.11L93,30.45H98l-8.34,8.9,8.87,11.83H93.39l-6.65-9.09-2.42,2v7.1H80V22h4.37V36.24l-.23,4Z"/><path d="M101.64,25a2.45,2.45,0,0,1,.65-1.82,2.54,2.54,0,0,1,1.85-.63,2.49,2.49,0,0,1,1.81.63,2.45,2.45,0,0,1,.64,1.82,2.39,2.39,0,0,1-.64,1.77,2.42,2.42,0,0,1-1.81.65,2.47,2.47,0,0,1-1.85-.65A2.39,2.39,0,0,1,101.64,25Zm4.67,26.23h-4.4V30.45h4.4Z"/><path d="M123.21,30.07a7.2,7.2,0,0,1,6,2.81q2.17,2.82,2.17,7.9c0,3.4-.73,6-2.2,7.94a8,8,0,0,1-12.2,0h-.3l-.81,2.45h-3.3V22H117V29c0,.51,0,1.27-.08,2.28s-.08,1.66-.11,1.93H117A7,7,0,0,1,123.21,30.07Zm-1.15,3.6a4.46,4.46,0,0,0-3.83,1.57c-.78,1-1.19,2.79-1.21,5.24v.3q0,3.78,1.2,5.48a4.46,4.46,0,0,0,3.92,1.7,4,4,0,0,0,3.55-1.86,9.8,9.8,0,0,0,1.21-5.36Q126.9,33.67,122.06,33.67Z"/><path d="M149.51,51.18l-.88-2.88h-.15a8.45,8.45,0,0,1-3,2.57,9.46,9.46,0,0,1-3.9.69,6.6,6.6,0,0,1-4.77-1.65,6.2,6.2,0,0,1-1.72-4.67,5.49,5.49,0,0,1,2.39-4.84q2.37-1.63,7.25-1.78l3.58-.11V37.4a4.24,4.24,0,0,0-.92-3,3.78,3.78,0,0,0-2.88-1,10.08,10.08,0,0,0-3.06.46A25.65,25.65,0,0,0,138.62,35l-1.43-3.15a15.48,15.48,0,0,1,3.7-1.34,16.74,16.74,0,0,1,3.79-.46q3.94,0,6,1.73t2,5.41v14Zm-6.56-3a5.42,5.42,0,0,0,3.85-1.34,4.84,4.84,0,0,0,1.46-3.76v-1.8l-2.67.12a9,9,0,0,0-4.52,1,3.15,3.15,0,0,0-1.42,2.84,2.79,2.79,0,0,0,.82,2.14A3.56,3.56,0,0,0,143,48.18Z"/><path d="M177.06,51.18h-4.43V38.43a5.6,5.6,0,0,0-1-3.58,3.74,3.74,0,0,0-3.07-1.18,4.89,4.89,0,0,0-4.09,1.65q-1.29,1.65-1.29,5.53V51.18h-4.41V30.45h3.45l.62,2.71h.23a6.08,6.08,0,0,1,2.66-2.28,8.87,8.87,0,0,1,3.82-.81q7.47,0,7.47,7.59Z"/><path d="M196.16,51.18l-.88-2.88h-.15a8.45,8.45,0,0,1-3,2.57,9.46,9.46,0,0,1-3.9.69,6.59,6.59,0,0,1-4.77-1.65,6.2,6.2,0,0,1-1.72-4.67,5.49,5.49,0,0,1,2.39-4.84q2.37-1.63,7.25-1.78l3.58-.11V37.4a4.24,4.24,0,0,0-.92-3,3.78,3.78,0,0,0-2.88-1,10.08,10.08,0,0,0-3.06.46A25.65,25.65,0,0,0,185.27,35l-1.43-3.15a15.48,15.48,0,0,1,3.7-1.34,16.8,16.8,0,0,1,3.79-.46q3.94,0,6,1.73t2,5.41v14Zm-6.56-3a5.42,5.42,0,0,0,3.85-1.34,4.84,4.84,0,0,0,1.46-3.76v-1.8l-2.67.12a9,9,0,0,0-4.52,1,3.15,3.15,0,0,0-1.42,2.84,2.79,2.79,0,0,0,.82,2.14A3.54,3.54,0,0,0,189.6,48.18Z"/><path class="cls-1" d="M8,32V65.58L31.87,38.09A49.82,49.82,0,0,0,8,32Z"/><path class="cls-2" d="M8,8V32a49.82,49.82,0,0,1,23.87,6.09L58,8Z"/><path class="cls-3" d="M37,41.31,12.53,69.51,10.37,72H57A50,50,0,0,0,37,41.31Z"/></svg> 233 | <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 328 80"><defs><style>.cls-1{fill:#343741;}.cls-1,.cls-2,.cls-3{fill-rule:evenodd;}.cls-2{fill:#fec514;}.cls-3{fill:#00bfb3;}</style></defs><title>Elastic Search Color Lockup</title><path d="M93.27,49.56a10,10,0,0,1-7.56-2.82A10.73,10.73,0,0,1,83,39c0-3.38.84-6.05,2.53-8a8.75,8.75,0,0,1,7-2.91A8.54,8.54,0,0,1,99,30.56a9.54,9.54,0,0,1,2.38,6.87v2.38H87.52a6.78,6.78,0,0,0,1.63,4.64,5.68,5.68,0,0,0,4.33,1.62,15.48,15.48,0,0,0,3.42-.35,17.49,17.49,0,0,0,3.4-1.15v3.58A13.45,13.45,0,0,1,97,49.24,20.24,20.24,0,0,1,93.27,49.56Zm-.8-18.15a4.42,4.42,0,0,0-3.37,1.33,6.35,6.35,0,0,0-1.51,3.88H97a5.71,5.71,0,0,0-1.23-3.89A4.24,4.24,0,0,0,92.47,31.41Z"/><path d="M110.75,49.18h-4.41V20h4.41Z"/><path d="M130,49.18l-.88-2.88H129a8.45,8.45,0,0,1-3,2.57,9.46,9.46,0,0,1-3.9.69,6.59,6.59,0,0,1-4.77-1.65,6.2,6.2,0,0,1-1.72-4.67A5.49,5.49,0,0,1,118,38.4q2.37-1.63,7.25-1.78l3.58-.11V35.4a4.2,4.2,0,0,0-.93-3,3.74,3.74,0,0,0-2.87-1,10,10,0,0,0-3.06.46A25.65,25.65,0,0,0,119.13,33l-1.43-3.15a15.48,15.48,0,0,1,3.7-1.34,16.72,16.72,0,0,1,3.78-.46q4,0,6,1.73t2,5.41v14Zm-6.56-3a5.42,5.42,0,0,0,3.85-1.34,4.84,4.84,0,0,0,1.46-3.76v-1.8l-2.67.12a9.08,9.08,0,0,0-4.53,1,3.16,3.16,0,0,0-1.41,2.84,2.75,2.75,0,0,0,.82,2.14A3.54,3.54,0,0,0,123.46,46.18Z"/><path d="M153.25,43.28A5.42,5.42,0,0,1,151,47.94a10.6,10.6,0,0,1-6.34,1.62,14.89,14.89,0,0,1-6.65-1.26V44.5a16.35,16.35,0,0,0,6.8,1.68c2.72,0,4.07-.82,4.07-2.45a2,2,0,0,0-.45-1.32A5.18,5.18,0,0,0,147,41.33a25.2,25.2,0,0,0-2.87-1.28,13.33,13.33,0,0,1-4.85-2.77,5.17,5.17,0,0,1-1.26-3.6,4.71,4.71,0,0,1,2.15-4.14A10.18,10.18,0,0,1,146,28.07a16.55,16.55,0,0,1,6.92,1.48l-1.43,3.32a15.52,15.52,0,0,0-5.64-1.39c-2.33,0-3.49.67-3.49,2a2,2,0,0,0,.91,1.65,20,20,0,0,0,4,1.86A18,18,0,0,1,151,38.8a5.4,5.4,0,0,1,1.72,1.9A5.46,5.46,0,0,1,153.25,43.28Z"/><path d="M165.74,46a10.67,10.67,0,0,0,3.23-.51v3.32a8.93,8.93,0,0,1-1.89.53,12.43,12.43,0,0,1-2.39.22q-6.25,0-6.26-6.6V31.78H155.6v-2l3-1.61,1.5-4.39h2.72v4.62h5.91v3.33h-5.91v11.1a3.13,3.13,0,0,0,.8,2.36A2.93,2.93,0,0,0,165.74,46Z"/><path d="M172.85,23a2.45,2.45,0,0,1,.64-1.82,2.54,2.54,0,0,1,1.85-.63A2.23,2.23,0,0,1,177.8,23a2.25,2.25,0,0,1-2.46,2.42,2.47,2.47,0,0,1-1.85-.65A2.39,2.39,0,0,1,172.85,23Zm4.67,26.23h-4.41V28.45h4.41Z"/><path d="M192.18,49.56c-3.14,0-5.52-.92-7.16-2.75s-2.44-4.46-2.44-7.88.85-6.17,2.56-8,4.17-2.81,7.39-2.81a13.91,13.91,0,0,1,5.91,1.22l-1.33,3.54a13.41,13.41,0,0,0-4.61-1.08q-5.38,0-5.38,7.14a8.52,8.52,0,0,0,1.34,5.24,4.62,4.62,0,0,0,3.92,1.75A11.2,11.2,0,0,0,198,44.42v3.84a8.46,8.46,0,0,1-2.52,1A15.11,15.11,0,0,1,192.18,49.56Z"/><path d="M216.76,43.28a5.44,5.44,0,0,1-2.21,4.66,10.62,10.62,0,0,1-6.34,1.62,15,15,0,0,1-6.66-1.26V44.5a16.43,16.43,0,0,0,6.81,1.68q4.06,0,4.07-2.45a2,2,0,0,0-.45-1.32,5.33,5.33,0,0,0-1.48-1.08,26,26,0,0,0-2.87-1.28,13.24,13.24,0,0,1-4.85-2.77,5.17,5.17,0,0,1-1.26-3.6,4.73,4.73,0,0,1,2.14-4.14,10.2,10.2,0,0,1,5.84-1.47,16.48,16.48,0,0,1,6.92,1.48L215,32.87a15.52,15.52,0,0,0-5.65-1.39c-2.32,0-3.48.67-3.48,2a2,2,0,0,0,.9,1.65,20.21,20.21,0,0,0,4,1.86,17.91,17.91,0,0,1,3.73,1.82,5.43,5.43,0,0,1,1.73,1.9A5.58,5.58,0,0,1,216.76,43.28Z"/><path d="M230.58,49.56A10,10,0,0,1,223,46.74,10.73,10.73,0,0,1,220.28,39c0-3.38.85-6.05,2.54-8a8.71,8.71,0,0,1,7-2.91,8.56,8.56,0,0,1,6.49,2.49,9.54,9.54,0,0,1,2.38,6.87v2.38H224.82a6.82,6.82,0,0,0,1.63,4.64,5.69,5.69,0,0,0,4.33,1.62,15.51,15.51,0,0,0,3.43-.35,17.71,17.71,0,0,0,3.4-1.15v3.58a13.59,13.59,0,0,1-3.26,1.09A20.24,20.24,0,0,1,230.58,49.56Zm-.81-18.15a4.4,4.4,0,0,0-3.36,1.33,6.3,6.3,0,0,0-1.51,3.88h9.41a5.77,5.77,0,0,0-1.24-3.89A4.24,4.24,0,0,0,229.77,31.41Z"/><path d="M256.62,49.18l-.88-2.88h-.15a8.45,8.45,0,0,1-3,2.57,9.46,9.46,0,0,1-3.9.69,6.59,6.59,0,0,1-4.77-1.65,6.2,6.2,0,0,1-1.72-4.67,5.49,5.49,0,0,1,2.39-4.84q2.37-1.63,7.25-1.78l3.58-.11V35.4a4.2,4.2,0,0,0-.93-3,3.74,3.74,0,0,0-2.87-1,10,10,0,0,0-3.06.46A25.65,25.65,0,0,0,245.73,33l-1.43-3.15a15.48,15.48,0,0,1,3.7-1.34,16.72,16.72,0,0,1,3.78-.46q4,0,6,1.73t2,5.41v14Zm-6.56-3a5.42,5.42,0,0,0,3.85-1.34,4.84,4.84,0,0,0,1.46-3.76v-1.8l-2.67.12a9.08,9.08,0,0,0-4.53,1,3.16,3.16,0,0,0-1.41,2.84,2.75,2.75,0,0,0,.82,2.14A3.54,3.54,0,0,0,250.06,46.18Z"/><path d="M276.44,28.07a10.17,10.17,0,0,1,2.19.19l-.43,4.1a8.27,8.27,0,0,0-1.95-.22A5.63,5.63,0,0,0,272,33.86a6.23,6.23,0,0,0-1.64,4.49V49.18h-4.41V28.45h3.45L270,32.1h.23a8.13,8.13,0,0,1,2.69-2.94A6.35,6.35,0,0,1,276.44,28.07Z"/><path d="M290.84,49.56q-4.71,0-7.15-2.75t-2.45-7.88q0-5.24,2.56-8c1.71-1.87,4.17-2.81,7.4-2.81a13.9,13.9,0,0,1,5.9,1.22l-1.33,3.54a13.41,13.41,0,0,0-4.61-1.08q-5.39,0-5.38,7.14a8.52,8.52,0,0,0,1.34,5.24,4.63,4.63,0,0,0,3.93,1.75,11.23,11.23,0,0,0,5.57-1.46v3.84a8.52,8.52,0,0,1-2.53,1A15,15,0,0,1,290.84,49.56Z"/><path d="M319.73,49.18h-4.42V36.43a5.54,5.54,0,0,0-1-3.58,3.71,3.71,0,0,0-3.06-1.18,4.86,4.86,0,0,0-4.08,1.66q-1.31,1.66-1.3,5.56V49.18h-4.41V20h4.41v7.4a34.65,34.65,0,0,1-.23,3.81H306a6.12,6.12,0,0,1,2.51-2.32,8,8,0,0,1,3.74-.83q7.53,0,7.53,7.59Z"/><path class="cls-1" d="M8,40a32,32,0,0,0,1.05,8H48a8,8,0,0,0,8-8h0a8,8,0,0,0-8-8H9.09A32,32,0,0,0,8,40Z"/><path class="cls-2" d="M61.89,23.32A29.59,29.59,0,0,0,65,20a31.92,31.92,0,0,0-53.67,6H55.06A10.07,10.07,0,0,0,61.89,23.32Z"/><path class="cls-3" d="M55.06,54H11.33A31.92,31.92,0,0,0,65,60a29.59,29.59,0,0,0-3.11-3.32A10.07,10.07,0,0,0,55.06,54Z"/></svg> 234 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> 235 | <!-- Created with Inkscape (http://www.inkscape.org/) --> 236 | <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="110.4211" height="109.8461" id="svg2169" sodipodi:version="0.32" inkscape:version="0.45.1" version="1.0" sodipodi:docbase="/home/bene/Desktop" sodipodi:docname="dessin-1.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" data-ember-extension="1"> 237 | <defs id="defs2171"> 238 | <linearGradient id="linearGradient11301" inkscape:collect="always"> 239 | <stop id="stop11303" offset="0" style="stop-color:#ffe052;stop-opacity:1"/> 240 | <stop id="stop11305" offset="1" style="stop-color:#ffc331;stop-opacity:1"/> 241 | </linearGradient> 242 | <linearGradient gradientUnits="userSpaceOnUse" y2="168.1012" x2="147.77737" y1="111.92053" x1="89.136749" id="linearGradient11307" xlink:href="#linearGradient11301" inkscape:collect="always"/> 243 | <linearGradient id="linearGradient9515" inkscape:collect="always"> 244 | <stop id="stop9517" offset="0" style="stop-color:#387eb8;stop-opacity:1"/> 245 | <stop id="stop9519" offset="1" style="stop-color:#366994;stop-opacity:1"/> 246 | </linearGradient> 247 | <linearGradient gradientUnits="userSpaceOnUse" y2="131.85291" x2="110.14919" y1="77.070274" x1="55.549179" id="linearGradient9521" xlink:href="#linearGradient9515" inkscape:collect="always"/> 248 | </defs> 249 | <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.24748737" inkscape:cx="-260.46312" inkscape:cy="316.02744" inkscape:document-units="px" inkscape:current-layer="layer1" width="131.10236px" height="184.25197px" inkscape:window-width="872" inkscape:window-height="624" inkscape:window-x="5" inkscape:window-y="48"/> 250 | <metadata id="metadata2174"> 251 | <rdf:RDF> 252 | <cc:Work rdf:about=""> 253 | <dc:format>image/svg+xml</dc:format> 254 | <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> 255 | </cc:Work> 256 | </rdf:RDF> 257 | </metadata> 258 | <g inkscape:label="Calque 1" inkscape:groupmode="layer" id="layer1" transform="translate(-473.36088,-251.72485)"> 259 | <g id="g1894" transform="translate(428.42338,184.2561)"> 260 | <path style="opacity:1;color:#000000;fill:url(#linearGradient9521);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" d="M 99.75,67.46875 C 71.718268,67.468752 73.46875,79.625 73.46875,79.625 L 73.5,92.21875 L 100.25,92.21875 L 100.25,96 L 62.875,96 C 62.875,96 44.9375,93.965724 44.9375,122.25 C 44.937498,150.53427 60.59375,149.53125 60.59375,149.53125 L 69.9375,149.53125 L 69.9375,136.40625 C 69.9375,136.40625 69.433848,120.75 85.34375,120.75 C 101.25365,120.75 111.875,120.75 111.875,120.75 C 111.875,120.75 126.78125,120.99096 126.78125,106.34375 C 126.78125,91.696544 126.78125,82.125 126.78125,82.125 C 126.78125,82.124998 129.04443,67.46875 99.75,67.46875 z M 85,75.9375 C 87.661429,75.937498 89.8125,78.088571 89.8125,80.75 C 89.812502,83.411429 87.661429,85.5625 85,85.5625 C 82.338571,85.562502 80.1875,83.411429 80.1875,80.75 C 80.187498,78.088571 82.338571,75.9375 85,75.9375 z " id="path8615"/> 261 | <path id="path8620" d="M 100.5461,177.31485 C 128.57784,177.31485 126.82735,165.1586 126.82735,165.1586 L 126.7961,152.56485 L 100.0461,152.56485 L 100.0461,148.7836 L 137.4211,148.7836 C 137.4211,148.7836 155.3586,150.81787 155.3586,122.53359 C 155.35861,94.249323 139.70235,95.252343 139.70235,95.252343 L 130.3586,95.252343 L 130.3586,108.37734 C 130.3586,108.37734 130.86226,124.03359 114.95235,124.03359 C 99.042448,124.03359 88.421098,124.03359 88.421098,124.03359 C 88.421098,124.03359 73.514848,123.79263 73.514848,138.43985 C 73.514848,153.08705 73.514848,162.6586 73.514848,162.6586 C 73.514848,162.6586 71.251668,177.31485 100.5461,177.31485 z M 115.2961,168.8461 C 112.63467,168.8461 110.4836,166.69503 110.4836,164.0336 C 110.4836,161.37217 112.63467,159.2211 115.2961,159.2211 C 117.95753,159.2211 120.1086,161.37217 120.1086,164.0336 C 120.10861,166.69503 117.95753,168.8461 115.2961,168.8461 z " style="opacity:1;color:#000000;fill:url(#linearGradient11307);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"/> 262 | </g> 263 | </g> 264 | </svg> 265 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> 266 | <!-- Created with Inkscape (http://www.inkscape.org/) --> 267 | 268 | <svg 269 | xmlns:dc="http://purl.org/dc/elements/1.1/" 270 | xmlns:cc="http://creativecommons.org/ns#" 271 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 272 | xmlns:svg="http://www.w3.org/2000/svg" 273 | xmlns="http://www.w3.org/2000/svg" 274 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 275 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 276 | id="svg2" 277 | version="1.1" 278 | inkscape:version="0.91 r13725" 279 | width="125" 280 | height="125" 281 | viewBox="0 0 125 125" 282 | sodipodi:docname="Stack Filled-100.svg"> 283 | <metadata 284 | id="metadata8"> 285 | <rdf:RDF> 286 | <cc:Work 287 | rdf:about=""> 288 | <dc:format>image/svg+xml</dc:format> 289 | <dc:type 290 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 291 | <dc:title /> 292 | </cc:Work> 293 | </rdf:RDF> 294 | </metadata> 295 | <defs 296 | id="defs6" /> 297 | <sodipodi:namedview 298 | pagecolor="#ffffff" 299 | bordercolor="#666666" 300 | borderopacity="1" 301 | objecttolerance="10" 302 | gridtolerance="10" 303 | guidetolerance="10" 304 | inkscape:pageopacity="0" 305 | inkscape:pageshadow="2" 306 | inkscape:window-width="952" 307 | inkscape:window-height="1072" 308 | id="namedview4" 309 | showgrid="false" 310 | inkscape:zoom="5.3400704" 311 | inkscape:cx="81.874673" 312 | inkscape:cy="60.415215" 313 | inkscape:window-x="0" 314 | inkscape:window-y="0" 315 | inkscape:window-maximized="0" 316 | inkscape:current-layer="svg2" /> 317 | <path 318 | style="fill:#000000" 319 | d="m 0.525956,123.31764 c -0.36005064,-0.93828 -0.48505919,-5.30296 -0.27779676,-9.6993 L 0.625,105.625 l 61.875,0 61.875,0 0,9.375 0,9.375 -61.597204,0.3243 c -51.108325,0.26908 -61.7086753,0.0338 -62.25184,-1.38166 z m 110.138974,-5.86176 c 2.24308,-2.47858 2.23197,-2.61454 -0.43127,-5.27777 l -2.73366,-2.73366 -2.73366,2.73366 c -2.66324,2.66323 -2.67435,2.79919 -0.43127,5.27777 1.26632,1.39927 2.69054,2.54412 3.16493,2.54412 0.47439,0 1.89861,-1.14485 3.16493,-2.54412 z M 0.525956,98.31764 C 0.16590536,97.379364 0.04089681,93.014679 0.24815924,88.618341 L 0.625,80.625 l 61.875,0 61.875,0 0,9.375 0,9.375 -61.597204,0.324299 C 11.669471,99.968376 1.0691207,99.733105 0.525956,98.31764 Z M 110.66493,92.455883 c 2.24308,-2.478579 2.23197,-2.614539 -0.43127,-5.277778 l -2.73366,-2.73366 -2.73366,2.73366 c -2.66324,2.663239 -2.67435,2.799199 -0.43127,5.277778 C 105.60139,93.855147 107.02561,95 107.5,95 c 0.47439,0 1.89861,-1.144853 3.16493,-2.544117 z M 0.525956,73.31764 C 0.16590536,72.379364 0.04089681,68.014679 0.24815924,63.618341 L 0.625,55.625 l 61.875,0 61.875,0 0,9.375 0,9.375 -61.597204,0.324299 C 11.669471,74.968376 1.0691207,74.733105 0.525956,73.31764 Z M 110.66493,67.455883 c 2.24308,-2.478579 2.23197,-2.614539 -0.43127,-5.277778 l -2.73366,-2.73366 -2.73366,2.73366 c -2.66324,2.663239 -2.67435,2.799199 -0.43127,5.277778 C 105.60139,68.855147 107.02561,70 107.5,70 c 0.47439,0 1.89861,-1.144853 3.16493,-2.544117 z M 0.56010486,46.917255 C 0.96462614,44.877995 4.399763,33.48737 8.1937424,21.604755 L 15.091886,0 62.5,0 l 47.40811,0 6.89815,21.604755 c 3.79398,11.882615 7.26968,23.462447 7.72378,25.732961 l 0.82565,4.128205 L 62.590147,51.045461 -0.17538835,50.625 0.56010486,46.917255 Z" 320 | id="path3338" 321 | inkscape:connector-curvature="0" /> 322 | <path 323 | style="fill:#ffffff" 324 | d="m 106.79944,69.519879 c -0.83185,-0.509864 -3.81784,-3.71857 -3.94982,-4.244433 -0.16582,-0.660682 0.36576,-1.397163 2.63409,-3.649423 l 1.98029,-1.966266 2.33622,2.355424 c 2.81888,2.842043 2.82789,2.874437 1.3111,4.713309 -1.07002,1.297235 -3.13886,3.137632 -3.52573,3.136425 -0.1234,-3.85e-4 -0.47717,-0.155651 -0.78615,-0.345036 z" 325 | id="path3333" 326 | inkscape:connector-curvature="0" /> 327 | <path 328 | style="fill:#ffffff" 329 | d="m 106.64069,94.377099 c -0.97825,-0.647964 -3.19398,-2.966159 -3.61708,-3.784344 -0.42309,-0.818165 -0.13428,-1.280693 2.34174,-3.750265 l 2.20208,-2.196344 2.18077,2.227739 c 2.16851,2.215226 2.5435,2.806535 2.28877,3.609116 -0.16391,0.51643 -3.22033,3.699088 -3.97942,4.143776 -0.5431,0.318158 -0.56556,0.314201 -1.41686,-0.249678 z" 330 | id="path3335" 331 | inkscape:connector-curvature="0" /> 332 | <path 333 | style="fill:#ffffff" 334 | d="m 106.79944,119.51922 c -0.83185,-0.50986 -3.81784,-3.71857 -3.94982,-4.24443 -0.16582,-0.66069 0.36576,-1.39717 2.63409,-3.64943 l 1.98029,-1.96626 2.33622,2.35542 c 2.81888,2.84205 2.82789,2.87444 1.3111,4.71331 -1.07002,1.29724 -3.13886,3.13763 -3.52573,3.13643 -0.1234,-3.9e-4 -0.47717,-0.15566 -0.78615,-0.34504 z" 335 | id="path3337" 336 | inkscape:connector-curvature="0" /> 337 | </svg> 338 | 339 | 340 | 341 | 342 | -------------------------------------------------------------------------------- /images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwanko/dmarc-elk-stack/5545b7301f12ba66605a82846263a15d25be851a/images/architecture.png -------------------------------------------------------------------------------- /images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kwanko/dmarc-elk-stack/5545b7301f12ba66605a82846263a15d25be851a/images/dashboard.png -------------------------------------------------------------------------------- /kibana/dmarc_statistics.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "_id": "683e7dd0-ffcb-11e8-bf48-2542df260526", 4 | "_type": "dashboard", 5 | "_source": { 6 | "title": "DMARC statistics", 7 | "hits": 0, 8 | "description": "", 9 | "panelsJSON": "[{\"embeddableConfig\":{\"mapCenter\":[0,0],\"mapZoom\":1},\"gridData\":{\"x\":9,\"y\":16,\"w\":15,\"h\":15,\"i\":\"1\"},\"id\":\"8af28de0-fef3-11e8-bf48-2542df260526\",\"panelIndex\":\"1\",\"type\":\"visualization\",\"version\":\"6.5.3\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":31,\"i\":\"2\"},\"id\":\"7c1fbc10-fef4-11e8-bf48-2542df260526\",\"panelIndex\":\"2\",\"type\":\"visualization\",\"version\":\"6.5.3\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":5,\"w\":9,\"h\":26,\"i\":\"3\"},\"id\":\"963bac90-ffca-11e8-bf48-2542df260526\",\"panelIndex\":\"3\",\"type\":\"visualization\",\"version\":\"6.5.3\"},{\"embeddableConfig\":{\"vis\":{\"colors\":{\"fail\":\"#E24D42\",\"pass\":\"#629E51\"},\"legendOpen\":false}},\"gridData\":{\"x\":9,\"y\":0,\"w\":15,\"h\":16,\"i\":\"4\"},\"id\":\"e5921010-ffd2-11e8-bf48-2542df260526\",\"panelIndex\":\"4\",\"type\":\"visualization\",\"version\":\"6.5.3\"},{\"embeddableConfig\":{},\"gridData\":{\"x\":0,\"y\":0,\"w\":9,\"h\":5,\"i\":\"5\"},\"id\":\"5bd393a0-01e2-11e9-bf48-2542df260526\",\"panelIndex\":\"5\",\"type\":\"visualization\",\"version\":\"6.5.3\"},{\"embeddableConfig\":{\"vis\":{\"legendOpen\":false}},\"gridData\":{\"x\":0,\"y\":31,\"w\":24,\"h\":35,\"i\":\"6\"},\"id\":\"5a086d90-0203-11e9-bf48-2542df260526\",\"panelIndex\":\"6\",\"type\":\"visualization\",\"version\":\"6.5.3\"},{\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"1\":\"rgb(247,251,255)\"},\"legendOpen\":false}},\"gridData\":{\"x\":24,\"y\":49,\"w\":24,\"h\":17,\"i\":\"7\"},\"id\":\"d85758f0-043d-11e9-bf48-2542df260526\",\"panelIndex\":\"7\",\"type\":\"visualization\",\"version\":\"6.5.3\"},{\"gridData\":{\"x\":24,\"y\":31,\"w\":24,\"h\":18,\"i\":\"8\"},\"version\":\"6.5.3\",\"panelIndex\":\"8\",\"type\":\"visualization\",\"id\":\"79780720-0925-11e9-bf48-2542df260526\",\"embeddableConfig\":{}}]", 10 | "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}", 11 | "version": 1, 12 | "timeRestore": false, 13 | "kibanaSavedObjectMeta": { 14 | "searchSourceJSON": "{\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[]}" 15 | } 16 | } 17 | }, 18 | { 19 | "_id": "7c1fbc10-fef4-11e8-bf48-2542df260526", 20 | "_type": "visualization", 21 | "_source": { 22 | "title": "DMARC - dispositions", 23 | "visState": "{\"title\":\"DMARC - dispositions\",\"type\":\"histogram\",\"params\":{\"type\":\"histogram\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"},\"valueAxis\":\"ValueAxis-1\"},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":false,\"truncate\":100,\"rotate\":75},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"emails\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"histogram\",\"mode\":\"stacked\",\"data\":{\"label\":\"emails\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"showCircles\":true}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"dmarc.record.row.count\",\"customLabel\":\"emails\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"dmarc.report_metadata.org_name.keyword\",\"size\":100,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"org_name\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"split\",\"params\":{\"field\":\"dmarc.policy_published.domain.keyword\",\"size\":30,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"domain\",\"row\":true}},{\"id\":\"4\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"dmarc.record.row.policy_evaluated.disposition.keyword\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"disposition\"}}]}", 24 | "uiStateJSON": "{\"vis\":{\"colors\":{\"quarantine\":\"#EF843C\"}}}", 25 | "description": "", 26 | "version": 1, 27 | "kibanaSavedObjectMeta": { 28 | "searchSourceJSON": "{\"index\":\"d7322400-fec5-11e8-bf48-2542df260526\",\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}" 29 | } 30 | } 31 | }, 32 | { 33 | "_id": "8af28de0-fef3-11e8-bf48-2542df260526", 34 | "_type": "visualization", 35 | "_source": { 36 | "title": "DMARC - worldmap", 37 | "visState": "{\"title\":\"DMARC - worldmap\",\"type\":\"tile_map\",\"params\":{\"colorSchema\":\"Blues\",\"mapType\":\"Shaded Circle Markers\",\"isDesaturated\":true,\"addTooltip\":true,\"heatClusterSize\":1.3,\"legendPosition\":\"bottomright\",\"mapZoom\":2,\"mapCenter\":[0,0],\"wms\":{\"enabled\":false,\"options\":{\"format\":\"image/png\",\"transparent\":true},\"selectedTmsLayer\":{\"id\":\"road_map\",\"url\":\"https://tiles.maps.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=6.5.3&license=37b61e50-b8d8-40f1-8797-d33a9cb5fefd\",\"minZoom\":0,\"maxZoom\":18,\"attribution\":\"

© OpenStreetMap contributors | Elastic Maps Service

\",\"subdomains\":[]}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"dmarc.record.row.count\",\"customLabel\":\"emails\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"geohash_grid\",\"schema\":\"segment\",\"params\":{\"field\":\"geoip.location\",\"autoPrecision\":true,\"isFilteredByCollar\":true,\"useGeocentroid\":true,\"mapZoom\":2,\"mapCenter\":{\"lon\":0,\"lat\":-0.17578097424708533},\"precision\":2}}]}", 38 | "uiStateJSON": "{}", 39 | "description": "", 40 | "version": 1, 41 | "kibanaSavedObjectMeta": { 42 | "searchSourceJSON": "{\"index\":\"d7322400-fec5-11e8-bf48-2542df260526\",\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[]}" 43 | } 44 | } 45 | }, 46 | { 47 | "_id": "5a086d90-0203-11e9-bf48-2542df260526", 48 | "_type": "visualization", 49 | "_source": { 50 | "title": "DMARC - SPF domain for DKIM fails", 51 | "visState": "{\"title\":\"DMARC - SPF domain for DKIM fails\",\"type\":\"horizontal_bar\",\"params\":{\"type\":\"histogram\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":200},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":75,\"filter\":true,\"truncate\":100},\"title\":{\"text\":\"emails\"}}],\"seriesParams\":[{\"show\":true,\"type\":\"histogram\",\"mode\":\"normal\",\"data\":{\"label\":\"emails\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"showCircles\":true}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"dmarc.record.row.count\",\"customLabel\":\"emails\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"dmarc.record.auth_results.spf.domain.keyword\",\"size\":100,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":true,\"otherBucketLabel\":\"Other\",\"missingBucket\":true,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"spf domain\"}}]}", 52 | "uiStateJSON": "{}", 53 | "description": "", 54 | "version": 1, 55 | "kibanaSavedObjectMeta": { 56 | "searchSourceJSON": "{\"index\":\"d7322400-fec5-11e8-bf48-2542df260526\",\"query\":{\"query\":\"dmarc.record.row.policy_evaluated.dkim.keyword:\\\"fail\\\"\",\"language\":\"lucene\"},\"filter\":[]}" 57 | } 58 | } 59 | }, 60 | { 61 | "_id": "e5921010-ffd2-11e8-bf48-2542df260526", 62 | "_type": "visualization", 63 | "_source": { 64 | "title": "DMARC - DKIM repartition", 65 | "visState": "{\"title\":\"DMARC - DKIM repartition\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":false,\"labels\":{\"show\":true,\"values\":true,\"last_level\":true,\"truncate\":100}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"dmarc.record.row.count\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"dmarc.policy_published.domain.keyword\",\"size\":20,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":true,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"domain\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"dmarc.record.row.policy_evaluated.dkim.keyword\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":true,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"dkim\"}}]}", 66 | "uiStateJSON": "{\"vis\":{\"colors\":{\"fail\":\"#E24D42\",\"pass\":\"#629E51\"}}}", 67 | "description": "", 68 | "version": 1, 69 | "kibanaSavedObjectMeta": { 70 | "searchSourceJSON": "{\"index\":\"d7322400-fec5-11e8-bf48-2542df260526\",\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}" 71 | } 72 | } 73 | }, 74 | { 75 | "_id": "5bd393a0-01e2-11e9-bf48-2542df260526", 76 | "_type": "visualization", 77 | "_source": { 78 | "title": "DMARC - domain selector", 79 | "visState": "{\"title\":\"DMARC - domain selector\",\"type\":\"input_control_vis\",\"params\":{\"controls\":[{\"id\":\"1545040686173\",\"indexPattern\":\"d7322400-fec5-11e8-bf48-2542df260526\",\"fieldName\":\"dmarc.policy_published.domain.keyword\",\"parent\":\"\",\"label\":\"domain\",\"type\":\"list\",\"options\":{\"type\":\"terms\",\"multiselect\":true,\"dynamicOptions\":true,\"size\":5,\"order\":\"desc\"}}],\"updateFiltersOnChange\":true,\"useTimeFilter\":true,\"pinFilters\":true},\"aggs\":[]}", 80 | "uiStateJSON": "{}", 81 | "description": "", 82 | "version": 1, 83 | "kibanaSavedObjectMeta": { 84 | "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}" 85 | } 86 | } 87 | }, 88 | { 89 | "_id": "963bac90-ffca-11e8-bf48-2542df260526", 90 | "_type": "visualization", 91 | "_source": { 92 | "title": "DMARC - status", 93 | "visState": "{\"title\":\"DMARC - status\",\"type\":\"timelion\",\"params\":{\"expression\":\".es('dmarc.record.row.policy_evaluated.dkim:\\\"pass\\\" AND dmarc.record.row.policy_evaluated.spf:\\\"pass\\\"', index=dmarc-report-*, metric=sum:dmarc.record.row.count, kibana=true).bars().color(#78AB84).label(\\\"pass\\\"),\\n.es('dmarc.record.row.policy_evaluated.dkim:\\\"pass\\\" AND dmarc.record.row.policy_evaluated.spf:\\\"fail\\\"', index=dmarc-report-*, metric=sum:dmarc.record.row.count, kibana=true).bars().color(#689BC4).label(\\\"forwarded emails (dkim pass, spf fail)\\\"),\\n.es('dmarc.record.row.policy_evaluated.dkim:\\\"fail\\\"', index=dmarc-report-*, metric=sum:dmarc.record.row.count, kibana=true).bars().color(#CC6363).label(\\\"fail\\\")\",\"interval\":\"1d\"},\"aggs\":[]}", 94 | "uiStateJSON": "{}", 95 | "description": "", 96 | "version": 1, 97 | "kibanaSavedObjectMeta": { 98 | "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}" 99 | } 100 | } 101 | }, 102 | { 103 | "_id": "d85758f0-043d-11e9-bf48-2542df260526", 104 | "_type": "visualization", 105 | "_source": { 106 | "title": "DMARC - report sender organizations", 107 | "visState": "{\"title\":\"DMARC - report sender organizations\",\"type\":\"heatmap\",\"params\":{\"addLegend\":true,\"addTooltip\":true,\"colorSchema\":\"Blues\",\"colorsNumber\":4,\"colorsRange\":[],\"enableHover\":false,\"invertColors\":false,\"legendPosition\":\"right\",\"percentageMode\":false,\"setColorRange\":false,\"times\":[],\"type\":\"heatmap\",\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"color\":\"#555\",\"overwriteColor\":false,\"rotate\":0,\"show\":false},\"scale\":{\"defaultYExtents\":true,\"type\":\"linear\"},\"show\":false,\"type\":\"value\"}]},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"dmarc.report_metadata.report_id.keyword\",\"customLabel\":\"sent reports\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"dmarc.report_metadata.date_range.begin\",\"timeRange\":{\"from\":\"now-7d\",\"mode\":\"quick\",\"to\":\"now\"},\"useNormalizedEsInterval\":true,\"interval\":\"d\",\"time_zone\":\"Europe/Berlin\",\"drop_partials\":false,\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{},\"customLabel\":\"date\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"dmarc.report_metadata.org_name.keyword\",\"size\":20,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":true,\"otherBucketLabel\":\"Other\",\"missingBucket\":true,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"report sender organization\"}}]}", 108 | "uiStateJSON": "{\"vis\":{\"defaultColors\":{\"1 - 7\":\"rgb(247,251,255)\",\"7 - 13\":\"rgb(198,219,239)\",\"13 - 19\":\"rgb(107,174,214)\",\"19 - 24\":\"rgb(33,113,181)\"},\"legendOpen\":false}}", 109 | "description": "", 110 | "version": 1, 111 | "kibanaSavedObjectMeta": { 112 | "searchSourceJSON": "{\"index\":\"d7322400-fec5-11e8-bf48-2542df260526\",\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[]}" 113 | } 114 | } 115 | }, 116 | { 117 | "_id": "79780720-0925-11e9-bf48-2542df260526", 118 | "_type": "visualization", 119 | "_source": { 120 | "title": "DMARC - domain mismatch", 121 | "visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{\"customLabel\":\"emails\",\"field\":\"dmarc.record.row.count\"},\"schema\":\"metric\",\"type\":\"sum\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"customInterval\":\"2h\",\"drop_partials\":false,\"extended_bounds\":{},\"field\":\"@timestamp\",\"interval\":\"auto\",\"min_doc_count\":1,\"timeRange\":{\"from\":\"now-24h\",\"mode\":\"quick\",\"to\":\"now\"},\"time_zone\":\"Europe/Berlin\",\"useNormalizedEsInterval\":true},\"schema\":\"segment\",\"type\":\"date_histogram\"},{\"enabled\":true,\"id\":\"3\",\"params\":{\"customLabel\":\"mismatch\",\"field\":\"tags.keyword\",\"include\":\"dmarc_.*_mismatch\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"size\":8},\"schema\":\"group\",\"type\":\"terms\"}],\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{},\"type\":\"category\"}],\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"legendPosition\":\"right\",\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"emails\"},\"drawLinesBetweenPoints\":true,\"mode\":\"stacked\",\"show\":\"true\",\"showCircles\":true,\"type\":\"histogram\",\"valueAxis\":\"ValueAxis-1\"}],\"times\":[],\"type\":\"histogram\",\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"emails\"},\"type\":\"value\"}]},\"title\":\"DMARC - domain mismatch\",\"type\":\"histogram\"}", 122 | "uiStateJSON": "{}", 123 | "description": "", 124 | "version": 1, 125 | "kibanaSavedObjectMeta": { 126 | "searchSourceJSON": "{\"index\":\"d7322400-fec5-11e8-bf48-2542df260526\",\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[]}" 127 | } 128 | } 129 | } 130 | ] 131 | -------------------------------------------------------------------------------- /logstash/10.inputs.conf: -------------------------------------------------------------------------------- 1 | # vim: syntax=conf tabstop=4 shiftwidth=4 expandtab 2 | 3 | input { 4 | file { 5 | path => "/var/cache/dmarc-reports/**/*.xml" 6 | mode => "read" 7 | file_chunk_size => 10485760 8 | file_completed_action => "log" 9 | file_completed_log_path => "/var/cache/dmarc-reports/processed_files.log" 10 | start_position => "beginning" 11 | delimiter => "\004" 12 | stat_interval => "30" 13 | discover_interval => "1" 14 | tags => ["dmarc-report"] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /logstash/20.filters.conf: -------------------------------------------------------------------------------- 1 | # vim: syntax=conf tabstop=4 shiftwidth=4 expandtab 2 | 3 | filter { 4 | if "dmarc-report" in [tags] { 5 | xml { 6 | source => "message" 7 | target => "dmarc" 8 | force_array => false 9 | remove_field => ["message"] 10 | } 11 | ruby { code => 'case event.get("[dmarc][record]") when Array then event.tag("record_to_split") end' } 12 | if "record_to_split" in [tags] { 13 | split { 14 | field => "[dmarc][record]" 15 | remove_tag => ["record_to_split"] 16 | } 17 | } 18 | mutate { 19 | convert => { 20 | "[dmarc][policy_published][pct]" => "integer" 21 | "[dmarc][record][row][count]" => "integer" 22 | } 23 | copy => { "[dmarc][record][row][source_ip]" => "[dmarc][record][row][source_host]" } 24 | strip => ["[dmarc][report_metadata][date_range][begin]", "[dmarc][report_metadata][date_range][end]"] 25 | } 26 | date { 27 | match => ["[dmarc][report_metadata][date_range][end]", "UNIX", "ISO8601", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"] 28 | timezone => "UTC" 29 | } 30 | date { 31 | match => ["[dmarc][report_metadata][date_range][begin]", "UNIX", "ISO8601", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"] 32 | timezone => "UTC" 33 | target => "[dmarc][report_metadata][date_range][begin]" 34 | } 35 | date { 36 | match => ["[dmarc][report_metadata][date_range][end]", "UNIX", "ISO8601", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"] 37 | timezone => "UTC" 38 | target => "[dmarc][report_metadata][date_range][end]" 39 | } 40 | dns { 41 | reverse => "[dmarc][record][row][source_host]" 42 | action => "replace" 43 | hit_cache_size => 128 44 | } 45 | geoip { 46 | default_database_type => "City" 47 | source => "[dmarc][record][row][source_ip]" 48 | } 49 | geoip { 50 | default_database_type => "ASN" 51 | source => "[dmarc][record][row][source_ip]" 52 | } 53 | if [dmarc][policy_published][domain] != [dmarc][record][auth_results][dkim][domain] { 54 | mutate { 55 | add_tag => [ "dmarc_dkim_domain_mismatch" ] 56 | } 57 | } 58 | if [dmarc][policy_published][domain] != [dmarc][record][auth_results][spf][domain] { 59 | mutate { 60 | add_tag => [ "dmarc_spf_domain_mismatch" ] 61 | } 62 | } 63 | if [dmarc][policy_published][domain] != [dmarc][record][identifiers][header_from] { 64 | mutate { 65 | add_tag => [ "dmarc_header_from_domain_mismatch" ] 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /logstash/30.outputs.conf: -------------------------------------------------------------------------------- 1 | # vim: syntax=conf tabstop=4 shiftwidth=4 expandtab 2 | 3 | output { 4 | if "dmarc-report" in [tags] { 5 | elasticsearch { 6 | hosts => ["http://127.0.0.1"] 7 | index => "dmarc-report-%{+YYYY.MM.dd}" 8 | manage_template => false 9 | } 10 | } 11 | } 12 | --------------------------------------------------------------------------------