diff --git a/app/create_db.py b/app/create_db.py
index cc4b6613..fca42693 100644
--- a/app/create_db.py
+++ b/app/create_db.py
@@ -518,7 +518,7 @@ def update_db_v_3(**kwargs):
except sqltool.Error as e:
if kwargs.get('silent') != 1:
if e.args[0] == 'duplicate column name: section' or e == " 1060 (42S21): Duplicate column name 'section' ":
- print('DB was update to 3.0 It\' last version')
+ print('Updating... go to version 3.2')
else:
print("An error occurred:", e)
return False
@@ -558,7 +558,7 @@ def update_db_v_31(**kwargs):
except sqltool.Error as e:
if kwargs.get('silent') != 1:
if e.args[0] == 'duplicate column name: desc' or e == "1060 (42S21): Duplicate column name 'desc' ":
- print('DB was update to 3.0 It\' last version')
+ print('')
else:
print("An error occurred:", e)
return False
@@ -567,6 +567,42 @@ def update_db_v_31(**kwargs):
return True
cur.close()
con.close()
+
+def update_db_v_3_2(**kwargs):
+ con, cur = get_cur()
+ sql = """CREATE TABLE IF NOT EXISTS `waf` (`server_id` INTEGER UNIQUE, metrics INTEGER); """
+ try:
+ cur.execute(sql)
+ con.commit()
+ except sqltool.Error as e:
+ if kwargs.get('silent') != 1:
+ if e.args[0] == 'duplicate column name: server_id' or e == "1060 (42S21): Duplicate column name 'server_id' ":
+ print('DB was updated')
+ else:
+ print("An error occurred:", e.args[0])
+ return False
+ else:
+ return True
+ cur.close()
+ con.close()
+
+def update_db_v_3_21(**kwargs):
+ con, cur = get_cur()
+ sql = """CREATE TABLE IF NOT EXISTS `waf_metrics` (`serv` varchar(64), conn INTEGER, `date` DATETIME default '0000-00-00 00:00:00'); """
+ try:
+ cur.execute(sql)
+ con.commit()
+ except sqltool.Error as e:
+ if kwargs.get('silent') != 1:
+ if e.args[0] == 'duplicate column name: token' or e == "1060 (42S21): Duplicate column name 'token' ":
+ print('Updating... go to version 2.6')
+ else:
+ print("An error occurred:", e.args[0])
+ return False
+ else:
+ return True
+ cur.close()
+ con.close()
def update_all():
update_db_v_2_0_1()
@@ -586,6 +622,8 @@ def update_all():
update_db_v_2_91()
update_db_v_3()
update_db_v_31()
+ update_db_v_3_2()
+ update_db_v_3_21()
def update_all_silent():
update_db_v_2_0_1(silent=1)
@@ -605,4 +643,6 @@ def update_all_silent():
update_db_v_2_91(silent=1)
update_db_v_3(silent=1)
update_db_v_31(silent=1)
+ update_db_v_3_2(silent=1)
+ update_db_v_3_21(silent=1)
\ No newline at end of file
diff --git a/app/funct.py b/app/funct.py
index b8ef1b36..594c2003 100644
--- a/app/funct.py
+++ b/app/funct.py
@@ -270,16 +270,12 @@ def install_haproxy(serv, **kwargs):
" STATS_USER="+stats_user+" STATS_PASS="+stats_password ]
upload(serv, tmp_config_path, script)
+ os.system("rm -f %s" % script)
ssh_command(serv, commands, print_out="1")
if kwargs.get('syn_flood') == "1":
syn_flood_protect(serv)
- if kwargs.get('waf') == "1":
- waf_install(serv)
-
- os.system("rm -f %s" % script)
-
def syn_flood_protect(serv, **kwargs):
import sql
script = "syn_flood_protect.sh"
@@ -295,9 +291,8 @@ def syn_flood_protect(serv, **kwargs):
commands = [ "chmod +x "+tmp_config_path+script, tmp_config_path+script+ " "+enable ]
upload(serv, tmp_config_path, script)
- ssh_command(serv, commands, print_out="1")
-
os.system("rm -f %s" % script)
+ ssh_command(serv, commands, print_out="1")
def waf_install(serv, **kwargs):
import sql
@@ -313,9 +308,9 @@ def waf_install(serv, **kwargs):
" HAPROXY_PATH="+haproxy_dir +" VERSION="+ver ]
upload(serv, tmp_config_path, script)
- ssh_command(serv, commands, print_out="1")
-
os.system("rm -f %s" % script)
+ sql.insert_waf_metrics_enable(serv, "0")
+ ssh_command(serv, commands, print_out="1")
def check_haproxy_version(serv):
import sql
diff --git a/app/metrics.py b/app/metrics.py
index 4589c26a..0c261dc7 100644
--- a/app/metrics.py
+++ b/app/metrics.py
@@ -15,9 +15,7 @@ try:
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
user_id = cookie.get('uuid')
user = sql.get_user_name_by_uuid(user_id.value)
- servers = sql.get_dick_permit()
token = sql.get_token(user_id.value)
- table_stat = sql.select_table_metrics(user_id.value)
except:
pass
diff --git a/app/options.py b/app/options.py
index b52f4d6e..a6805eed 100644
--- a/app/options.py
+++ b/app/options.py
@@ -114,7 +114,7 @@ if act == "overview":
ovw.get_overview()
if act == "overviewwaf":
- ovw.get_overviewWaf()
+ ovw.get_overviewWaf(form.getvalue('page'))
if act == "overviewServers":
ovw.get_overviewServers()
@@ -389,8 +389,14 @@ if form.getvalue('masteradd'):
os.system("rm -f %s" % script)
if form.getvalue('haproxyaddserv'):
- funct.install_haproxy(form.getvalue('haproxyaddserv'), syn_flood=form.getvalue('syn_flood'), waf=form.getvalue('waf'))
+ funct.install_haproxy(form.getvalue('haproxyaddserv'), syn_flood=form.getvalue('syn_flood'))
+if form.getvalue('installwaf'):
+ funct.waf_install(form.getvalue('installwaf'))
+
+if form.getvalue('metrics_waf'):
+ sql.update_waf_metrics_enable(form.getvalue('metrics_waf'), form.getvalue('enable'))
+
if form.getvalue('table_metrics'):
import http.cookies
from jinja2 import Environment, FileSystemLoader
@@ -489,6 +495,78 @@ if form.getvalue('metrics'):
grid = gridplot(plots, ncols=2, plot_width=800, plot_height=250, toolbar_location = "left", toolbar_options=dict(logo=None))
show(grid)
+if form.getvalue('waf_metrics'):
+ from datetime import timedelta
+ from bokeh.plotting import figure, output_file, show
+ from bokeh.models import ColumnDataSource, HoverTool, DatetimeTickFormatter, DatePicker
+ from bokeh.layouts import widgetbox, gridplot
+ from bokeh.models.widgets import Button, RadioButtonGroup, Select
+ import pandas as pd
+ import http.cookies
+
+ cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
+ user_id = cookie.get('uuid')
+ servers = sql.select_waf_servers_metrics(user_id.value)
+
+ p = {}
+ for serv in servers:
+ serv = serv[0]
+ p[serv] = {}
+ metric = sql.select_waf_metrics(serv)
+ metrics = {}
+
+ for i in metric:
+ rep_date = str(i[2])
+ metrics[rep_date] = {}
+ metrics[rep_date]['conn'] = str(i[1])
+
+ df = pd.DataFrame.from_dict(metrics, orient="index")
+ df = df.fillna(0)
+ df.index = pd.to_datetime(df.index)
+ df.index.name = 'Date'
+ df.sort_index(inplace=True)
+ source = ColumnDataSource(df)
+
+ output_file("templates/metrics_waf_out.html")
+
+ x_min = df.index.min() - pd.Timedelta(hours=1)
+ x_max = df.index.max() + pd.Timedelta(minutes=1)
+
+ p[serv] = figure(
+ tools="pan,box_zoom,reset,xwheel_zoom",
+ title=metric[0][0],
+ x_axis_type="datetime", y_axis_label='Connections',
+ x_range = (x_max.timestamp()*1000-60*100000, x_max.timestamp()*1000)
+ )
+
+ hover = HoverTool(
+ tooltips=[
+ ("Connections", "@conn"),
+ ],
+ mode='mouse'
+ )
+
+ p[serv].ygrid.band_fill_color = "#f3f8fb"
+ p[serv].ygrid.band_fill_alpha = 0.9
+ p[serv].y_range.start = 0
+ p[serv].y_range.end = int(df['conn'].max()) + 150
+ p[serv].add_tools(hover)
+ p[serv].title.text_font_size = "20px"
+
+
+ p[serv].line("Date", "conn", source=source, alpha=0.5, color='#5cb85c', line_width=2, legend="Conn")
+ p[serv].legend.orientation = "horizontal"
+ p[serv].legend.location = "top_left"
+ p[serv].legend.padding = 5
+
+ plots = []
+ i = 0
+ for key, value in p.items():
+ plots.append(value)
+
+ grid = gridplot(plots, ncols=2, plot_width=800, plot_height=250, toolbar_location = "left", toolbar_options=dict(logo=None))
+ show(grid)
+
if form.getvalue('get_hap_v'):
output = funct.check_haproxy_version(serv)
print(output)
diff --git a/app/ovw.py b/app/ovw.py
index 8088a3d5..dff776f1 100644
--- a/app/ovw.py
+++ b/app/ovw.py
@@ -29,7 +29,7 @@ def get_overview():
template = template.render(service_status = servers, role = sql.get_user_role_by_uuid(user_id.value))
print(template)
-def get_overviewWaf():
+def get_overviewWaf(url):
import http.cookies
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates/ajax'))
@@ -46,10 +46,10 @@ def get_overviewWaf():
for server in listhap:
server_status = ()
- server_status = (server[1],server[2], funct.ssh_command(server[2], commands), funct.ssh_command(server[2], commands1))
+ server_status = (server[1],server[2], funct.ssh_command(server[2], commands), funct.ssh_command(server[2], commands1), sql.select_waf_metrics_enable_server(server[2]))
servers.append(server_status)
- template = template.render(service_status = servers, role = sql.get_user_role_by_uuid(user_id.value))
+ template = template.render(service_status = servers, role = sql.get_user_role_by_uuid(user_id.value), url=url)
print(template)
def get_overviewServers():
diff --git a/app/scripts/waf.sh b/app/scripts/waf.sh
index c5b6c3a0..7ba115ee 100644
--- a/app/scripts/waf.sh
+++ b/app/scripts/waf.sh
@@ -28,7 +28,8 @@ fi
if [ -f $HAPROXY_PATH/waf/modsecurity.conf ];then
echo -e 'error: Haproxy WAF already installed. You can edit confighere
'
exit 1
-fiif hash apt-get 2>/dev/null; then
+fi
+if hash apt-get 2>/dev/null; then
sudo apt-get install yajl-dev libevent-dev httpd-dev libxml2-dev gcc curl-dev -y
else
wget -O /tmp/yajl-devel-2.0.4-4.el7.x86_64.rpm http://rpmfind.net/linux/centos/7.5.1804/os/x86_64/Packages/yajl-devel-2.0.4-4.el7.x86_64.rpm
diff --git a/app/sql.py b/app/sql.py
index 2468d2b0..f4cf0fbc 100644
--- a/app/sql.py
+++ b/app/sql.py
@@ -652,6 +652,137 @@ def insert_mentrics(serv, curr_con, cur_ssl_con, sess_rate, max_sess_rate):
cur.close()
con.close()
+def select_waf_metrics_enable(id):
+ con, cur = create_db.get_cur()
+ sql = """ select waf.metrics from waf left join servers as serv on waf.server_id = serv.id where server_id = '%s' """ % id
+ try:
+ cur.execute(sql)
+ except sqltool.Error as e:
+ print('An error occurred: ' + e.args[0] + ' X')
+ else:
+ return cur.fetchall()
+ cur.close()
+ con.close()
+
+def select_waf_metrics_enable_server(ip):
+ con, cur = create_db.get_cur()
+ sql = """ select waf.metrics from waf left join servers as serv on waf.server_id = serv.id where ip = '%s' """ % ip
+ try:
+ cur.execute(sql)
+ except sqltool.Error as e:
+ print('An error occurred: ' + e.args[0] + ' X')
+ else:
+ for enable in cur.fetchall():
+ return enable[0]
+ cur.close()
+ con.close()
+
+def select_waf_servers():
+ con, cur = create_db.get_cur()
+ sql = """ select serv.ip from waf left join servers as serv on waf.server_id = serv.id where waf.metrics = '1'"""
+ try:
+ cur.execute(sql)
+ except sqltool.Error as e:
+ print('An error occurred: ' + e.args[0] + ' X')
+ else:
+ return cur.fetchall()
+ cur.close()
+ con.close()
+
+def select_waf_servers_metrics(uuid, **kwargs):
+ con, cur = create_db.get_cur()
+ sql = """ select * from user where username = '%s' """ % get_user_name_by_uuid(uuid)
+
+ if kwargs.get('disable') == 0:
+ disable = 'or enable = 0'
+ else:
+ disable = ''
+
+ try:
+ cur.execute(sql)
+ except sqltool.Error as e:
+ print("An error occurred:", e)
+ else:
+ for group in cur:
+ if group[5] == '1':
+ sql = """ select servers.ip from servers left join waf as waf on waf.server_id = servers.id where servers.enable = 1 %s and waf.metrics = '1' """ % (disable)
+ else:
+ sql = """ select servers.ip from servers left join waf as waf on waf.server_id = servers.id where servers.enable = 1 %s and waf.metrics = '1' and servers.groups like '%{group}%' """.format(group=group[5])
+ try:
+ cur.execute(sql)
+ except sqltool.Error as e:
+ print("An error occurred:", e.args[0])
+ else:
+ return cur.fetchall()
+ cur.close()
+ con.close()
+
+def select_waf_metrics(serv, **kwargs):
+ con, cur = create_db.get_cur()
+ sql = """ select * from waf_metrics where serv = '%s' order by `date` desc """ % serv
+ try:
+ cur.execute(sql)
+ except sqltool.Error as e:
+ print('An error occurred: ' + e + ' X')
+ else:
+ return cur.fetchall()
+ cur.close()
+ con.close()
+
+def insert_waf_metrics_enable(serv, enable):
+ con, cur = create_db.get_cur()
+ sql = """ insert into waf (server_id, metrics) values((select id from servers where ip = '%s'), '%s') """ % (serv, enable)
+ try:
+ cur.execute(sql)
+ con.commit()
+ except sqltool.Error as e:
+ print('An error occurred: ' + e.args[0] + ' X')
+ con.rollback()
+ cur.close()
+ con.close()
+
+def insert_waf_mentrics(serv, conn):
+ con, cur = create_db.get_cur()
+ if mysql_enable == '1':
+ sql = """ insert into waf_metrics (serv, conn, date) values('%s', '%s', now()) """ % (serv, con)
+ else:
+ sql = """ insert into waf_metrics (serv, conn, date) values('%s', '%s', datetime('now', 'localtime')) """ % (serv, conn)
+ try:
+ cur.execute(sql)
+ con.commit()
+ except sqltool.Error as e:
+ print('An error occurred: ' + e.args[0] + ' X')
+ con.rollback()
+ cur.close()
+ con.close()
+
+def delete_waf_mentrics():
+ con, cur = create_db.get_cur()
+ if mysql_enable == '1':
+ sql = """ delete from metrics where date < now() - INTERVAL 3 day """
+ else:
+ sql = """ delete from metrics where date < datetime('now', '-3 days') """
+ try:
+ cur.execute(sql)
+ con.commit()
+ except sqltool.Error as e:
+ print('An error occurred: ' + e.args[0] + ' X')
+ con.rollback()
+ cur.close()
+ con.close()
+
+def update_waf_metrics_enable(name, enable):
+ con, cur = create_db.get_cur()
+ sql = """ update waf set metrics = %s where server_id = (select id from servers where hostname = '%s') """ % (enable, name)
+ try:
+ cur.execute(sql)
+ con.commit()
+ except sqltool.Error as e:
+ print('An error occurred: ' + e.args[0] + ' X')
+ con.rollback()
+ cur.close()
+ con.close()
+
def delete_mentrics():
con, cur = create_db.get_cur()
if mysql_enable == '1':
diff --git a/app/templates/ajax/overivewWaf.html b/app/templates/ajax/overivewWaf.html
index 337be011..423168a2 100644
--- a/app/templates/ajax/overivewWaf.html
+++ b/app/templates/ajax/overivewWaf.html
@@ -1,4 +1,5 @@
{% for service in service_status %}
+ {% if service.3 or url == "waf.py" %}