From 7e98ad19d569de881c224f45b315ce90241db752 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 8 May 2019 20:03:27 +0900 Subject: [PATCH 01/21] new: [platform] Added cheap check to see if we run under a RedHat flavoured OS. --- start_all.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/start_all.sh b/start_all.sh index ef00155..0214a1a 100755 --- a/start_all.sh +++ b/start_all.sh @@ -20,7 +20,23 @@ else exit 1 fi -[ ! -f "`which redis-server`" ] && echo "'redis-server' is not installed/not on PATH. Please fix and run again." && exit 1 +if [[ -f "/etc/redhat-release" ]]; then + echo "You are running a RedHat flavour. Detecting scl potential..." + SCL=$(which scl > /dev/null 2>&1) + if [[ ! -z $SCL ]]; then + echo "scl detected, checking for redis-server" + SCL_REDIS=$(scl -l|grep rh-redis) + if [[ ! -z $SCL_REDIS ]]; then + echo "We detected: ${SCL_REDIS} acting accordingly" + REDIS_RUN="/usr/bin/scl enable ${SCL_REDIS}" + fi + else + echo "redis-server seems not to be install in scl, perhaps system-wide, testing." + [ ! -f "`which redis-server`" ] && echo "'redis-server' is not installed/not on PATH. Please fix and run again." && exit 1 + fi +else + [ ! -f "`which redis-server`" ] && echo "'redis-server' is not installed/not on PATH. Please fix and run again." && exit 1 +fi netstat -an |grep LISTEN |grep 6250 |grep -v tcp6 ; check_redis_port=$? netstat -an |grep LISTEN |grep 8001 |grep -v tcp6 ; check_dashboard_port=$? @@ -38,7 +54,7 @@ conf_dir="config/" sleep 0.1 if [ "${check_redis_port}" == "1" ]; then echo -e $GREEN"\t* Launching Redis servers"$DEFAULT - redis-server ${conf_dir}6250.conf & + $REDIS_RUN redis-server ${conf_dir}6250.conf & else echo -e $RED"\t* NOT starting Redis server, made a very unrealiable check on port 6250, and something seems to be there… please double check if this is good!"$DEFAULT fi From c809e285d6387bf46eccd9f83857e59e60a66b0b Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 8 May 2019 20:07:47 +0900 Subject: [PATCH 02/21] fix: [scl] Fix for scl based OSs. --- start_all.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/start_all.sh b/start_all.sh index 0214a1a..1b02595 100755 --- a/start_all.sh +++ b/start_all.sh @@ -53,8 +53,12 @@ conf_dir="config/" sleep 0.1 if [ "${check_redis_port}" == "1" ]; then - echo -e $GREEN"\t* Launching Redis servers"$DEFAULT - $REDIS_RUN redis-server ${conf_dir}6250.conf & + echo -e $GREEN"\t* Launching Redis servers"$DEFAULT + if [[ -z $REDIS_RUN ]]; then + $REDIS_RUN "redis-server ${conf_dir}6250.conf" & + else + redis-server ${conf_dir}6250.conf & + fi else echo -e $RED"\t* NOT starting Redis server, made a very unrealiable check on port 6250, and something seems to be there… please double check if this is good!"$DEFAULT fi From 041c2697a062e7aed5ce76f4743d99584d8b9509 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 8 May 2019 20:11:31 +0900 Subject: [PATCH 03/21] fix: [scl] Somewhy which scl does not work for user apache... --- start_all.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/start_all.sh b/start_all.sh index 1b02595..48b9535 100755 --- a/start_all.sh +++ b/start_all.sh @@ -22,8 +22,7 @@ fi if [[ -f "/etc/redhat-release" ]]; then echo "You are running a RedHat flavour. Detecting scl potential..." - SCL=$(which scl > /dev/null 2>&1) - if [[ ! -z $SCL ]]; then + if [[ -f "/usr/bin/scl" ]]; then echo "scl detected, checking for redis-server" SCL_REDIS=$(scl -l|grep rh-redis) if [[ ! -z $SCL_REDIS ]]; then From 33af08b9ee36473351867262b162434d4e39e66a Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Thu, 9 May 2019 08:08:54 +0900 Subject: [PATCH 04/21] fix: [start_all] Minor mistake/typo. --- start_all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start_all.sh b/start_all.sh index 48b9535..08b1800 100755 --- a/start_all.sh +++ b/start_all.sh @@ -53,7 +53,7 @@ conf_dir="config/" sleep 0.1 if [ "${check_redis_port}" == "1" ]; then echo -e $GREEN"\t* Launching Redis servers"$DEFAULT - if [[ -z $REDIS_RUN ]]; then + if [[ ! -z $REDIS_RUN ]]; then $REDIS_RUN "redis-server ${conf_dir}6250.conf" & else redis-server ${conf_dir}6250.conf & From c18626ea93baa590769f856421e6fa9bfb5771cd Mon Sep 17 00:00:00 2001 From: Koen Van Impe Date: Mon, 20 May 2019 14:31:53 +0200 Subject: [PATCH 05/21] No module zmq error documentation --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 34bde55..21c623b 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,25 @@ The misp-dashboard being stateless in regards to MISP, it can only process data The most revelant example could be the user login punchcard. If your MISP doesn't have the option ``Plugin.ZeroMQ_audit_notifications_enable`` set to ``true``, the punchcard will be empty. +## Dashboard not showing results - No module named zmq +When the misp-dashboard does not show results then first check if the zmq module within MISP is properly installed. + +In **Administration**, **Plugin Settings**, **ZeroMQ** check that **Plugin.ZeroMQ_enable** is set to **True**. + +Publish a test event from MISP to ZMQ via **Event Actions**, **Publish event to ZMQ**. + +Verify the logfiles +``` +${PATH_TO_MISP}/app/tmp/log/mispzmq.error.log +${PATH_TO_MISP}/app/tmp/log/mispzmq.log +``` + +If there's an error **ModuleNotFoundError: No module named 'zmq'** then install pyzmq. + +``` +$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install pyzmq +``` + # zmq_subscriber options ```usage: zmq_subscriber.py [-h] [-n ZMQNAME] [-u ZMQURL] From 9d4cdd7e16830e34b274387db8b53f7f05c78b8d Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 08:30:57 +0900 Subject: [PATCH 06/21] chg: [sort] isort on source files fix: [typo] fix retreive to retrieve --- clean.py | 8 +++---- give_honors_to_org.py | 10 +++++--- helpers/users_helper.py | 6 ++--- retreive_map_pic.py => retrieve_map_pic.py | 12 ++++++---- server.py | 24 +++++++++---------- static/js/trendings.js | 2 +- util.py | 3 ++- zmq_dispatcher.py | 27 +++++++++++----------- zmq_subscriber.py | 14 ++++++----- 9 files changed, 57 insertions(+), 49 deletions(-) rename retreive_map_pic.py => retrieve_map_pic.py (98%) diff --git a/clean.py b/clean.py index 061321d..0db079c 100755 --- a/clean.py +++ b/clean.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -from pprint import pprint -import os -import redis -import configparser import argparse +import configparser +import os +from pprint import pprint +import redis RED="\033[91m" GREEN="\033[92m" diff --git a/give_honors_to_org.py b/give_honors_to_org.py index f154f73..9279e64 100755 --- a/give_honors_to_org.py +++ b/give_honors_to_org.py @@ -1,9 +1,13 @@ #!/usr/bin/env python3.5 -import os, sys, json -import datetime, time -import redis import configparser +import datetime +import json +import os +import sys +import time + +import redis import util from helpers import contributor_helper diff --git a/helpers/users_helper.py b/helpers/users_helper.py index 5fe8b90..440ad39 100644 --- a/helpers/users_helper.py +++ b/helpers/users_helper.py @@ -63,11 +63,11 @@ class Users_helper: else: break # timestamps should be sorted, no need to process anymore return to_return - + # return: All dates for all orgs, if date is not supplied, return for all dates def getUserLogins(self, date=None): - # get all orgs and retreive their timestamps + # get all orgs and retrieve their timestamps dates = [] for org in self.getAllOrg(): keyname = "{}:{}".format(self.keyOrgLog, org) @@ -169,7 +169,7 @@ class Users_helper: data = [data[6]]+data[:6] return data - # return: a dico of the form {login: [[timestamp, count], ...], contrib: [[timestamp, 1/0], ...]} + # return: a dico of the form {login: [[timestamp, count], ...], contrib: [[timestamp, 1/0], ...]} # either for all orgs or the supplied one def getUserLoginsAndContribOvertime(self, date, org=None, prev_days=6): dico_hours_contrib = {} diff --git a/retreive_map_pic.py b/retrieve_map_pic.py similarity index 98% rename from retreive_map_pic.py rename to retrieve_map_pic.py index 55929a1..e8dd22e 100755 --- a/retreive_map_pic.py +++ b/retrieve_map_pic.py @@ -1,13 +1,15 @@ #!/usr/bin/env python3.5 -import redis -import requests -import shutil import json import math -import sys, os +import os +import shlex +import shutil +import sys import time from subprocess import PIPE, Popen -import shlex + +import redis +import requests URL_OPEN_MAP = "http://tile.openstreetmap.org/{zoom}/{x}/{y}.png" MAP_DIR = "static/maps/" diff --git a/server.py b/server.py index 8a1943f..f8ace13 100755 --- a/server.py +++ b/server.py @@ -1,21 +1,21 @@ #!/usr/bin/env python3 -from flask import Flask, render_template, request, Response, jsonify, stream_with_context -import json -import redis -import random, math import configparser +import datetime +import json +import logging +import math +import os +import random from time import gmtime as now from time import sleep, strftime -import datetime -import os -import logging + +import redis import util -from helpers import geo_helper -from helpers import contributor_helper -from helpers import users_helper -from helpers import trendings_helper -from helpers import live_helper +from flask import (Flask, Response, jsonify, render_template, request, + stream_with_context) +from helpers import (contributor_helper, geo_helper, live_helper, + trendings_helper, users_helper) configfile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config/config.cfg') cfg = configparser.ConfigParser() diff --git a/static/js/trendings.js b/static/js/trendings.js index d87aeae..b2ea959 100644 --- a/static/js/trendings.js +++ b/static/js/trendings.js @@ -145,7 +145,7 @@ function getTextColour(rgb) { } } -// If json (from tag), only retreive the name> otherwise return the supplied arg. +// If json (from tag), only retrieve the name> otherwise return the supplied arg. function getOnlyName(potentialJson) { try { jsonLabel = JSON.parse(potentialJson); diff --git a/util.py b/util.py index 6f6d0db..e61984c 100644 --- a/util.py +++ b/util.py @@ -1,5 +1,6 @@ +import datetime +import time from collections import defaultdict -import datetime, time ONE_DAY = 60*60*24 diff --git a/zmq_dispatcher.py b/zmq_dispatcher.py index 37a3874..3f94b81 100755 --- a/zmq_dispatcher.py +++ b/zmq_dispatcher.py @@ -1,23 +1,22 @@ #!/usr/bin/env python3 -import time, datetime -import copy -import logging -import zmq -import redis -import random -import configparser import argparse -import os -import sys +import configparser +import copy +import datetime import json +import logging +import os +import random +import sys +import time + +import redis +import zmq import util -from helpers import geo_helper -from helpers import contributor_helper -from helpers import users_helper -from helpers import trendings_helper -from helpers import live_helper +from helpers import (contributor_helper, geo_helper, live_helper, + trendings_helper, users_helper) configfile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config/config.cfg') cfg = configparser.ConfigParser() diff --git a/zmq_subscriber.py b/zmq_subscriber.py index b642333..97b2a71 100755 --- a/zmq_subscriber.py +++ b/zmq_subscriber.py @@ -1,14 +1,16 @@ #!/usr/bin/env python3 -import time, datetime -import zmq -import logging -import redis -import configparser import argparse +import configparser +import datetime +import json +import logging import os import sys -import json +import time + +import redis +import zmq configfile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config/config.cfg') cfg = configparser.ConfigParser() From e74b4a5bff91875879f743844d414a8b75b92dfc Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 08:42:39 +0900 Subject: [PATCH 07/21] fix: [isort] isort source files: https://github.com/timothycrosley/isort/wiki/isort-Plugins --- helpers/contributor_helper.py | 16 +++++++++------- helpers/geo_helper.py | 19 +++++++++++-------- helpers/live_helper.py | 7 ++++--- helpers/trendings_helper.py | 11 +++++++---- helpers/users_helper.py | 9 ++++++--- tests/test_geo.py | 10 +++++++--- tests/test_trendings.py | 11 ++++++++--- tests/test_users.py | 11 ++++++++--- 8 files changed, 60 insertions(+), 34 deletions(-) diff --git a/helpers/contributor_helper.py b/helpers/contributor_helper.py index 671eed3..5dd6abc 100644 --- a/helpers/contributor_helper.py +++ b/helpers/contributor_helper.py @@ -1,16 +1,19 @@ -import util -from util import getZrange -import math, random -import time -import os import configparser -import json import datetime +import json import logging +import math +import os +import random +import time + import redis import util +from util import getZrange + from . import users_helper + KEYDAY = "CONTRIB_DAY" # To be used by other module KEYALLORG = "CONTRIB_ALL_ORG" # To be used by other module @@ -589,4 +592,3 @@ class Contributor_helper: return { 'remainingPts': i-points, 'stepPts': prev } prev = i return { 'remainingPts': 0, 'stepPts': self.rankMultiplier**self.levelMax } - diff --git a/helpers/geo_helper.py b/helpers/geo_helper.py index d45e6f3..57a0065 100644 --- a/helpers/geo_helper.py +++ b/helpers/geo_helper.py @@ -1,18 +1,21 @@ -import math, random -import os +import datetime import json -import datetime, time import logging -import json -import redis +import math +import os +import random +import time from collections import OrderedDict -import geoip2.database -import phonenumbers, pycountry -from phonenumbers import geocoder +import redis +import geoip2.database +import phonenumbers +import pycountry import util from helpers import live_helper +from phonenumbers import geocoder + class InvalidCoordinate(Exception): pass diff --git a/helpers/live_helper.py b/helpers/live_helper.py index 985bca8..31af76b 100644 --- a/helpers/live_helper.py +++ b/helpers/live_helper.py @@ -1,8 +1,9 @@ -import os +import datetime import json -import random -import datetime, time import logging +import os +import random +import time class Live_helper: diff --git a/helpers/trendings_helper.py b/helpers/trendings_helper.py index 61e1479..e19292c 100644 --- a/helpers/trendings_helper.py +++ b/helpers/trendings_helper.py @@ -1,13 +1,16 @@ -import math, random -import os -import json import copy -import datetime, time +import datetime +import json import logging +import math +import os +import random +import time from collections import OrderedDict import util + class Trendings_helper: def __init__(self, serv_redis_db, cfg): self.serv_redis_db = serv_redis_db diff --git a/helpers/users_helper.py b/helpers/users_helper.py index 440ad39..f38b1f9 100644 --- a/helpers/users_helper.py +++ b/helpers/users_helper.py @@ -1,10 +1,13 @@ -import math, random -import os +import datetime import json -import datetime, time import logging +import math +import os +import random +import time import util + from . import contributor_helper diff --git a/tests/test_geo.py b/tests/test_geo.py index 94b9801..4c75b3d 100755 --- a/tests/test_geo.py +++ b/tests/test_geo.py @@ -1,8 +1,13 @@ #!/usr/bin/env python3.5 import configparser -import redis -import sys,os import datetime +import os +import sys + +import redis + +from helpers import geo_helper + sys.path.append('..') configfile = 'test_config.cfg' @@ -14,7 +19,6 @@ serv_redis_db = redis.StrictRedis( port=6260, db=1) -from helpers import geo_helper geo_helper = geo_helper.Geo_helper(serv_redis_db, cfg) categ = 'Network Activity' diff --git a/tests/test_trendings.py b/tests/test_trendings.py index 4cce0e7..4716e05 100755 --- a/tests/test_trendings.py +++ b/tests/test_trendings.py @@ -1,8 +1,14 @@ #!/usr/bin/env python3.5 import configparser +import datetime +import os +import sys +import time + import redis -import sys,os -import datetime, time + +from helpers import trendings_helper + sys.path.append('..') configfile = 'test_config.cfg' @@ -14,7 +20,6 @@ serv_redis_db = redis.StrictRedis( port=6260, db=1) -from helpers import trendings_helper trendings_helper = trendings_helper.Trendings_helper(serv_redis_db, cfg) diff --git a/tests/test_users.py b/tests/test_users.py index 61e7b41..2eb6f71 100755 --- a/tests/test_users.py +++ b/tests/test_users.py @@ -1,8 +1,14 @@ #!/usr/bin/env python3.5 import configparser +import datetime +import os +import sys +import time + import redis -import sys,os -import datetime, time + +from helpers import users_helper + sys.path.append('..') configfile = 'test_config.cfg' @@ -14,7 +20,6 @@ serv_redis_db = redis.StrictRedis( port=6260, db=1) -from helpers import users_helper users_helper = users_helper.Users_helper(serv_redis_db, cfg) From 30cb762ef7384d7029f4c50a4264dc23afab58a4 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 09:09:14 +0900 Subject: [PATCH 08/21] fix: [error] If the port is used, be graceful. --- server.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/server.py b/server.py index f8ace13..e7da6a6 100755 --- a/server.py +++ b/server.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import configparser import datetime +import errno import json import logging import math @@ -590,4 +591,12 @@ def getGenericTrendingOvertime(): return jsonify(data) if __name__ == '__main__': - app.run(host=server_host, port=server_port, threaded=True) + try: + app.run(host=server_host, + port=server_port, + threaded=True) + except OSError as error: + if error.errno == 98: + print("\n\n\nAddress already in use, the defined port is: " + str(server_port)) + else: + print(str(error)) From fc1c83242065176105c7f03b1bf9ae89c4df636e Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 09:48:26 +0900 Subject: [PATCH 09/21] fix: [errorHandling] more try catch error --- zmq_dispatcher.py | 12 ++++++++++-- zmq_subscriber.py | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/zmq_dispatcher.py b/zmq_dispatcher.py index 3f94b81..d5892f3 100755 --- a/zmq_dispatcher.py +++ b/zmq_dispatcher.py @@ -27,7 +27,12 @@ logfilename = cfg.get('Log', 'filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) -logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) +try: + logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) +except PermissionError as error: + print(error) + print("Please fix the above and try again.") + sys.exit(126) logger = logging.getLogger('zmq_dispatcher') LISTNAME = cfg.get('RedisLIST', 'listName') @@ -289,4 +294,7 @@ if __name__ == "__main__": parser.add_argument('-s', '--sleep', required=False, dest='sleeptime', type=int, help='The number of second to wait before checking redis list size', default=5) args = parser.parse_args() - main(args.sleeptime) + try: + main(args.sleeptime) + except redis.exceptions.ResponseError as error: + print(error) diff --git a/zmq_subscriber.py b/zmq_subscriber.py index 97b2a71..f793040 100755 --- a/zmq_subscriber.py +++ b/zmq_subscriber.py @@ -20,7 +20,12 @@ logfilename = cfg.get('Log', 'filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) -logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) +try: + logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) +except PermissionError as error: + print(error) + print("Please fix the above and try again.") + sys.exit(126) logger = logging.getLogger('zmq_subscriber') ZMQ_URL = cfg.get('RedisGlobal', 'zmq_url') @@ -64,4 +69,7 @@ if __name__ == "__main__": parser.add_argument('-u', '--url', required=False, dest='zmqurl', help='The URL to connect to', default=ZMQ_URL) args = parser.parse_args() - main(args.zmqname) + try: + main(args.zmqname) + except redis.exceptions.ResponseError as error: + print(error) From 6b291a55263a46ba599eddb48b36a480bd4aa34e Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 09:58:09 +0900 Subject: [PATCH 10/21] fix: [geoadd] Catch the following issue: https://github.com/MISP/misp-dashboard/issues/70 --- helpers/geo_helper.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/helpers/geo_helper.py b/helpers/geo_helper.py index 57a0065..2f59066 100644 --- a/helpers/geo_helper.py +++ b/helpers/geo_helper.py @@ -184,7 +184,12 @@ class Geo_helper: now = datetime.datetime.now() today_str = util.getDateStrFormat(now) keyname = "{}:{}".format(keyCateg, today_str) - self.serv_redis_db.geoadd(keyname, lon, lat, content) + try: + self.serv_redis_db.geoadd(keyname, lon, lat, content) + except redis.exceptions.ResponseError as error: + print(error) + print("Please fix the above, and make sure you use a redis version that supports the GEOADD command.") + print("To test for support: echo \"help GEOADD\"| redis-cli") self.logger.debug('Added to redis: keyname={}, lon={}, lat={}, content={}'.format(keyname, lon, lat, content)) def push_to_redis_zset(self, keyCateg, toAdd, endSubkey="", count=1): now = datetime.datetime.now() From 92b91c5c05dcb373487b32e73241d1741988d60f Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 10:41:43 +0900 Subject: [PATCH 11/21] chg: [log] Added 3 seperate log files: helpers.log / zmq_subscribre.log / zmq_dispatcher.log fix: [log] Catch permission errors on log files --- config/config.cfg.default | 4 +++- helpers/contributor_helper.py | 25 +++++++++++++++---------- helpers/geo_helper.py | 9 +++++++-- helpers/live_helper.py | 11 ++++++++--- helpers/trendings_helper.py | 9 +++++++-- helpers/users_helper.py | 9 +++++++-- zmq_dispatcher.py | 4 ++-- zmq_subscriber.py | 4 ++-- 8 files changed, 51 insertions(+), 24 deletions(-) diff --git a/config/config.cfg.default b/config/config.cfg.default index 1d18adb..7597d26 100644 --- a/config/config.cfg.default +++ b/config/config.cfg.default @@ -33,7 +33,9 @@ additional_help_text = ["Sightings multiplies earned points by 2", "Editing an a [Log] directory=logs -filename=logs.log +dispatcher_filename=zmq_dispatcher.log +subscriber_filename=zmq_subscriber.log +helpers_filename=helpers.log [RedisGlobal] host=localhost diff --git a/helpers/contributor_helper.py b/helpers/contributor_helper.py index 5dd6abc..68bf16a 100644 --- a/helpers/contributor_helper.py +++ b/helpers/contributor_helper.py @@ -33,11 +33,16 @@ class Contributor_helper: #logger logDir = cfg.get('Log', 'directory') - logfilename = cfg.get('Log', 'filename') + logfilename = cfg.get('Log', 'helpers_filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) - logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + try: + logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + except PermissionError as error: + print(error) + print("Please fix the above and try again.") + sys.exit(126) self.logger = logging.getLogger(__name__) #honorBadge @@ -123,14 +128,14 @@ class Contributor_helper: if action in ['edit', None]: pass #return #not a contribution? - + now = datetime.datetime.now() nowSec = int(time.time()) pnts_to_add = self.default_pnts_per_contribution - + # Do not consider contribution as login anymore #self.users_helper.add_user_login(nowSec, org) - + # is a valid contribution if categ is not None: try: @@ -138,23 +143,23 @@ class Contributor_helper: except KeyError: pnts_to_add = self.default_pnts_per_contribution pnts_to_add *= pntMultiplier - + util.push_to_redis_zset(self.serv_redis_db, self.keyDay, org, count=pnts_to_add) #CONTRIB_CATEG retain the contribution per category, not the point earned in this categ util.push_to_redis_zset(self.serv_redis_db, self.keyCateg, org, count=1, endSubkey=':'+util.noSpaceLower(categ)) self.publish_log(zmq_name, 'CONTRIBUTION', {'org': org, 'categ': categ, 'action': action, 'epoch': nowSec }, channel=self.CHANNEL_LASTCONTRIB) else: categ = "" - + self.serv_redis_db.sadd(self.keyAllOrg, org) - + keyname = "{}:{}".format(self.keyLastContrib, util.getDateStrFormat(now)) self.serv_redis_db.zadd(keyname, nowSec, org) self.logger.debug('Added to redis: keyname={}, nowSec={}, org={}'.format(keyname, nowSec, org)) self.serv_redis_db.expire(keyname, util.ONE_DAY*7) #expire after 7 day - + awards_given = self.updateOrgContributionRank(org, pnts_to_add, action, contribType, eventTime=datetime.datetime.now(), isLabeled=isLabeled, categ=util.noSpaceLower(categ)) - + for award in awards_given: # update awards given keyname = "{}:{}".format(self.keyLastAward, util.getDateStrFormat(now)) diff --git a/helpers/geo_helper.py b/helpers/geo_helper.py index 2f59066..b2f5de3 100644 --- a/helpers/geo_helper.py +++ b/helpers/geo_helper.py @@ -32,11 +32,16 @@ class Geo_helper: #logger logDir = cfg.get('Log', 'directory') - logfilename = cfg.get('Log', 'filename') + logfilename = cfg.get('Log', 'helpers_filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) - logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + try: + logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + except PermissionError as error: + print(error) + print("Please fix the above and try again.") + sys.exit(126) self.logger = logging.getLogger(__name__) self.keyCategCoord = "GEO_COORD" diff --git a/helpers/live_helper.py b/helpers/live_helper.py index 31af76b..cda4eda 100644 --- a/helpers/live_helper.py +++ b/helpers/live_helper.py @@ -17,11 +17,16 @@ class Live_helper: # logger logDir = cfg.get('Log', 'directory') - logfilename = cfg.get('Log', 'filename') + logfilename = cfg.get('Log', 'helpers_filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) - logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + try: + logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + except PermissionError as error: + print(error) + print("Please fix the above and try again.") + sys.exit(126) self.logger = logging.getLogger(__name__) def publish_log(self, zmq_name, name, content, channel=None): @@ -44,7 +49,7 @@ class Live_helper: jentry = json.loads(entry.decode('utf8')) to_ret.append(jentry) return to_ret - + def add_to_stream_log_cache(self, cacheKey, item): rKey = self.prefix_redis_key+cacheKey diff --git a/helpers/trendings_helper.py b/helpers/trendings_helper.py index e19292c..07e91e2 100644 --- a/helpers/trendings_helper.py +++ b/helpers/trendings_helper.py @@ -26,11 +26,16 @@ class Trendings_helper: #logger logDir = cfg.get('Log', 'directory') - logfilename = cfg.get('Log', 'filename') + logfilename = cfg.get('Log', 'helpers_filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) - logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + try: + logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + except PermissionError as error: + print(error) + print("Please fix the above and try again.") + sys.exit(126) self.logger = logging.getLogger(__name__) ''' SETTER ''' diff --git a/helpers/users_helper.py b/helpers/users_helper.py index f38b1f9..18498bc 100644 --- a/helpers/users_helper.py +++ b/helpers/users_helper.py @@ -23,11 +23,16 @@ class Users_helper: #logger logDir = cfg.get('Log', 'directory') - logfilename = cfg.get('Log', 'filename') + logfilename = cfg.get('Log', 'helpers_filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) - logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + try: + logging.basicConfig(filename=logPath, filemode='a', level=logging.INFO) + except PermissionError as error: + print(error) + print("Please fix the above and try again.") + sys.exit(126) self.logger = logging.getLogger(__name__) def add_user_login(self, timestamp, org, email=''): diff --git a/zmq_dispatcher.py b/zmq_dispatcher.py index d5892f3..7c9b5d8 100755 --- a/zmq_dispatcher.py +++ b/zmq_dispatcher.py @@ -23,7 +23,7 @@ cfg = configparser.ConfigParser() cfg.read(configfile) logDir = cfg.get('Log', 'directory') -logfilename = cfg.get('Log', 'filename') +logfilename = cfg.get('Log', 'dispatcher_filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) @@ -296,5 +296,5 @@ if __name__ == "__main__": try: main(args.sleeptime) - except redis.exceptions.ResponseError as error: + except (redis.exceptions.ResponseError, KeyboardInterrupt) as error: print(error) diff --git a/zmq_subscriber.py b/zmq_subscriber.py index f793040..ad9e548 100755 --- a/zmq_subscriber.py +++ b/zmq_subscriber.py @@ -16,7 +16,7 @@ configfile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config/c cfg = configparser.ConfigParser() cfg.read(configfile) logDir = cfg.get('Log', 'directory') -logfilename = cfg.get('Log', 'filename') +logfilename = cfg.get('Log', 'subscriber_filename') logPath = os.path.join(logDir, logfilename) if not os.path.exists(logDir): os.makedirs(logDir) @@ -64,7 +64,7 @@ def main(zmqName): if __name__ == "__main__": - parser = argparse.ArgumentParser(description='A zmq subscriber. It subscribes to a ZNQ then redispatch it to the misp-dashboard') + parser = argparse.ArgumentParser(description='A zmq subscriber. It subscribes to a ZMQ then redispatch it to the misp-dashboard') parser.add_argument('-n', '--name', required=False, dest='zmqname', help='The ZMQ feed name', default="MISP Standard ZMQ") parser.add_argument('-u', '--url', required=False, dest='zmqurl', help='The URL to connect to', default=ZMQ_URL) args = parser.parse_args() From a65d2cb233488706929e6d0e37233045e7ec8765 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 10:58:09 +0900 Subject: [PATCH 12/21] chg: [log] Let the user know which "IP" was not resolved. --- helpers/geo_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers/geo_helper.py b/helpers/geo_helper.py index b2f5de3..d858111 100644 --- a/helpers/geo_helper.py +++ b/helpers/geo_helper.py @@ -133,7 +133,7 @@ class Geo_helper: self.live_helper.add_to_stream_log_cache('Map', j_to_send) self.logger.info('Published: {}'.format(json.dumps(to_send))) except ValueError: - self.logger.warning("can't resolve ip") + self.logger.warning("Can't resolve IP: " + str(supposed_ip)) except geoip2.errors.AddressNotFoundError: self.logger.warning("Address not in Database") except InvalidCoordinate: From cba4ab68f1cd6732ccff1202303f550a3a7a2ea0 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 11:18:32 +0900 Subject: [PATCH 13/21] fix: [flask] Added favicon.ico --- install_dependencies.sh | 3 ++- server.py | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/install_dependencies.sh b/install_dependencies.sh index e9beb8e..51d86b6 100755 --- a/install_dependencies.sh +++ b/install_dependencies.sh @@ -35,7 +35,8 @@ mkdir -p css fonts js popd mkdir -p temp -wget http://www.misp-project.org/assets/images/misp-small.png -O static/pics/MISP.png +wget https://www.misp-project.org/assets/images/misp-small.png -O static/pics/MISP.png +wget https://www.misp-project.org/favicon.ico -O static/favicon.ico # jquery JQVERSION="3.2.1" diff --git a/server.py b/server.py index e7da6a6..ab2a2e5 100755 --- a/server.py +++ b/server.py @@ -14,7 +14,7 @@ import redis import util from flask import (Flask, Response, jsonify, render_template, request, - stream_with_context) + send_from_directory, stream_with_context) from helpers import (contributor_helper, geo_helper, live_helper, trendings_helper, users_helper) @@ -141,6 +141,10 @@ def index(): zoomlevel=cfg.getint('Dashboard' ,'zoomlevel') ) +@app.route('/favicon.ico') +def favicon(): + return send_from_directory(os.path.join(app.root_path, 'static'), + 'favicon.ico', mimetype='image/vnd.microsoft.icon') @app.route("/geo") def geo(): From 1f48d9621cf948184b66978afbe9dcead139b40d Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Wed, 29 May 2019 13:15:49 +0900 Subject: [PATCH 14/21] chg: [perms] Check if permissions fail on the MaxMind db files chg: [installer] Check if network is present and the first wget worked chg: [installer] Exit if the virtualenv creation/update fails --- helpers/geo_helper.py | 7 ++++++- install_dependencies.sh | 21 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/helpers/geo_helper.py b/helpers/geo_helper.py index d858111..8e8af52 100644 --- a/helpers/geo_helper.py +++ b/helpers/geo_helper.py @@ -51,7 +51,12 @@ class Geo_helper: self.PATH_TO_JSON = cfg.get('RedisMap', 'path_countrycode_to_coord_JSON') self.CHANNELDISP = cfg.get('RedisMap', 'channelDisp') - self.reader = geoip2.database.Reader(self.PATH_TO_DB) + try: + self.reader = geoip2.database.Reader(self.PATH_TO_DB) + except PermissionError as error: + print(error) + print("Please fix the above and try again.") + sys.exit(126) self.country_to_iso = { country.name: country.alpha_2 for country in pycountry.countries} with open(self.PATH_TO_JSON) as f: self.country_code_to_coord = json.load(f) diff --git a/install_dependencies.sh b/install_dependencies.sh index 51d86b6..3a0747d 100755 --- a/install_dependencies.sh +++ b/install_dependencies.sh @@ -1,12 +1,21 @@ #!/bin/bash -set -e +## disable -e for production systems +#set -e + +## Debug mode #set -x sudo apt-get install python3-virtualenv virtualenv screen redis-server unzip -y if [ -z "$VIRTUAL_ENV" ]; then - virtualenv -p python3 DASHENV + virtualenv -p python3 DASHENV ; DASH_VENV=$? + + if [[ "$DASH_VENV" != "0" ]]; then + echo "Something went wrong with either the update or install of the virtualenv." + echo "Please investigate manually." + exit $DASH_VENV + fi . ./DASHENV/bin/activate fi @@ -35,7 +44,13 @@ mkdir -p css fonts js popd mkdir -p temp -wget https://www.misp-project.org/assets/images/misp-small.png -O static/pics/MISP.png +NET_WGET=$(wget --no-cache -q https://www.misp-project.org/assets/images/misp-small.png -O static/pics/MISP.png; echo $?) + +if [[ "$NET_WGET" != "0" ]]; then + echo "The first wget we tried failed, please investigate manually." + exit $NET_WGET +fi + wget https://www.misp-project.org/favicon.ico -O static/favicon.ico # jquery From 62375666645890f2f31a1d6d249893c184a5641f Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Sat, 1 Jun 2019 15:03:31 +0900 Subject: [PATCH 15/21] fix: [import] import sys was missing for proper error handling --- helpers/live_helper.py | 1 + 1 file changed, 1 insertion(+) diff --git a/helpers/live_helper.py b/helpers/live_helper.py index cda4eda..1a1a728 100644 --- a/helpers/live_helper.py +++ b/helpers/live_helper.py @@ -3,6 +3,7 @@ import json import logging import os import random +import sys import time From eda258144167df494a5796ed2a4553fd69700fd5 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Sat, 1 Jun 2019 15:08:48 +0900 Subject: [PATCH 16/21] fix: [import] Fixed missing import sys --- helpers/contributor_helper.py | 1 + helpers/geo_helper.py | 1 + helpers/trendings_helper.py | 1 + helpers/users_helper.py | 1 + 4 files changed, 4 insertions(+) diff --git a/helpers/contributor_helper.py b/helpers/contributor_helper.py index 68bf16a..bc4813b 100644 --- a/helpers/contributor_helper.py +++ b/helpers/contributor_helper.py @@ -5,6 +5,7 @@ import logging import math import os import random +import sys import time import redis diff --git a/helpers/geo_helper.py b/helpers/geo_helper.py index 8e8af52..ededda2 100644 --- a/helpers/geo_helper.py +++ b/helpers/geo_helper.py @@ -4,6 +4,7 @@ import logging import math import os import random +import sys import time from collections import OrderedDict diff --git a/helpers/trendings_helper.py b/helpers/trendings_helper.py index 07e91e2..4b55423 100644 --- a/helpers/trendings_helper.py +++ b/helpers/trendings_helper.py @@ -5,6 +5,7 @@ import logging import math import os import random +import sys import time from collections import OrderedDict diff --git a/helpers/users_helper.py b/helpers/users_helper.py index 18498bc..ba3ab22 100644 --- a/helpers/users_helper.py +++ b/helpers/users_helper.py @@ -4,6 +4,7 @@ import logging import math import os import random +import sys import time import util From 491e2aac61ad77300d0af01dbfad0ada9324d065 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Sat, 1 Jun 2019 16:24:26 +0900 Subject: [PATCH 17/21] chg: [dev] Added debug mode to config, False by default. --- config/config.cfg.default | 1 + server.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/config/config.cfg.default b/config/config.cfg.default index 7597d26..878e71e 100644 --- a/config/config.cfg.default +++ b/config/config.cfg.default @@ -1,6 +1,7 @@ [Server] host = localhost port = 8001 +debug = False [Dashboard] #hours diff --git a/server.py b/server.py index ab2a2e5..0e862ec 100755 --- a/server.py +++ b/server.py @@ -27,6 +27,7 @@ logger.setLevel(logging.ERROR) server_host = cfg.get("Server", "host") server_port = cfg.getint("Server", "port") +server_debug = cfg.get("Server", "debug") app = Flask(__name__) @@ -598,6 +599,7 @@ if __name__ == '__main__': try: app.run(host=server_host, port=server_port, + debug=server_debug, threaded=True) except OSError as error: if error.errno == 98: From bc8e74a400ce13879ba6256d3d2cc02be953a8d1 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Sun, 2 Jun 2019 10:50:03 +0900 Subject: [PATCH 18/21] fix: [js] Contributors dates will now look: 2019-04-03@11:03 - Amend if unwanted. --- server.py | 2 +- static/js/contrib.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/server.py b/server.py index ab2a2e5..91b2b1a 100755 --- a/server.py +++ b/server.py @@ -82,7 +82,7 @@ class LogItem(): def get_row(self): to_ret = {} - #Number to keep them sorted (jsonify sort keys) + # Number to keep them sorted (jsonify sort keys) for item in range(len(LogItem.FIELDNAME_ORDER)): try: to_ret[item] = self.fields[item] diff --git a/static/js/contrib.js b/static/js/contrib.js index 99f3fec..9e8fd67 100644 --- a/static/js/contrib.js +++ b/static/js/contrib.js @@ -346,7 +346,8 @@ function addLastContributor(datatable, data, update) { } else { last_added_contrib = org; var date = new Date(data.epoch*1000); - date.toString = function() {return this.toTimeString().slice(0,-15) +' '+ this.toLocaleDateString(); }; + //date.toString = function() {return this.toTimeString().slice(0,-15) +' '+ this.toLocaleDateString(); }; + date = date.getFullYear() + "-" + String(date.getMonth()).padStart(2, "0") + "-" + String(date.getDay()).padStart(2, "0") + "@" + String(date.getHours()).padStart(2, "0") + ":" + String(date.getMinutes()).padStart(2, "0"); var to_add = [ date, data.pnts, @@ -383,7 +384,8 @@ function addAwards(datatableAwards, json, playAnim) { var award = createTrophyImg(json.award[1][1], 40, categ); } var date = new Date(json.epoch*1000); - date.toString = function() {return this.toTimeString().slice(0,-15) +' '+ this.toLocaleDateString(); }; + //date.toString = function() {return this.toTimeString().slice(0,-15) +' '+ this.toLocaleDateString(); }; + date = date.getFullYear() + "-" + String(date.getMonth()).padStart(2, "0") + "-" + String(date.getDay()).padStart(2, "0") + "@" + String(date.getHours()).padStart(2, "0") + ":" + String(date.getMinutes()).padStart(2, "0"); var to_add = [ date, createImg(json.logo_path, 32), From ba45138d7aab5d04c059dbdc0f80ea8356ffdb94 Mon Sep 17 00:00:00 2001 From: Steve Clement Date: Sun, 2 Jun 2019 11:24:31 +0900 Subject: [PATCH 19/21] fix: [doc] Some typos fixed fix: [doc] License updated and note added --- LICENSE | 5 +++-- README.md | 63 ++++++++++++++++++++----------------------------------- 2 files changed, 26 insertions(+), 42 deletions(-) diff --git a/LICENSE b/LICENSE index dba13ed..dc42269 100644 --- a/LICENSE +++ b/LICENSE @@ -629,8 +629,9 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - - Copyright (C) + A dashboard for a real-time overview of threat intelligence from MISP instances + Copyright (C) 2017-2010 CIRCL - Computer Incident Response Center Luxembourg (c/o smile, security made in Lëtzebuerg, Groupement d'Intérêt Economique) + Copyright (c) 2017-2019 Sami Mokaddem This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by diff --git a/README.md b/README.md index 21c623b..3219152 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,23 @@ # misp-dashboard -A dashboard showing live data and statistics from the ZMQ feeds of one or more [MISP](https://www.misp-project.org/) instances. The dashboard -can be used as a real-time situational awareness tool to gather threat intelligence information. The misp-dashboard includes -a gamification tool to show the contributions of each organisations and how they are ranked over time. The dashboard can be used for -SOC (Security Operation Center), security team or during cyber exercise to keep track of what's going on your various MISP instances. +A dashboard showing live data and statistics from the ZMQ feeds of one or more [MISP](https://www.misp-project.org/) instances. +The dashboard can be used as a real-time situational awareness tool to gather threat intelligence information. +The misp-dashboard includes a [gamification](https://en.wikipedia.org/wiki/Gamification#Criticism) tool to show the contributions of each organisation and how they are ranked over time. +The dashboard can be used for SOCs (Security Operation Centers), security teams or during cyber exercises to keep track of what is being processed on your various MISP instances. # Features ## Live Dashboard -- Possibility to subscribe to multiple ZMQ feeds -- Shows direct contribution made by organisations -- Shows live resolvable posted locations +- Possibility to subscribe to multiple ZMQ feeds from different MISP instances +- Shows immediate contributions made by organisations +- Displays live resolvable posted geo-locations ![Dashboard live](./screenshots/dashboard-live.png) ## Geolocalisation Dashboard -- Provides historical geolocalised information to support security teams, CSIRTs or SOC finding threats in their constituency +- Provides historical geolocalised information to support security teams, CSIRTs or SOCs in finding threats within their constituency - Possibility to get geospatial information from specific regions ![Dashbaord geo](./screenshots/dashboard-geo.png) @@ -25,25 +25,25 @@ SOC (Security Operation Center), security team or during cyber exercise to keep ## Contributors Dashboard __Shows__: -- The monthly rank of all organisation +- The monthly rank of all organisations - The last organisation that contributed (dynamic updates) -- The contribution level of all organisation -- Each category of contribution per organisation +- The contribution level of all organisations +- Each category of contributions per organisation - The current ranking of the selected organisation (dynamic updates) __Includes__: -- Gamification of the platform: +- [Gamification](https://en.wikipedia.org/wiki/Gamification#Criticism) of the platform: - Two different levels of ranking with unique icons - Exclusive obtainable badges for source code contributors and donator -![Dashboard contributor](./screenshots/dashboard-contributors2.png) -![Dashboard contributor2](./screenshots/dashboard-contributors3.png) +![Dashboard contributors](./screenshots/dashboard-contributors2.png) +![Dashboard contributors2](./screenshots/dashboard-contributors3.png) ## Users Dashboard - Shows when and how the platform is used: - - Login punchcard and overtime + - Login punchcard and contributions over time - Contribution vs login ![Dashboard users](./screenshots/dashboard-users.png) @@ -57,7 +57,7 @@ __Includes__: ![Dashboard users](./screenshots/dashboard-trendings.png) # Installation -- Launch ```./install_dependencies.sh``` from the MISP-Dashboard directory +- Launch ```./install_dependencies.sh``` from the MISP-Dashboard directory ([idempotent-ish](https://en.wikipedia.org/wiki/Idempotence)) - Update the configuration file ```config.cfg``` so that it matches your system - Fields that you may change: - RedisGlobal -> host @@ -68,7 +68,7 @@ __Includes__: # Updating by pulling - Re-launch ```./install_dependencies.sh``` to fetch new required dependencies -- Re-update your configuration file ```config.cfg``` +- Re-update your configuration file ```config.cfg``` by comparing eventual changes in ```config.cfg.default``` :warning: Make sure no zmq python3 scripts are running. They block the update. @@ -92,7 +92,7 @@ OSError: [Errno 26] Text file busy: '/home/steve/code/misp-dashboard/DASHENV/bin ``` # Starting the System -:warning: You do not need to run it as root. Normal privileges are fine. +:warning: You should not run it as root. Normal privileges are fine. - Be sure to have a running redis server - e.g. ```redis-server --port 6250``` @@ -102,7 +102,7 @@ OSError: [Errno 26] Text file busy: '/home/steve/code/misp-dashboard/DASHENV/bin - Start the Flask server ```./server.py &``` - Access the interface at ```http://localhost:8001/``` -Alternatively, you can run the ```start_all.sh``` script to run the commands described above. +__Alternatively__, you can run the ```start_all.sh``` script to run the commands described above. # Debug @@ -117,7 +117,7 @@ export FLASK_APP=server.py flask run --host=0.0.0.0 --port=8001 # <- Be careful here, this exposes it on ALL ip addresses. Ideally if run locally --host=127.0.0.1 ``` -OR, just toggle the debug flag in start_all.sh script. +OR, just toggle the debug flag in start_all.sh or config.cfg. Happy hacking ;) @@ -174,7 +174,7 @@ optional arguments: # Deploy in production using mod_wsgi -Install Apache's mod-wsgi for Python3 +Install Apache mod-wsgi for Python3 ```bash sudo apt-get install libapache2-mod-wsgi-py3 @@ -189,7 +189,7 @@ The following NEW packages will be installed: libapache2-mod-wsgi-py3 ``` -Configuration file `/etc/apache2/sites-available/misp-dashboard.conf` assumes that `misp-dashboard` is cloned into `var/www/misp-dashboard`. It runs as user `misp` in this example. Change the permissions to folder and files accordingly. +Configuration file `/etc/apache2/sites-available/misp-dashboard.conf` assumes that `misp-dashboard` is cloned into `/var/www/misp-dashboard`. It runs as user `misp` in this example. Change the permissions to your custom folder and files accordingly. ``` @@ -249,21 +249,4 @@ Note that: - Part of ```MISPHonorableIcons/4.svg``` comes from [Zeptozephyr](https://zeptozephyr.deviantart.com/art/Vectored-Portal-Icons-207347804) & [octicons.github.com](https://octicons.github.com/icon/git-pull-request/) (CC0 - No Rights Reserved) - Part of ```MISPHonorableIcons/5.svg``` comes from [Zeptozephyr](https://zeptozephyr.deviantart.com/art/Vectored-Portal-Icons-207347804) & [octicons.github.com](https://octicons.github.com/icon/git-pull-request/) (CC0 - No Rights Reserved) -``` -Copyright (C) 2017-2018 CIRCL - Computer Incident Response Center Luxembourg (c/o smile, security made in Lëtzebuerg, Groupement d'Intérêt Economique) -Copyright (c) 2017-2018 Sami Mokaddem - - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -``` +Please see [LICENSE](https://github.com/MISP/misp-dashboard/blob/master/LICENSE) for a visual overview on how you may use this software. From d132d30fe4d598d8525d5da5ede59eeb798505fc Mon Sep 17 00:00:00 2001 From: Alexandre Dulaunoy Date: Sun, 2 Jun 2019 07:33:27 +0200 Subject: [PATCH 20/21] chg: [doc] default LICENSE template is not there to be changed --- LICENSE | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/LICENSE b/LICENSE index dc42269..dba13ed 100644 --- a/LICENSE +++ b/LICENSE @@ -629,9 +629,8 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - A dashboard for a real-time overview of threat intelligence from MISP instances - Copyright (C) 2017-2010 CIRCL - Computer Incident Response Center Luxembourg (c/o smile, security made in Lëtzebuerg, Groupement d'Intérêt Economique) - Copyright (c) 2017-2019 Sami Mokaddem + + Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by From 16682247d9dc4598ac4402cb8e8fc007c0a0890f Mon Sep 17 00:00:00 2001 From: Alexandre Dulaunoy Date: Sun, 2 Jun 2019 07:37:12 +0200 Subject: [PATCH 21/21] chg: [doc] license has been rectified to the standard format --- README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3219152..0e8b9e9 100644 --- a/README.md +++ b/README.md @@ -237,16 +237,35 @@ Configuration file `/etc/apache2/sites-available/misp-dashboard.conf` assumes th # License +~~~~ + Copyright (C) 2017-2019 CIRCL - Computer Incident Response Center Luxembourg (c/o smile, security made in Lëtzebuerg, Groupement d'Intérêt Economique) + Copyright (c) 2017-2019 Sami Mokaddem + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +~~~~ + Images and logos are handmade for: + - rankingMISPOrg/ - rankingMISPMonthly/ - MISPHonorableIcons/ Note that: + - Part of ```MISPHonorableIcons/1.svg``` comes from [octicons.github.com](https://octicons.github.com/icon/git-pull-request/) (CC0 - No Rights Reserved) - Part of ```MISPHonorableIcons/2.svg``` comes from [Zeptozephyr](https://zeptozephyr.deviantart.com/art/Vectored-Portal-Icons-207347804) (CC0 - No Rights Reserved) - Part of ```MISPHonorableIcons/3.svg``` comes from [octicons.github.com](https://octicons.github.com/icon/git-pull-request/) (CC0 - No Rights Reserved) - Part of ```MISPHonorableIcons/4.svg``` comes from [Zeptozephyr](https://zeptozephyr.deviantart.com/art/Vectored-Portal-Icons-207347804) & [octicons.github.com](https://octicons.github.com/icon/git-pull-request/) (CC0 - No Rights Reserved) - Part of ```MISPHonorableIcons/5.svg``` comes from [Zeptozephyr](https://zeptozephyr.deviantart.com/art/Vectored-Portal-Icons-207347804) & [octicons.github.com](https://octicons.github.com/icon/git-pull-request/) (CC0 - No Rights Reserved) -Please see [LICENSE](https://github.com/MISP/misp-dashboard/blob/master/LICENSE) for a visual overview on how you may use this software.