WAF page!
pull/42/head
Aidaho12 2018-08-20 12:39:52 +06:00
parent 7d6ca27c86
commit 2a7a11a9c8
17 changed files with 526 additions and 33 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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():

View File

@ -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

View File

@ -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':

View File

@ -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 %}

View File

@ -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>

View File

@ -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>

54
app/templates/waf.html Normal file
View File

@ -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 %}

View File

@ -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()

View File

@ -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

28
app/waf.py Normal file
View File

@ -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)

View File

@ -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);
} }
} ); } );
} }

View File

@ -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( {

50
inc/waf.js Normal file
View File

@ -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>');
}
}
} );
}