mirror of https://github.com/Aidaho12/haproxy-wi
parent
7d6ca27c86
commit
2a7a11a9c8
|
@ -518,7 +518,7 @@ def update_db_v_3(**kwargs):
|
||||||
except sqltool.Error as e:
|
except sqltool.Error as e:
|
||||||
if kwargs.get('silent') != 1:
|
if kwargs.get('silent') != 1:
|
||||||
if e.args[0] == 'duplicate column name: section' or e == " 1060 (42S21): Duplicate column name 'section' ":
|
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:
|
else:
|
||||||
print("An error occurred:", e)
|
print("An error occurred:", e)
|
||||||
return False
|
return False
|
||||||
|
@ -558,7 +558,7 @@ def update_db_v_31(**kwargs):
|
||||||
except sqltool.Error as e:
|
except sqltool.Error as e:
|
||||||
if kwargs.get('silent') != 1:
|
if kwargs.get('silent') != 1:
|
||||||
if e.args[0] == 'duplicate column name: desc' or e == "1060 (42S21): Duplicate column name 'desc' ":
|
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:
|
else:
|
||||||
print("An error occurred:", e)
|
print("An error occurred:", e)
|
||||||
return False
|
return False
|
||||||
|
@ -568,6 +568,42 @@ def update_db_v_31(**kwargs):
|
||||||
cur.close()
|
cur.close()
|
||||||
con.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():
|
def update_all():
|
||||||
update_db_v_2_0_1()
|
update_db_v_2_0_1()
|
||||||
update_db_v_2_0_1_1()
|
update_db_v_2_0_1_1()
|
||||||
|
@ -586,6 +622,8 @@ def update_all():
|
||||||
update_db_v_2_91()
|
update_db_v_2_91()
|
||||||
update_db_v_3()
|
update_db_v_3()
|
||||||
update_db_v_31()
|
update_db_v_31()
|
||||||
|
update_db_v_3_2()
|
||||||
|
update_db_v_3_21()
|
||||||
|
|
||||||
def update_all_silent():
|
def update_all_silent():
|
||||||
update_db_v_2_0_1(silent=1)
|
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_2_91(silent=1)
|
||||||
update_db_v_3(silent=1)
|
update_db_v_3(silent=1)
|
||||||
update_db_v_31(silent=1)
|
update_db_v_31(silent=1)
|
||||||
|
update_db_v_3_2(silent=1)
|
||||||
|
update_db_v_3_21(silent=1)
|
||||||
|
|
13
app/funct.py
13
app/funct.py
|
@ -270,16 +270,12 @@ def install_haproxy(serv, **kwargs):
|
||||||
" STATS_USER="+stats_user+" STATS_PASS="+stats_password ]
|
" STATS_USER="+stats_user+" STATS_PASS="+stats_password ]
|
||||||
|
|
||||||
upload(serv, tmp_config_path, script)
|
upload(serv, tmp_config_path, script)
|
||||||
|
os.system("rm -f %s" % script)
|
||||||
ssh_command(serv, commands, print_out="1")
|
ssh_command(serv, commands, print_out="1")
|
||||||
|
|
||||||
if kwargs.get('syn_flood') == "1":
|
if kwargs.get('syn_flood') == "1":
|
||||||
syn_flood_protect(serv)
|
syn_flood_protect(serv)
|
||||||
|
|
||||||
if kwargs.get('waf') == "1":
|
|
||||||
waf_install(serv)
|
|
||||||
|
|
||||||
os.system("rm -f %s" % script)
|
|
||||||
|
|
||||||
def syn_flood_protect(serv, **kwargs):
|
def syn_flood_protect(serv, **kwargs):
|
||||||
import sql
|
import sql
|
||||||
script = "syn_flood_protect.sh"
|
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 ]
|
commands = [ "chmod +x "+tmp_config_path+script, tmp_config_path+script+ " "+enable ]
|
||||||
|
|
||||||
upload(serv, tmp_config_path, script)
|
upload(serv, tmp_config_path, script)
|
||||||
ssh_command(serv, commands, print_out="1")
|
|
||||||
|
|
||||||
os.system("rm -f %s" % script)
|
os.system("rm -f %s" % script)
|
||||||
|
ssh_command(serv, commands, print_out="1")
|
||||||
|
|
||||||
def waf_install(serv, **kwargs):
|
def waf_install(serv, **kwargs):
|
||||||
import sql
|
import sql
|
||||||
|
@ -313,9 +308,9 @@ def waf_install(serv, **kwargs):
|
||||||
" HAPROXY_PATH="+haproxy_dir +" VERSION="+ver ]
|
" HAPROXY_PATH="+haproxy_dir +" VERSION="+ver ]
|
||||||
|
|
||||||
upload(serv, tmp_config_path, script)
|
upload(serv, tmp_config_path, script)
|
||||||
ssh_command(serv, commands, print_out="1")
|
|
||||||
|
|
||||||
os.system("rm -f %s" % script)
|
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):
|
def check_haproxy_version(serv):
|
||||||
import sql
|
import sql
|
||||||
|
|
|
@ -15,9 +15,7 @@ try:
|
||||||
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
|
cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE"))
|
||||||
user_id = cookie.get('uuid')
|
user_id = cookie.get('uuid')
|
||||||
user = sql.get_user_name_by_uuid(user_id.value)
|
user = sql.get_user_name_by_uuid(user_id.value)
|
||||||
servers = sql.get_dick_permit()
|
|
||||||
token = sql.get_token(user_id.value)
|
token = sql.get_token(user_id.value)
|
||||||
table_stat = sql.select_table_metrics(user_id.value)
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ if act == "overview":
|
||||||
ovw.get_overview()
|
ovw.get_overview()
|
||||||
|
|
||||||
if act == "overviewwaf":
|
if act == "overviewwaf":
|
||||||
ovw.get_overviewWaf()
|
ovw.get_overviewWaf(form.getvalue('page'))
|
||||||
|
|
||||||
if act == "overviewServers":
|
if act == "overviewServers":
|
||||||
ovw.get_overviewServers()
|
ovw.get_overviewServers()
|
||||||
|
@ -389,7 +389,13 @@ if form.getvalue('masteradd'):
|
||||||
os.system("rm -f %s" % script)
|
os.system("rm -f %s" % script)
|
||||||
|
|
||||||
if form.getvalue('haproxyaddserv'):
|
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'):
|
if form.getvalue('table_metrics'):
|
||||||
import http.cookies
|
import http.cookies
|
||||||
|
@ -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))
|
grid = gridplot(plots, ncols=2, plot_width=800, plot_height=250, toolbar_location = "left", toolbar_options=dict(logo=None))
|
||||||
show(grid)
|
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'):
|
if form.getvalue('get_hap_v'):
|
||||||
output = funct.check_haproxy_version(serv)
|
output = funct.check_haproxy_version(serv)
|
||||||
print(output)
|
print(output)
|
||||||
|
|
|
@ -29,7 +29,7 @@ def get_overview():
|
||||||
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))
|
||||||
print(template)
|
print(template)
|
||||||
|
|
||||||
def get_overviewWaf():
|
def get_overviewWaf(url):
|
||||||
import http.cookies
|
import http.cookies
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
env = Environment(loader=FileSystemLoader('templates/ajax'))
|
env = Environment(loader=FileSystemLoader('templates/ajax'))
|
||||||
|
@ -46,10 +46,10 @@ def get_overviewWaf():
|
||||||
|
|
||||||
for server in listhap:
|
for server in listhap:
|
||||||
server_status = ()
|
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)
|
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)
|
print(template)
|
||||||
|
|
||||||
def get_overviewServers():
|
def get_overviewServers():
|
||||||
|
|
|
@ -28,7 +28,8 @@ fi
|
||||||
if [ -f $HAPROXY_PATH/waf/modsecurity.conf ];then
|
if [ -f $HAPROXY_PATH/waf/modsecurity.conf ];then
|
||||||
echo -e 'error: Haproxy WAF already installed. You can edit config<a href="/app/config.py" title="Edit HAProxy config">here</a> <br /><br />'
|
echo -e 'error: Haproxy WAF already installed. You can edit config<a href="/app/config.py" title="Edit HAProxy config">here</a> <br /><br />'
|
||||||
exit 1
|
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
|
sudo apt-get install yajl-dev libevent-dev httpd-dev libxml2-dev gcc curl-dev -y
|
||||||
else
|
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
|
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
|
||||||
|
|
131
app/sql.py
131
app/sql.py
|
@ -652,6 +652,137 @@ def insert_mentrics(serv, curr_con, cur_ssl_con, sess_rate, max_sess_rate):
|
||||||
cur.close()
|
cur.close()
|
||||||
con.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('<span class="alert alert-danger" id="error">An error occurred: ' + e.args[0] + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||||
|
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('<span class="alert alert-danger" id="error">An error occurred: ' + e.args[0] + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||||
|
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('<span class="alert alert-danger" id="error">An error occurred: ' + e.args[0] + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||||
|
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('<span class="alert alert-danger" id="error">An error occurred: ' + e + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||||
|
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('<span class="alert alert-danger" id="error">An error occurred: ' + e.args[0] + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||||
|
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('<span class="alert alert-danger" id="error">An error occurred: ' + e.args[0] + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||||
|
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('<span class="alert alert-danger" id="error">An error occurred: ' + e.args[0] + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||||
|
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('<span class="alert alert-danger" id="error">An error occurred: ' + e.args[0] + ' <a title="Close" id="errorMess"><b>X</b></a></span>')
|
||||||
|
con.rollback()
|
||||||
|
cur.close()
|
||||||
|
con.close()
|
||||||
|
|
||||||
def delete_mentrics():
|
def delete_mentrics():
|
||||||
con, cur = create_db.get_cur()
|
con, cur = create_db.get_cur()
|
||||||
if mysql_enable == '1':
|
if mysql_enable == '1':
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{% for service in service_status %}
|
{% for service in service_status %}
|
||||||
|
{% if service.3 or url == "waf.py" %}
|
||||||
<tr class="{{ loop.cycle('odd', 'even') }}">
|
<tr class="{{ loop.cycle('odd', 'even') }}">
|
||||||
<td class="padding10 first-collumn">
|
<td class="padding10 first-collumn">
|
||||||
<a href="#{{ service.0 }}" title="Go to {{ service.0 }} status" style="color: #000">{{ service.0 }}</a>
|
<a href="#{{ service.0 }}" title="Go to {{ service.0 }} status" style="color: #000">{{ service.0 }}</a>
|
||||||
|
@ -27,9 +28,21 @@
|
||||||
{% if service.3 %}
|
{% if service.3 %}
|
||||||
{{ service.3 }}
|
{{ service.3 }}
|
||||||
{%else %}
|
{%else %}
|
||||||
WAF not installed
|
<a title="Install WAF"><button onclick="installWaf('{{ service.1 }}')">Install</button></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
{% if url == "waf.py" %}
|
||||||
|
<td>
|
||||||
|
{% if service.3 %}
|
||||||
|
{% if service.4|int() == 1 %}
|
||||||
|
<label for="{{ service.0 }}"></label><input type="checkbox" id="{{ service.0 }}" checked>
|
||||||
|
{% else %}
|
||||||
|
<label for="{{ service.0 }}"></label><input type="checkbox" id="{{ service.0 }}">
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
|
@ -2,6 +2,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>{{title}} - HAproxy-WI</title>
|
<title>{{title}} - HAproxy-WI</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||||
|
<meta http-equiv="Pragma" content="no-cache" />
|
||||||
|
<meta http-equiv="Expires" content="0" />
|
||||||
<link href="/image/pic/favicon.ico" rel="icon" type="image/png" />
|
<link href="/image/pic/favicon.ico" rel="icon" type="image/png" />
|
||||||
<script>
|
<script>
|
||||||
FontAwesomeConfig = { searchPseudoElements: true, observeMutations: false };
|
FontAwesomeConfig = { searchPseudoElements: true, observeMutations: false };
|
||||||
|
@ -98,7 +101,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="copyright-menu">
|
<div class="copyright-menu">
|
||||||
HAproxy-WI v3.1
|
HAproxy-WI v3.2
|
||||||
<br>
|
<br>
|
||||||
<a href="https://www.patreon.com/haproxy_wi" title="Donate" target="_blank" style="color: #fff; margin-left: 30px; color: red;" class="patreon"> Patreon</a>
|
<a href="https://www.patreon.com/haproxy_wi" title="Donate" target="_blank" style="color: #fff; margin-left: 30px; color: red;" class="patreon"> Patreon</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
<td class="padding10 first-collumn" style="width: 350px;">Note</td>
|
<td class="padding10 first-collumn" style="width: 350px;">Note</td>
|
||||||
<td class="padding10 first-collumn">Server</td>
|
<td class="padding10 first-collumn">Server</td>
|
||||||
<td style="width: 150px;">SYN flood protect</td>
|
<td style="width: 150px;">SYN flood protect</td>
|
||||||
<td style="width: 150px;"><span title="Web application firewall">WAF(?)</span></td>
|
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -24,9 +23,6 @@
|
||||||
<td>
|
<td>
|
||||||
<label for="syn_flood" title="Enable SYN flood protect"><input type="checkbox" id="syn_flood" checked>
|
<label for="syn_flood" title="Enable SYN flood protect"><input type="checkbox" id="syn_flood" checked>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
|
||||||
<label for="waf" title="Enable SYN flood protect"><input type="checkbox" id="waf">
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<a class="ui-button ui-widget ui-corner-all" id="install" title="Install HAProxy">Install</a>
|
<a class="ui-button ui-widget ui-corner-all" id="install" title="Install HAProxy">Install</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<table class="overview">
|
||||||
|
<tr class="overviewHead">
|
||||||
|
<td class="padding10 first-collumn">
|
||||||
|
Server
|
||||||
|
</td class="padding10 second-collumn">
|
||||||
|
<td class="padding10 second-collumn">
|
||||||
|
WAF status
|
||||||
|
</td>
|
||||||
|
<td class="padding10">
|
||||||
|
Action
|
||||||
|
</td>
|
||||||
|
<td class="padding10">
|
||||||
|
WAF mode
|
||||||
|
</td class="padding10">
|
||||||
|
<td>
|
||||||
|
Metrics
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a onclick="showOverviewWaf()" title="Refresh" style="float: right; margin-right: 25px;"><img src="/image/pic/update.png" alt="restart" class="icon"></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tbody id="ajaxwafstatus"></tbody>
|
||||||
|
</table>
|
||||||
|
<div id="ajax"></div>
|
||||||
|
<style>
|
||||||
|
iframe {
|
||||||
|
border: none;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="metrics_iframe"></div>
|
||||||
|
<script>
|
||||||
|
showOverviewWaf()
|
||||||
|
function callIframe(url, callback) {
|
||||||
|
$('#metrics_iframe').html('<iframe id="metrics" style="width:100%;height:100%;" />');
|
||||||
|
$('iframe#metrics').attr('src', url);
|
||||||
|
$('iframe#metrics').load(function() {
|
||||||
|
callback(this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function loadMetrics() {
|
||||||
|
callIframe('templates/metrics_waf_out.html', function(){
|
||||||
|
$.get( "options.py?waf_metrics=1&token="+$('#token').val(), function( data ) {
|
||||||
|
$( ".result" ).html( data );
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMetrics()
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -20,6 +20,7 @@ class GracefulKiller:
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
sql.delete_mentrics()
|
sql.delete_mentrics()
|
||||||
|
sql.delete_waf_mentrics()
|
||||||
servers = sql.select_servers_metrics_for_master()
|
servers = sql.select_servers_metrics_for_master()
|
||||||
started_workers = get_worker()
|
started_workers = get_worker()
|
||||||
servers_list = []
|
servers_list = []
|
||||||
|
@ -38,6 +39,24 @@ def main():
|
||||||
for serv in need_start:
|
for serv in need_start:
|
||||||
start_worker(serv)
|
start_worker(serv)
|
||||||
|
|
||||||
|
waf_servers = sql.select_waf_servers()
|
||||||
|
waf_started_workers = get_waf_worker()
|
||||||
|
waf_servers_list = []
|
||||||
|
|
||||||
|
for serv in waf_servers:
|
||||||
|
waf_servers_list.append(serv[0])
|
||||||
|
|
||||||
|
waf_need_kill=list(set(waf_started_workers) - set(waf_servers_list))
|
||||||
|
waf_need_start=list(set(waf_servers_list) - set(waf_started_workers))
|
||||||
|
|
||||||
|
if waf_need_kill:
|
||||||
|
for serv in waf_need_kill:
|
||||||
|
kill_waf_worker(serv)
|
||||||
|
|
||||||
|
if waf_need_start:
|
||||||
|
for serv in waf_need_start:
|
||||||
|
start_waf_worker(serv)
|
||||||
|
|
||||||
def start_worker(serv):
|
def start_worker(serv):
|
||||||
port = sql.get_setting('haproxy_sock_port')
|
port = sql.get_setting('haproxy_sock_port')
|
||||||
cmd = "tools/metrics_worker.py %s --port %s &" % (serv, port)
|
cmd = "tools/metrics_worker.py %s --port %s &" % (serv, port)
|
||||||
|
@ -51,6 +70,19 @@ def kill_worker(serv):
|
||||||
if stderr:
|
if stderr:
|
||||||
funct.logging("localhost", stderr, metrics=1)
|
funct.logging("localhost", stderr, metrics=1)
|
||||||
|
|
||||||
|
def start_waf_worker(serv):
|
||||||
|
port = sql.get_setting('haproxy_sock_port')
|
||||||
|
cmd = "tools/metrics_waf_worker.py %s --port %s &" % (serv, port)
|
||||||
|
os.system(cmd)
|
||||||
|
funct.logging("localhost", " Masrer started new metrics worker for: "+serv, metrics=1)
|
||||||
|
|
||||||
|
def kill_waf_worker(serv):
|
||||||
|
cmd = "ps ax |grep 'tools/metrics_waf_worker.py %s'|grep -v grep |awk '{print $1}' |xargs kill" % serv
|
||||||
|
output, stderr = funct.subprocess_execute(cmd)
|
||||||
|
funct.logging("localhost", " Masrer killed metrics worker for: "+serv, metrics=1)
|
||||||
|
if stderr:
|
||||||
|
funct.logging("localhost", stderr, metrics=1)
|
||||||
|
|
||||||
def kill_all_workers():
|
def kill_all_workers():
|
||||||
cmd = "ps ax |grep -e 'tools/metrics_worker.py\|tools/metrics_waf_worker.py' |grep -v grep |awk '{print $1}' |xargs kill"
|
cmd = "ps ax |grep -e 'tools/metrics_worker.py\|tools/metrics_waf_worker.py' |grep -v grep |awk '{print $1}' |xargs kill"
|
||||||
output, stderr = funct.subprocess_execute(cmd)
|
output, stderr = funct.subprocess_execute(cmd)
|
||||||
|
@ -65,6 +97,13 @@ def get_worker():
|
||||||
funct.logging("localhost", stderr, metrics=1)
|
funct.logging("localhost", stderr, metrics=1)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def get_waf_worker():
|
||||||
|
cmd = "ps ax |grep 'tools/metrics_waf_worker.py' |grep -v grep |awk '{print $7}'"
|
||||||
|
output, stderr = funct.subprocess_execute(cmd)
|
||||||
|
if stderr:
|
||||||
|
funct.logging("localhost", stderr, metrics=1)
|
||||||
|
return output
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
funct.logging("localhost", " Metrics master started", metrics=1)
|
funct.logging("localhost", " Metrics master started", metrics=1)
|
||||||
killer = GracefulKiller()
|
killer = GracefulKiller()
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import subprocess
|
||||||
|
from subprocess import check_output, CalledProcessError
|
||||||
|
import time
|
||||||
|
import argparse
|
||||||
|
import os, sys
|
||||||
|
sys.path.append(os.path.join(sys.path[0], os.path.dirname(os.getcwd())))
|
||||||
|
sys.path.append(os.path.join(sys.path[0], os.getcwd()))
|
||||||
|
import sql
|
||||||
|
import signal
|
||||||
|
|
||||||
|
class GracefulKiller:
|
||||||
|
kill_now = False
|
||||||
|
def __init__(self):
|
||||||
|
signal.signal(signal.SIGINT, self.exit_gracefully)
|
||||||
|
signal.signal(signal.SIGTERM, self.exit_gracefully)
|
||||||
|
|
||||||
|
def exit_gracefully(self,signum, frame):
|
||||||
|
self.kill_now = True
|
||||||
|
|
||||||
|
def main(serv, port):
|
||||||
|
port = str(port)
|
||||||
|
firstrun = True
|
||||||
|
readstats = ""
|
||||||
|
killer = GracefulKiller()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
cmd = "echo 'show stat' |nc "+serv+" "+port+" | cut -d ',' -f 1-2,34 |grep waf |grep BACKEND |awk -F',' '{print $3}'"
|
||||||
|
readstats = subprocess.check_output([cmd], shell=True)
|
||||||
|
except CalledProcessError as e:
|
||||||
|
print("Command error")
|
||||||
|
except OSError as e:
|
||||||
|
print(e)
|
||||||
|
sys.exit()
|
||||||
|
readstats = readstats.decode(encoding='UTF-8')
|
||||||
|
metric = readstats.splitlines()
|
||||||
|
metrics = []
|
||||||
|
|
||||||
|
if metric:
|
||||||
|
for i in range(0,len(metric)):
|
||||||
|
sql.insert_waf_mentrics(serv, metric[i])
|
||||||
|
|
||||||
|
time.sleep(10)
|
||||||
|
|
||||||
|
if killer.kill_now:
|
||||||
|
break
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description='Metrics HAProxy service.', prog='metrics_worker.py', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||||
|
|
||||||
|
parser.add_argument('IP', help='Start get metrics from HAProxy service at this ip', nargs='?', type=str)
|
||||||
|
parser.add_argument('--port', help='Start get metrics from HAProxy service at this port', nargs='?', default=1999, type=int)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
if args.IP is None:
|
||||||
|
parser.print_help()
|
||||||
|
import sys
|
||||||
|
sys.exit()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
main(args.IP, args.port)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import sql
|
||||||
|
import http
|
||||||
|
import funct
|
||||||
|
import sql
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
env = Environment(loader=FileSystemLoader('templates/'))
|
||||||
|
template = env.get_template('waf.html')
|
||||||
|
|
||||||
|
print('Content-type: text/html\n')
|
||||||
|
funct.check_login()
|
||||||
|
|
||||||
|
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)
|
||||||
|
token = sql.get_token(user_id.value)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
template = template.render(h2 = 1, title = "Web application firewall",
|
||||||
|
autorefresh = 1,
|
||||||
|
role = sql.get_user_role_by_uuid(user_id.value),
|
||||||
|
user = user,
|
||||||
|
table_stat = sql.select_table_metrics(user_id.value),
|
||||||
|
token = token)
|
||||||
|
print(template)
|
|
@ -104,6 +104,11 @@ function startSetInterval(interval) {
|
||||||
intervalId = setInterval('loadMetrics()', interval);
|
intervalId = setInterval('loadMetrics()', interval);
|
||||||
loadMetrics();
|
loadMetrics();
|
||||||
}
|
}
|
||||||
|
else if (cur_url[0] == "waf.py") {
|
||||||
|
intervalId = setInterval('loadMetrics()', interval);
|
||||||
|
showOverviewWaf();
|
||||||
|
loadMetrics();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pauseAutoRefresh();
|
pauseAutoRefresh();
|
||||||
}
|
}
|
||||||
|
@ -156,11 +161,11 @@ function showOverview() {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
function showOverviewWaf() {
|
function showOverviewWaf() {
|
||||||
showOverviewServers();
|
|
||||||
$.ajax( {
|
$.ajax( {
|
||||||
url: "options.py",
|
url: "options.py",
|
||||||
data: {
|
data: {
|
||||||
act: "overviewwaf",
|
act: "overviewwaf",
|
||||||
|
page: cur_url[0],
|
||||||
token: $('#token').val()
|
token: $('#token').val()
|
||||||
},
|
},
|
||||||
type: "GET",
|
type: "GET",
|
||||||
|
@ -168,6 +173,8 @@ function showOverviewWaf() {
|
||||||
$("#ajaxwafstatus").empty();
|
$("#ajaxwafstatus").empty();
|
||||||
$("#ajaxwafstatus").html(data);
|
$("#ajaxwafstatus").html(data);
|
||||||
$.getScript('/inc/overview.js');
|
$.getScript('/inc/overview.js');
|
||||||
|
$.getScript('/inc/waf.js');
|
||||||
|
$.getScript(url);
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,13 +100,9 @@ $( function() {
|
||||||
$('#install').click(function() {
|
$('#install').click(function() {
|
||||||
$("#ajax").html('')
|
$("#ajax").html('')
|
||||||
var syn_flood = 0;
|
var syn_flood = 0;
|
||||||
var waf = 0;
|
|
||||||
if ($('#syn_flood').is(':checked')) {
|
if ($('#syn_flood').is(':checked')) {
|
||||||
syn_flood = '1';
|
syn_flood = '1';
|
||||||
}
|
}
|
||||||
if ($('#waf').is(':checked')) {
|
|
||||||
waf = '1';
|
|
||||||
}
|
|
||||||
$("#ajax").html('<div class="alert alert-warning">Please don\'t close and don\'t represh page. Wait until the work is completed. This may take some time </div>');
|
$("#ajax").html('<div class="alert alert-warning">Please don\'t close and don\'t represh page. Wait until the work is completed. This may take some time </div>');
|
||||||
$.ajax( {
|
$.ajax( {
|
||||||
url: "options.py",
|
url: "options.py",
|
||||||
|
@ -129,8 +125,6 @@ $( function() {
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
});
|
});
|
||||||
//$('.alert-danger').remove();
|
|
||||||
|
|
||||||
$('#add-user').click(function() {
|
$('#add-user').click(function() {
|
||||||
$('#error').remove();
|
$('#error').remove();
|
||||||
$.ajax( {
|
$.ajax( {
|
||||||
|
@ -393,7 +387,9 @@ $( function() {
|
||||||
var id = $(this).attr('id').split('-');
|
var id = $(this).attr('id').split('-');
|
||||||
updateTelegram(id[1])
|
updateTelegram(id[1])
|
||||||
});
|
});
|
||||||
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
function updateSettings(param, val) {
|
function updateSettings(param, val) {
|
||||||
$('.alert-danger').remove();
|
$('.alert-danger').remove();
|
||||||
$.ajax( {
|
$.ajax( {
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
$( function() {
|
||||||
|
$( "#ajaxwafstatus input" ).change(function() {
|
||||||
|
var id = $(this).attr('id');
|
||||||
|
console.log(id);
|
||||||
|
metrics_waf(id);
|
||||||
|
});
|
||||||
|
} );
|
||||||
|
function metrics_waf(name) {
|
||||||
|
var enable = 0;
|
||||||
|
if ($('#'+name).is(':checked')) {
|
||||||
|
enable = '1';
|
||||||
|
}
|
||||||
|
$.ajax( {
|
||||||
|
url: "options.py",
|
||||||
|
data: {
|
||||||
|
metrics_waf: name,
|
||||||
|
enable: enable,
|
||||||
|
token: $('#token').val()
|
||||||
|
},
|
||||||
|
type: "GET",
|
||||||
|
success: function( data ) {
|
||||||
|
showOverviewWaf();
|
||||||
|
setTimeout(function() {
|
||||||
|
$( "#"+name ).parent().parent().removeClass( "update" );
|
||||||
|
}, 2500 );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
function installWaf(ip) {
|
||||||
|
$("#ajax").html('')
|
||||||
|
$("#ajax").html('<div class="alert alert-warning">Please don\'t close and don\'t represh page. Wait until the work is completed. This may take some time </div>');
|
||||||
|
$.ajax( {
|
||||||
|
url: "options.py",
|
||||||
|
data: {
|
||||||
|
installwaf: ip,
|
||||||
|
token: $('#token').val()
|
||||||
|
},
|
||||||
|
type: "GET",
|
||||||
|
success: function( data ) {
|
||||||
|
data = data.replace(/\s+/g,' ');
|
||||||
|
if (data.indexOf('error') != '-1' || data.indexOf('Failed') != '-1') {
|
||||||
|
$("#ajax").html('<div class="alert alert-danger">'+data+'</data>');
|
||||||
|
} else if (data.indexOf('success') != '-1' ){
|
||||||
|
$('.alert-danger').remove();
|
||||||
|
$('.alert-warning').remove();
|
||||||
|
$("#ajax").html('<div class="alert alert-success">'+data+'</data>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
Loading…
Reference in New Issue