From eaa2658cab8cf7867e0e20e0a6e64de5314fd09e Mon Sep 17 00:00:00 2001 From: Pavel Loginov Date: Tue, 15 Mar 2022 12:51:03 +0300 Subject: [PATCH] v5.5.0.0 Changelog: https://roxy-wi.org/changelog.py#5_5_0 --- app/create_db.py | 9 ++- app/funct.py | 63 ++++++++++++------- app/options.py | 3 + app/templates/ajax/load_services.html | 4 +- app/templates/base.html | 1 + app/templates/include/admin_settings.html | 2 +- app/templates/servers.html | 4 +- inc/reconnecting-websocket.js | 1 + inc/script.js | 77 ++++++++++++----------- inc/users.js | 5 +- 10 files changed, 106 insertions(+), 63 deletions(-) create mode 100644 inc/reconnecting-websocket.js diff --git a/app/create_db.py b/app/create_db.py index a5bab14c..15c5da9f 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -88,6 +88,13 @@ def default_values(): 'desc': 'Attribute to search users by', 'group': '1'}, {'param': 'ldap_search_field', 'value': 'mail', 'section': 'ldap', 'desc': 'User\'s email address', 'group': '1'}, {'param': 'ldap_type', 'value': '0', 'section': 'ldap', 'desc': 'Use LDAPS (1 - yes, 0 - no)', 'group': '1'}, + {'param': 'rabbitmq_host', 'value': '127.0.0.1', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server host', 'group': '1'}, + {'param': 'rabbitmq_port', 'value': '5672', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server port', 'group': '1'}, + {'param': 'rabbitmq_port', 'value': '5672', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server port', 'group': '1'}, + {'param': 'rabbitmq_vhost', 'value': '/', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server vhost', 'group': '1'}, + {'param': 'rabbitmq_queue', 'value': 'roxy-wi', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server queue', 'group': '1'}, + {'param': 'rabbitmq_user', 'value': 'roxy-wi', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server user', 'group': '1'}, + {'param': 'rabbitmq_password', 'value': 'roxy-wi123', 'section': 'rabbitmq', 'desc': 'RabbitMQ-server user password', 'group': '1'}, ] try: Setting.insert_many(data_source).on_conflict_ignore().execute() @@ -896,7 +903,7 @@ def update_db_v_5_4_3_1(**kwargs): def update_ver(): - query = Version.update(version='5.4.3.0') + query = Version.update(version='5.5.0.0') try: query.execute() except: diff --git a/app/funct.py b/app/funct.py index 40772a60..d0a3269b 100644 --- a/app/funct.py +++ b/app/funct.py @@ -36,9 +36,8 @@ def get_config_var(sec, var): path_config = "/var/www/haproxy-wi/app/roxy-wi.cfg" config = ConfigParser(interpolation=ExtendedInterpolation()) config.read(path_config) - except Exception: - print('Content-type: text/html\n') - print('
Check the config file, whether it exists and the path. Must be: app/roxy-wi.cfg
') + except Exception as e: + print('error: ' + str(e)) return try: @@ -157,16 +156,7 @@ def logging(server_ip, action, **kwargs): except Exception: pass - if kwargs.get('metrics') == 1: - mess = get_data('date_in_log') + action + "\n" - log = open(log_path + "/metrics-"+get_data('logs')+".log", "a") - elif kwargs.get('keep_alive') == 1: - mess = get_data('date_in_log') + action + "\n" - log = open(log_path + "/keep_alive-"+get_data('logs')+".log", "a") - elif kwargs.get('port_scanner') == 1: - mess = get_data('date_in_log') + action + "\n" - log = open(log_path + "/port_scanner-"+get_data('logs')+".log", "a") - elif kwargs.get('haproxywi') == 1: + if kwargs.get('haproxywi') == 1: if kwargs.get('login'): mess = get_data('date_in_log') + " from " + ip + " user: " + login + ", group: " + user_group + ", " + \ action + " for: " + server_ip + "\n" @@ -975,7 +965,7 @@ def upload_and_restart(server_ip, cfg, **kwargs): if is_docker == '1': check_config = "sudo docker exec -it exec " + container_name + " nginx -t -q " else: - check_config = "sudo nginx -t -q -p " + tmp_file + check_config = "sudo nginx -t -q " check_and_move = "sudo mv -f " + tmp_file + " " + config_path + " && " + check_config if action == "test": commands = [check_config + " && sudo rm -f " + tmp_file] @@ -1236,7 +1226,7 @@ def show_haproxy_log(serv, rows=10, waf='0', grep=None, hour='00', minut='00', h syslog_server = sql.get_setting('syslog_server') if waf == "1": - local_path_logs = '/var/log/modsec_audit.log' + local_path_logs = '/var/log/waf.log' commands = ["sudo cat %s |tail -%s %s %s" % (local_path_logs, rows, grep_act, exgrep_act)] if kwargs.get('html') == 0: @@ -1437,9 +1427,9 @@ def get_files(dir=get_config_var('configs', 'haproxy_save_configs_dir'), format= def get_remote_files(server_ip: str, config_dir: str, file_format: str): config_dir = return_nice_path(config_dir) if file_format == 'conf': - commands = ['ls ' + config_dir + '*/*.' + file_format] + commands = ['sudo ls ' + config_dir + '*/*.' + file_format] else: - commands = ['ls ' + config_dir + '/*.' + file_format] + commands = ['sudo ls ' + config_dir + '/*.' + file_format] config_files = ssh_command(server_ip, commands) return config_files @@ -1478,11 +1468,11 @@ def check_new_version(**kwargs): try: if proxy is not None and proxy != '' and proxy != 'None': proxy_dict = {"https": proxy, "http": proxy} - response = requests.get('https://haproxy-wi.org/update.py?last_ver'+last_ver+'=1', timeout=1, proxies=proxy_dict) - requests.get('https://haproxy-wi.org/update.py?ver_send='+current_ver, timeout=1, proxies=proxy_dict) + response = requests.get('https://roxy-wi.org/update.py?last_ver'+last_ver+'=1', timeout=1, proxies=proxy_dict) + requests.get('https://roxy-wi.org/update.py?ver_send='+current_ver, timeout=1, proxies=proxy_dict) else: - response = requests.get('https://haproxy-wi.org/update.py?last_ver'+last_ver+'=1', timeout=1) - requests.get('https://haproxy-wi.org/update.py?ver_send='+current_ver, timeout=1) + response = requests.get('https://roxy-wi.org/update.py?last_ver'+last_ver+'=1', timeout=1) + requests.get('https://roxy-wi.org/update.py?ver_send='+current_ver, timeout=1) res = response.content.decode(encoding='UTF-8') except requests.exceptions.RequestException as e: @@ -1627,9 +1617,11 @@ def get_services_status(): 'roxy-wi-metrics': 'Metrics master service', 'roxy-wi-portscanner': 'Port scanner service', 'roxy-wi-smon': 'Simple monitoring network ports', + 'roxy-wi-socket': 'Socket service', 'prometheus': 'Prometheus service', 'grafana-server': 'Grafana service', - 'fail2ban': 'Fail2ban service'} + 'fail2ban': 'Fail2ban service', + 'rabbitmq-server': 'Message broker service'} for s, v in services_name.items(): cmd = "systemctl is-active %s" % s status, stderr = subprocess_execute(cmd) @@ -1892,3 +1884,30 @@ def get_system_info(server_ip: str) -> bool: def string_to_dict(dict_string) -> dict: from ast import literal_eval return literal_eval(dict_string) + + +def send_message_to_rabbit(message: str) -> None: + import pika + import sql + rabbit_user = sql.get_setting('rabbitmq_user') + rabbit_password = sql.get_setting('rabbitmq_password') + rabbit_host = sql.get_setting('rabbitmq_host') + rabbit_port = sql.get_setting('rabbitmq_port') + rabbit_vhost = sql.get_setting('rabbitmq_vhost') + rabbit_queue = sql.get_setting('rabbitmq_queue') + + credentials = pika.PlainCredentials(rabbit_user, rabbit_password) + parameters = pika.ConnectionParameters(rabbit_host, + rabbit_port, + rabbit_vhost, + credentials) + print(str(parameters)) + print(str(credentials)) + connection = pika.BlockingConnection(parameters) + channel = connection.channel() + channel.queue_declare(queue=rabbit_queue) + channel.basic_publish(exchange='', + routing_key='roxy-wi', + body=message) + + connection.close() diff --git a/app/options.py b/app/options.py index 3975dfb3..93348e73 100644 --- a/app/options.py +++ b/app/options.py @@ -70,6 +70,7 @@ if form.getvalue('delcert') is not None and serv is not None: if serv and form.getvalue('ssl_cert'): cert_local_dir = os.path.dirname(os.getcwd()) + "/" + sql.get_setting('ssl_local_path') cert_path = sql.get_setting('cert_path') + name = '' if not os.path.exists(cert_local_dir): os.makedirs(cert_local_dir) @@ -3734,6 +3735,7 @@ if form.getvalue('load_update_hapwi'): metrics_ver = funct.check_new_version(service='metrics') keep_ver = funct.check_new_version(service='keep') portscanner_ver = funct.check_new_version(service='portscanner') + socket_ver = funct.check_new_version(service='socket') services = funct.get_services_status() template = template.render(services=services, @@ -3742,6 +3744,7 @@ if form.getvalue('load_update_hapwi'): smon_ver=smon_ver, metrics_ver=metrics_ver, portscanner_ver=portscanner_ver, + socket_ver=socket_ver, keep_ver=keep_ver) print(template) diff --git a/app/templates/ajax/load_services.html b/app/templates/ajax/load_services.html index dfd9a3a4..b5df8219 100644 --- a/app/templates/ajax/load_services.html +++ b/app/templates/ajax/load_services.html @@ -4,13 +4,13 @@ {% if s.1.0 == 'active' %} {% else %} - {% if s.1.0 == 'inactive' or s.1.0 == 'failed' %} + {% if s.1.0 == 'inactive' or s.1.0 == 'failed' or s.1.0 == 'activating' %} {% else %} {% endif %} {% endif %} - {{s.0}} + {{s.0[0]|upper}}{{s.0[1:]}} diff --git a/app/templates/base.html b/app/templates/base.html index d7f51245..31bc3401 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -37,6 +37,7 @@ + diff --git a/app/templates/include/admin_settings.html b/app/templates/include/admin_settings.html index e5c0975c..e6f05db5 100644 --- a/app/templates/include/admin_settings.html +++ b/app/templates/include/admin_settings.html @@ -2,7 +2,7 @@ {% set section = namespace(section='') %} {% for set in settings %} - {% if page == "servers.py" and set.section == 'monitoring' %} + {% if page == "servers.py" and (set.section == 'monitoring' or set.section == 'rabbitmq') %} {% else %} {% if section.section|string() != set.section|string() %} diff --git a/app/templates/servers.html b/app/templates/servers.html index 9d7619f0..fbec22c5 100644 --- a/app/templates/servers.html +++ b/app/templates/servers.html @@ -45,7 +45,9 @@

Install HAProxy

Current version - Available Versions + + Available Versions (?) + Server Use Docker SYN-flood protection diff --git a/inc/reconnecting-websocket.js b/inc/reconnecting-websocket.js new file mode 100644 index 00000000..3015099a --- /dev/null +++ b/inc/reconnecting-websocket.js @@ -0,0 +1 @@ +!function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a}); diff --git a/inc/script.js b/inc/script.js index cdb599de..9e5c5292 100644 --- a/inc/script.js +++ b/inc/script.js @@ -1255,46 +1255,53 @@ $(function () { preload: true }); }); -async function waitConsumer() { +let socket = new ReconnectingWebSocket("wss://" + window.location.host, null, {maxReconnectAttempts: 20, reconnectInterval: 3000}); + +socket.onopen = function(e) { + console.log("[open] Connection is established with " + window.location.host); + getAlerts(); +}; + +function getAlerts() { + socket.send("alert_group " + Cookies.get('group') + ' ' + Cookies.get('uuid')); +} + +socket.onmessage = function(event) { cur_url = window.location.href.split('/').pop(); cur_url = cur_url.split('?'); - if (cur_url[0] != 'servers.py#installproxy' && cur_url[0] != 'servers.py#installmon' && - cur_url[0] != 'users.py#installmon' && cur_url[0] != 'ha.py' && cur_url[0] != 'users.py#updatehapwi' && - cur_url[0] != 'add.py?service=nginx#ssl' && cur_url[0] != 'add.py#ssl' && cur_url[0] != 'servers.py#geolite2' - && cur_url[0] != 'login.py?ref=/app/overview.py' && sessionStorage.getItem('disabled_alert') === null && localStorage.getItem('disabled_alert') === null) { - NProgress.configure({showSpinner: false}); - $.ajax({ - url: "options.py", - data: { - alert_consumer: '1', - token: $('#token').val() - }, - type: "POST", - success: function (data) { - data = data.split(";"); - for (i = 0; i < data.length; i++) { - if (data[i].indexOf('error:') != '-1' || data[i].indexOf('alert') != '-1' || data[i].indexOf('FAILED') != '-1') { - if (data[i].indexOf('error: database is locked') == '-1') { - toastr.error(data[i]); - ion.sound.play("bell_ring"); - } - } else if (data[i].indexOf('info: ') != '-1') { - toastr.info(data[i]); - ion.sound.play("glass"); - } else if (data[i].indexOf('success: ') != '-1') { - toastr.success(data[i]); - ion.sound.play("glass"); - } else if (data[i].indexOf('warning: ') != '-1') { - toastr.warning(data[i]); - ion.sound.play("bell_ring"); - } + if (cur_url[0] != 'login.py' && sessionStorage.getItem('disabled_alert') === null && localStorage.getItem('disabled_alert') === null) { + data = event.data.split(";"); + for (i = 0; i < data.length; i++) { + if (data[i].indexOf('error:') != '-1' || data[i].indexOf('alert') != '-1' || data[i].indexOf('FAILED') != '-1') { + if (data[i].indexOf('error: database is locked') == '-1') { + toastr.error(data[i]); + ion.sound.play("bell_ring"); } + } else if (data[i].indexOf('info: ') != '-1') { + toastr.info(data[i]); + ion.sound.play("glass"); + } else if (data[i].indexOf('success: ') != '-1') { + toastr.success(data[i]); + ion.sound.play("glass"); + } else if (data[i].indexOf('warning: ') != '-1') { + toastr.warning(data[i]); + ion.sound.play("bell_ring"); } - }); - NProgress.configure({showSpinner: true}); + } } -} -setInterval(waitConsumer, 20000); +}; + +socket.onclose = function(event) { + if (event.wasClean) { + console.log(`[close] Соединение закрыто чисто, код=${event.code} причина=${event.reason}`); + } else { + console.log('[close] Соединение прервано'); + } +}; + +socket.onerror = function(error) { + console.log(`[error] ${error.message}`); +}; function changePassword() { $( "#user-change-password-table" ).dialog({ autoOpen: true, diff --git a/inc/users.js b/inc/users.js index 4e2754ca..016ee74b 100644 --- a/inc/users.js +++ b/inc/users.js @@ -377,7 +377,7 @@ $( function() { type: "POST", success: function( data ) { data = data.replace(/^\s+|\s+$/g,''); - if (data.indexOf('error:') != '-1') { + if (data.indexOf('error:') != '-1' || data.indexOf('command') != '-1') { toastr.clear(); toastr.error(data); } else if(data == 'no') { @@ -793,6 +793,9 @@ $( function() { $('#logs-section-head').click(function () { hideAndShowSettings('logs'); }); + $('#rabbitmq-section-head').click(function () { + hideAndShowSettings('rabbitmq'); + }); } ); function hideAndShowSettings(section) { var ElemId = $('#' + section + '-section-h3');