mirror of https://github.com/MISP/misp-dashboard
Moved more to config + Added orange led
parent
366f1d826e
commit
e3cefa45da
|
@ -6,6 +6,8 @@ rotation_wait_time = 30
|
||||||
max_img_rotation = 10
|
max_img_rotation = 10
|
||||||
hours_spanned = 48
|
hours_spanned = 48
|
||||||
zoomlevel = 15
|
zoomlevel = 15
|
||||||
|
size_openStreet_pannel_perc = 55
|
||||||
|
size_world_pannel_perc = 35
|
||||||
|
|
||||||
[Log]
|
[Log]
|
||||||
fieldname_order=["id", "category", "type", "value"]
|
fieldname_order=["id", "category", "type", "value"]
|
||||||
|
@ -15,7 +17,7 @@ host=localhost
|
||||||
port=6250
|
port=6250
|
||||||
db=0
|
db=0
|
||||||
channel=1
|
channel=1
|
||||||
zmq_url="tcp://crf.circl.lu:5556"
|
zmq_url=tcp://localhost:9990
|
||||||
|
|
||||||
[RedisMap]
|
[RedisMap]
|
||||||
host=localhost
|
host=localhost
|
||||||
|
|
|
@ -82,7 +82,16 @@ class EventMessage():
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
|
ratioCorrection = 88
|
||||||
|
pannelSize = [
|
||||||
|
"{:.0f}".format(cfg.getint('Dashboard' ,'size_openStreet_pannel_perc')/100*ratioCorrection),
|
||||||
|
"{:.0f}".format((100-cfg.getint('Dashboard' ,'size_openStreet_pannel_perc'))/100*ratioCorrection),
|
||||||
|
"{:.0f}".format(cfg.getint('Dashboard' ,'size_world_pannel_perc')/100*ratioCorrection),
|
||||||
|
"{:.0f}".format((100-cfg.getint('Dashboard' ,'size_world_pannel_perc'))/100*ratioCorrection)
|
||||||
|
]
|
||||||
|
print(pannelSize)
|
||||||
return render_template('index.html',
|
return render_template('index.html',
|
||||||
|
pannelSize=pannelSize,
|
||||||
graph_log_refresh_rate=cfg.getint('Dashboard' ,'graph_log_refresh_rate'),
|
graph_log_refresh_rate=cfg.getint('Dashboard' ,'graph_log_refresh_rate'),
|
||||||
rotation_wait_time=cfg.getint('Dashboard' ,'rotation_wait_time'),
|
rotation_wait_time=cfg.getint('Dashboard' ,'rotation_wait_time'),
|
||||||
max_img_rotation=cfg.getint('Dashboard' ,'max_img_rotation'),
|
max_img_rotation=cfg.getint('Dashboard' ,'max_img_rotation'),
|
||||||
|
|
|
@ -2,6 +2,7 @@ var feedStatusFreqCheck = 1000*15;
|
||||||
var maxNumPoint = hours_spanned;
|
var maxNumPoint = hours_spanned;
|
||||||
var keepaliveTime = 0;
|
var keepaliveTime = 0;
|
||||||
var emptyArray = [];
|
var emptyArray = [];
|
||||||
|
var _timeoutLed;
|
||||||
for(i=0; i<maxNumPoint; i++) {
|
for(i=0; i<maxNumPoint; i++) {
|
||||||
emptyArray.push([i, 0]);
|
emptyArray.push([i, 0]);
|
||||||
}
|
}
|
||||||
|
@ -156,6 +157,7 @@ $(document).ready(function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
function ledColorManager() {
|
function ledColorManager() {
|
||||||
|
$("#status_led").removeClass("led_orange");
|
||||||
if(new Date().getTime() - keepaliveTime > feedStatusFreqCheck) { // no feed
|
if(new Date().getTime() - keepaliveTime > feedStatusFreqCheck) { // no feed
|
||||||
$("#status_led").removeClass("led_green");
|
$("#status_led").removeClass("led_green");
|
||||||
$("#status_led").addClass("led_red");
|
$("#status_led").addClass("led_red");
|
||||||
|
@ -163,8 +165,9 @@ function ledColorManager() {
|
||||||
$("#status_led").removeClass("led_red");
|
$("#status_led").removeClass("led_red");
|
||||||
$("#status_led").addClass("led_green");
|
$("#status_led").addClass("led_green");
|
||||||
}
|
}
|
||||||
setTimeout(function(){ ledColorManager(); }, feedStatusFreqCheck);
|
_timeoutLed = setTimeout(function(){ ledColorManager(); }, feedStatusFreqCheck);
|
||||||
}
|
}
|
||||||
|
_timeoutLed = setTimeout(function(){ ledColorManager(); }, feedStatusFreqCheck);
|
||||||
|
|
||||||
|
|
||||||
// LOG TABLE
|
// LOG TABLE
|
||||||
|
@ -198,6 +201,7 @@ function updateLogTable(feedName, log) {
|
||||||
}
|
}
|
||||||
} else if (feedName == "Keepalive") {
|
} else if (feedName == "Keepalive") {
|
||||||
keepaliveTime = new Date().getTime();
|
keepaliveTime = new Date().getTime();
|
||||||
|
clearTimeout(_timeoutLed); //cancel current led timeout
|
||||||
ledColorManager();
|
ledColorManager();
|
||||||
} else {
|
} else {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
|
|
@ -51,6 +51,17 @@ table {
|
||||||
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #304701 0 -1px 9px, #FF0303 0 2px 12px;
|
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #304701 0 -1px 9px, #FF0303 0 2px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.led_orange {
|
||||||
|
float: right;
|
||||||
|
margin: auto auto;
|
||||||
|
margin-top: 12.5px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background-color: #FFB400;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 7px 1px, inset #304701 0 -1px 9px, #FF9000 0 2px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.marker_animation {
|
.marker_animation {
|
||||||
stroke: darkred;
|
stroke: darkred;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -93,7 +104,7 @@ small {
|
||||||
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0; padding-left: 15px;">
|
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0; padding-left: 15px;">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<a class="navbar-brand" href="{{ url_for('index') }}">Misp feed dashboard</a>
|
<a class="navbar-brand" href="{{ url_for('index') }}">Misp feed dashboard</a>
|
||||||
<div id="status_led" class="led_red"></div>
|
<div id="status_led" class="led_orange"></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.navbar-header -->
|
<!-- /.navbar-header -->
|
||||||
|
|
||||||
|
@ -106,7 +117,7 @@ small {
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<div class="col-lg-5">
|
<div class="col-lg-5">
|
||||||
|
|
||||||
<div class="panel panel-default" style="margin-top: 15px; height: 68vh;">
|
<div class="panel panel-default" style="margin-top: 15px; height: {{ pannelSize[0] }}vh;">
|
||||||
<div class="panel-heading bg-info" style="font-weight: bold;">
|
<div class="panel-heading bg-info" style="font-weight: bold;">
|
||||||
<b id="textMap1"> No map </b>
|
<b id="textMap1"> No map </b>
|
||||||
<div style="float: right;">
|
<div style="float: right;">
|
||||||
|
@ -130,19 +141,19 @@ small {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panelbody" class="panel-body" style="height: 93%; padding: 5px">
|
<div id="panelbody" class="panel-body" style="height: 93%; padding: 5px">
|
||||||
<div id="feedDivMap1" style="width:100%; height: 100%;">
|
<div id="feedDivMap1" style="width:100%; height: 95%;">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.panel-body -->
|
<!-- /.panel-body -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.panel -->
|
<!-- /.panel -->
|
||||||
<div class="panel panel-default" style="margin-top: 15px; height: 20vh;">
|
<div class="panel panel-default" style="margin-top: 15px; height: {{ pannelSize[1] }}vh;">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-bar-chart-o fa-fw"></i> Log feed (hours)
|
<i class="fa fa-bar-chart-o fa-fw"></i> Log feed (hours)
|
||||||
</div>
|
</div>
|
||||||
<div id="panelbody" class="panel-body" style="width:100%; height: calc(100% - 30px);">
|
<div id="panelbody" class="panel-body" style="width:100%; height: calc(100% - 30px);">
|
||||||
<div id="feedDiv3" style="width:100%; height: calc(100% - 30px); position: relative;"></div>
|
<div id="feedDiv3" style="width:100%; height: 100%; position: relative;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -150,22 +161,18 @@ small {
|
||||||
</div>
|
</div>
|
||||||
<!-- /.col-lg-6 -->
|
<!-- /.col-lg-6 -->
|
||||||
<!-- /.col-lg-6 -->
|
<!-- /.col-lg-6 -->
|
||||||
<!-- vh sum = 87 -->
|
|
||||||
<div class="col-lg-7">
|
<div class="col-lg-7">
|
||||||
|
|
||||||
<div class="panel panel-default" style="margin-top: 15px; height: 39vh;">
|
<div class="panel panel-default" style="margin-top: 15px; height: {{ pannelSize[2] }}vh;">
|
||||||
<!--<div class="panel-heading">
|
<div id="panelbody" class="panel-body" style="height: 100%; padding: 3px;">
|
||||||
<i class="fa fa-bar-chart-o fa-fw"></i> Feed
|
<div id="feedDiv2" style="width:100%; height: 100%; position: relative;"></div>
|
||||||
</div>-->
|
|
||||||
<div id="panelbody" class="panel-body" style="height: 100%;">
|
|
||||||
<div id="feedDiv2" style="width:100%; height: calc(100% - 30px); position: relative;"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.panel-body -->
|
<!-- /.panel-body -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.panel -->
|
<!-- /.panel -->
|
||||||
|
|
||||||
<div class="panel panel-default" style="height: 49vh;">
|
<div class="panel panel-default" style="height: {{ pannelSize[3] }}vh;">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-tasks fa-fw"></i> Logs
|
<i class="fa fa-tasks fa-fw"></i> Logs
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
|
|
@ -15,35 +15,27 @@ cfg = configparser.ConfigParser()
|
||||||
cfg.read(configfile)
|
cfg.read(configfile)
|
||||||
|
|
||||||
zmq_url = cfg.get('RedisLog', 'zmq_url')
|
zmq_url = cfg.get('RedisLog', 'zmq_url')
|
||||||
zmq_url = "tcp://192.168.56.50:50000"
|
|
||||||
zmq_url = "tcp://localhost:9990"
|
|
||||||
channel = cfg.get('RedisLog', 'channel')
|
channel = cfg.get('RedisLog', 'channel')
|
||||||
context = zmq.Context()
|
context = zmq.Context()
|
||||||
socket = context.socket(zmq.SUB)
|
socket = context.socket(zmq.SUB)
|
||||||
socket.connect(zmq_url)
|
socket.connect(zmq_url)
|
||||||
socket.setsockopt_string(zmq.SUBSCRIBE, '')
|
socket.setsockopt_string(zmq.SUBSCRIBE, '')
|
||||||
|
channelDisp = cfg.get('RedisMap', 'channelDisp')
|
||||||
|
|
||||||
redis_server = redis.StrictRedis(
|
redis_server = redis.StrictRedis(
|
||||||
host=cfg.get('RedisLog', 'host'),
|
host=cfg.get('RedisLog', 'host'),
|
||||||
port=cfg.getint('RedisLog', 'port'),
|
port=cfg.getint('RedisLog', 'port'),
|
||||||
db=cfg.getint('RedisLog', 'db'))
|
db=cfg.getint('RedisLog', 'db'))
|
||||||
serv_coord = redis.StrictRedis(
|
serv_coord = redis.StrictRedis(
|
||||||
host='localhost',
|
host=cfg.get('RedisMap', 'host'),
|
||||||
port=6250,
|
port=cfg.getint('RedisMap', 'port'),
|
||||||
db=1)
|
db=cfg.getint('RedisMap', 'db'))
|
||||||
path_to_db = "/home/sami/Downloads/GeoLite2-City_20171003/GeoLite2-City.mmdb"
|
path_to_db = "/home/sami/Downloads/GeoLite2-City_20171003/GeoLite2-City.mmdb"
|
||||||
reader = geoip2.database.Reader(path_to_db)
|
reader = geoip2.database.Reader(path_to_db)
|
||||||
|
|
||||||
channel_proc = "CoordToProcess"
|
channel_proc = "CoordToProcess"
|
||||||
channel_disp = "PicToDisplay"
|
|
||||||
|
|
||||||
|
|
||||||
def publish_coord(coord):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_ip(data):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def ip_to_coord(ip):
|
def ip_to_coord(ip):
|
||||||
resp = reader.city(ip)
|
resp = reader.city(ip)
|
||||||
lat = float(resp.location.latitude)
|
lat = float(resp.location.latitude)
|
||||||
|
@ -54,18 +46,23 @@ def ip_to_coord(ip):
|
||||||
lon_corrected = float("{:.4f}".format(lon))
|
lon_corrected = float("{:.4f}".format(lon))
|
||||||
return { 'coord': {'lat': lat_corrected, 'lon': lon_corrected}, 'full_rep': resp }
|
return { 'coord': {'lat': lat_corrected, 'lon': lon_corrected}, 'full_rep': resp }
|
||||||
|
|
||||||
def default_log(jsonevent):
|
|
||||||
|
##############
|
||||||
|
## HANDLERS ##
|
||||||
|
##############
|
||||||
|
|
||||||
|
def handler_log(jsonevent):
|
||||||
print('sending', 'log')
|
print('sending', 'log')
|
||||||
return
|
return
|
||||||
#redis_server.publish(channel, json.dumps(jsonevent))
|
#redis_server.publish(channel, json.dumps(jsonevent))
|
||||||
|
|
||||||
def default_keepalive(jsonevent):
|
def handler_keepalive(jsonevent):
|
||||||
print('sending', 'keepalive')
|
print('sending', 'keepalive')
|
||||||
to_push = [ jsonevent['uptime'] ]
|
to_push = [ jsonevent['uptime'] ]
|
||||||
to_send = { 'name': 'Keepalive', 'log': json.dumps(to_push) }
|
to_send = { 'name': 'Keepalive', 'log': json.dumps(to_push) }
|
||||||
redis_server.publish(channel, json.dumps(to_send))
|
redis_server.publish(channel, json.dumps(to_send))
|
||||||
|
|
||||||
def default_event(jsonevent):
|
def handler_event(jsonevent):
|
||||||
print('sending', 'event')
|
print('sending', 'event')
|
||||||
#fields: threat_level_id, id, info
|
#fields: threat_level_id, id, info
|
||||||
jsonevent = jsonevent['Event']
|
jsonevent = jsonevent['Event']
|
||||||
|
@ -76,7 +73,7 @@ def default_event(jsonevent):
|
||||||
to_send = { 'name': 'Event', 'log': json.dumps(to_push) }
|
to_send = { 'name': 'Event', 'log': json.dumps(to_push) }
|
||||||
redis_server.publish(channel, json.dumps(to_send))
|
redis_server.publish(channel, json.dumps(to_send))
|
||||||
|
|
||||||
def default_attribute(jsonattr):
|
def handler_attribute(jsonattr):
|
||||||
print('sending', 'attribute')
|
print('sending', 'attribute')
|
||||||
jsonattr = jsonattr['Attribute']
|
jsonattr = jsonattr['Attribute']
|
||||||
to_push = []
|
to_push = []
|
||||||
|
@ -85,12 +82,12 @@ def default_attribute(jsonattr):
|
||||||
|
|
||||||
#try to get coord
|
#try to get coord
|
||||||
if jsonattr['category'] == "Network activity":
|
if jsonattr['category'] == "Network activity":
|
||||||
handleCoord(jsonattr['value'], jsonattr['category'])
|
getCoordAndPublish(jsonattr['value'], jsonattr['category'])
|
||||||
|
|
||||||
to_send = { 'name': 'Attribute', 'log': json.dumps(to_push) }
|
to_send = { 'name': 'Attribute', 'log': json.dumps(to_push) }
|
||||||
redis_server.publish(channel, json.dumps(to_send))
|
redis_server.publish(channel, json.dumps(to_send))
|
||||||
|
|
||||||
def handleCoord(supposed_ip, categ):
|
def getCoordAndPublish(supposed_ip, categ):
|
||||||
try:
|
try:
|
||||||
rep = ip_to_coord(supposed_ip)
|
rep = ip_to_coord(supposed_ip)
|
||||||
coord = rep['coord']
|
coord = rep['coord']
|
||||||
|
@ -109,7 +106,7 @@ def handleCoord(supposed_ip, categ):
|
||||||
"specifName": rep['full_rep'].subdivisions.most_specific.name,
|
"specifName": rep['full_rep'].subdivisions.most_specific.name,
|
||||||
"cityName": rep['full_rep'].city.name,
|
"cityName": rep['full_rep'].city.name,
|
||||||
}
|
}
|
||||||
serv_coord.publish(channel_disp, json.dumps(to_send))
|
serv_coord.publish(channelDisp, json.dumps(to_send))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print("can't resolve ip")
|
print("can't resolve ip")
|
||||||
|
|
||||||
|
@ -128,13 +125,13 @@ def main():
|
||||||
|
|
||||||
|
|
||||||
dico_action = {
|
dico_action = {
|
||||||
"misp_json": default_event,
|
"misp_json": handler_event,
|
||||||
"misp_json_self": default_keepalive,
|
"misp_json_self": handler_keepalive,
|
||||||
"misp_json_attribute": default_attribute,
|
"misp_json_attribute": handler_attribute,
|
||||||
"misp_json_sighting": default_log,
|
"misp_json_sighting": handler_log,
|
||||||
"misp_json_organisation": default_log,
|
"misp_json_organisation": handler_log,
|
||||||
"misp_json_user": default_log,
|
"misp_json_user": handler_log,
|
||||||
"misp_json_conversation": default_log
|
"misp_json_conversation": handler_log
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue