Aidaho 2024-04-04 14:30:07 +03:00
parent 4382c44b92
commit 8c28c5128c
47 changed files with 346 additions and 349 deletions

View File

@ -735,7 +735,7 @@ def update_db_v_7_2_0_1():
def update_ver():
try:
Version.update(version='7.2.1.0').execute()
Version.update(version='7.2.2.0').execute()
except Exception:
print('Cannot update version')

View File

@ -1,13 +1,52 @@
import re
import dateutil
from datetime import datetime
from shlex import quote
from shutil import which
from pytz import timezone
import app.modules.db.sql as sql
error_mess = 'error: All fields must be completed'
def _convert_to_time_zone(date: datetime) -> datetime:
"""
Convert a datetime object to the specified time zone.
:param date: The datetime object to convert.
:return: The converted datetime object.
"""
from_zone = dateutil.tz.gettz('UTC')
time_zone = sql.get_setting('time_zone')
to_zone = dateutil.tz.gettz(time_zone)
utc = date.replace(tzinfo=from_zone)
native = utc.astimezone(to_zone)
return native
def get_time_zoned_date(date: datetime, fmt: str = None) -> str:
"""
Formats a given date and returns the formatted date in the specified or default format.
:param date: The date to be formatted.
:type date: datetime
:param fmt: The format to use for the formatted date. If not provided, a default format will be used.
:type fmt: str, optional
:return: The formatted date.
:rtype: str
"""
native = _convert_to_time_zone(date)
date_format = '%Y-%m-%d %H:%M:%S'
if fmt:
return native.strftime(fmt)
else:
return native.strftime(date_format)
def get_present_time():
"""
Returns the current time in UTC.

View File

@ -1,12 +1,11 @@
from app.modules.db.db_model import ConfigVersion
from app.modules.db.sql import get_setting
from app.modules.db.server import select_server_id_by_ip
from app.modules.db.common import out_error
import app.modules.roxy_wi_tools as roxy_wi_tools
def insert_config_version(server_id: int, user_id: int, service: str, local_path: str, remote_path: str, diff: str):
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
ConfigVersion.insert(

View File

@ -31,7 +31,7 @@ def alerts_history(service, user_group, **kwargs):
def insert_alerts(user_group, level, ip, port, message, service):
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
Alerts.insert(
@ -43,7 +43,7 @@ def insert_alerts(user_group, level, ip, port, message, service):
def delete_alert_history(keep_interval: int, service: str):
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=keep_interval)
query = Alerts.delete().where(
(Alerts.date < cur_date) & (Alerts.service == service)
@ -55,7 +55,7 @@ def delete_alert_history(keep_interval: int, service: str):
def insert_action_history(service: str, action: str, server_id: int, user_id: int, user_ip: str, server_ip: str, hostname: str):
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
ActionHistory.insert(
@ -82,7 +82,7 @@ def delete_action_history(server_id: int):
def delete_action_history_for_period():
time_period = get_setting('action_keep_history_range')
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=time_period)
query = ActionHistory.delete().where(ActionHistory.date < cur_date)
try:

View File

@ -1,12 +1,10 @@
from app.modules.db.db_model import connect, mysql_enable, Metrics, MetricsHttpStatus, Server, NginxMetrics, ApacheMetrics, WafMetrics
from app.modules.db.sql import get_setting
from app.modules.db.common import out_error
import app.modules.roxy_wi_tools as roxy_wi_tools
def insert_metrics(serv, curr_con, cur_ssl_con, sess_rate, max_sess_rate):
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
Metrics.insert(
@ -23,8 +21,7 @@ def insert_metrics(serv, curr_con, cur_ssl_con, sess_rate, max_sess_rate):
def insert_metrics_http(serv, http_2xx, http_3xx, http_4xx, http_5xx):
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
MetricsHttpStatus.insert(
@ -41,8 +38,7 @@ def insert_metrics_http(serv, http_2xx, http_3xx, http_4xx, http_5xx):
def insert_nginx_metrics(serv, connection):
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
NginxMetrics.insert(serv=serv, conn=connection, date=cur_date).execute()
@ -56,8 +52,7 @@ def insert_nginx_metrics(serv, connection):
def insert_apache_metrics(serv, connection):
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
ApacheMetrics.insert(serv=serv, conn=connection, date=cur_date).execute()
@ -71,8 +66,7 @@ def insert_apache_metrics(serv, connection):
def insert_waf_metrics(serv, connection):
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
WafMetrics.insert(serv=serv, conn=connection, date=cur_date).execute()
@ -86,8 +80,7 @@ def insert_waf_metrics(serv, connection):
def delete_waf_metrics():
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = WafMetrics.delete().where(WafMetrics.date < cur_date)
try:
@ -102,8 +95,7 @@ def delete_waf_metrics():
def delete_metrics():
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = Metrics.delete().where(Metrics.date < cur_date)
try:
@ -118,8 +110,7 @@ def delete_metrics():
def delete_http_metrics():
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = MetricsHttpStatus.delete().where(MetricsHttpStatus.date < cur_date)
try:
@ -134,8 +125,7 @@ def delete_http_metrics():
def delete_nginx_metrics():
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = NginxMetrics.delete().where(NginxMetrics.date < cur_date)
try:
@ -150,7 +140,7 @@ def delete_nginx_metrics():
def delete_apache_metrics():
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=3)
query = ApacheMetrics.delete().where(ApacheMetrics.date < cur_date)
try:

View File

@ -1,5 +1,4 @@
from app.modules.db.db_model import connect, fn, PortScannerPorts, PortScannerSettings, PortScannerHistory
from app.modules.db.sql import get_setting
from app.modules.db.common import out_error
import app.modules.roxy_wi_tools as roxy_wi_tools
@ -37,7 +36,7 @@ def select_port_scanner_settings_for_service():
def insert_port_scanner_port(serv, user_group_id, port, service_name):
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
PortScannerPorts.insert(
@ -83,7 +82,7 @@ def delete_ports(serv):
def insert_port_scanner_history(serv, port, port_status, service_name):
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
PortScannerHistory.insert(
@ -130,7 +129,7 @@ def select_count_opened_ports(serv):
def delete_portscanner_history(keep_interval: int):
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=keep_interval)
query = PortScannerHistory.delete().where(
PortScannerHistory.date < cur_date)

View File

@ -3,7 +3,6 @@ import uuid
from peewee import fn
from app.modules.db.db_model import SmonAgent, Server, SMON, SmonTcpCheck, SmonHttpCheck, SmonDnsCheck, SmonPingCheck, SmonHistory, SmonStatusPageCheck, SmonStatusPage
from app.modules.db.sql import get_setting
from app.modules.db.common import out_error
import app.modules.roxy_wi_tools as roxy_wi_tools
@ -187,7 +186,7 @@ def add_sec_to_state_time(time, smon_id):
def insert_smon_history(smon_id: int, resp_time: float, status: int, check_id: int, mes='') -> None:
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
try:
SmonHistory.insert(smon_id=smon_id, response_time=resp_time, status=status, date=cur_date, check_id=check_id, mes=mes).execute()
@ -645,7 +644,7 @@ def count_agents() -> int:
def delete_smon_history():
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta_minus=1)
query = SmonHistory.delete().where(SmonHistory.date < cur_date)
try:

View File

@ -2,7 +2,6 @@ from flask import request
from app.modules.db.db_model import GeoipCodes, Setting, Role
from app.modules.db.common import out_error
import app.modules.roxy_wi_tools as roxy_wi_tools
def get_setting(param, **kwargs):
@ -39,10 +38,6 @@ def get_setting(param, **kwargs):
return setting.value
time_zone = get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
def update_setting(param: str, val: str, user_group: int) -> bool:
query = Setting.update(value=val).where((Setting.param == param) & (Setting.group == user_group))
try:

View File

@ -256,7 +256,7 @@ def get_user_role_by_uuid(uuid, group_id):
def write_user_uuid(login, user_uuid):
session_ttl = get_setting('session_ttl')
user_id = get_user_id_by_username(login)
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta=session_ttl)
try:
@ -268,7 +268,7 @@ def write_user_uuid(login, user_uuid):
def write_user_token(login, user_token):
token_ttl = get_setting('token_ttl')
user_id = get_user_id_by_username(login)
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta=token_ttl)
try:
@ -368,7 +368,7 @@ def get_user_id_by_api_token(token):
def write_api_token(user_token, group_id, user_role, user_name):
token_ttl = int(get_setting('token_ttl'))
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular', timedelta=token_ttl)
cur_date_token_ttl = get_date.return_date('regular', timedelta=token_ttl)
@ -404,7 +404,7 @@ def get_token(uuid):
def delete_old_uuid():
get_date = roxy_wi_tools.GetDate(get_setting('time_zone'))
get_date = roxy_wi_tools.GetDate()
cur_date = get_date.return_date('regular')
query = UUID.delete().where((UUID.exp < cur_date) | (UUID.exp.is_null(True)))
query1 = Token.delete().where((Token.exp < cur_date) | (Token.exp.is_null(True)))

View File

@ -22,14 +22,14 @@ class GetConfigVar:
class GetDate:
def __init__(self, time_zone):
def __init__(self, time_zone=None):
self.time_zone = time_zone
self.fmt = "%Y-%m-%d.%H:%M:%S"
def return_date(self, log_type, **kwargs):
try:
if self.time_zone:
cur_time_zone = timezone(self.time_zone)
except Exception:
else:
cur_time_zone = timezone('UTC')
if kwargs.get('timedelta'):

View File

@ -1,6 +1,7 @@
import psutil
import app.modules.db.metric as metric_sql
import app.modules.common.common as common
import app.modules.server.server as server_mod
@ -66,8 +67,9 @@ def haproxy_metrics(server_ip: str, hostname: str, time_range: str) -> dict:
server = ''
for i in metric:
label = str(i[5])
label = label.split(' ')[1]
label = i[5]
metric_time = common.get_time_zoned_date(label, '%H:%M:%S')
label = metric_time
labels += label + ','
curr_con += str(i[1]) + ','
curr_ssl_con += str(i[2]) + ','
@ -95,8 +97,9 @@ def haproxy_http_metrics(server_ip: str, hostname: str, time_range: str) -> dict
server = ''
for i in metric:
label = str(i[5])
label = label.split(' ')[1]
label = i[5]
metric_time = common.get_time_zoned_date(label, '%H:%M:%S')
label = metric_time
labels += label + ','
http_2xx += str(i[1]) + ','
http_3xx += str(i[2]) + ','
@ -123,8 +126,9 @@ def service_metrics(server_ip: str, hostname: str, service: str, time_range: str
curr_con = ''
for i in metric:
label = str(i[2])
label = label.split(' ')[1]
label = i[2]
metric_time = common.get_time_zoned_date(label, '%H:%M:%S')
label = metric_time
labels += label + ','
curr_con += str(i[1]) + ','

View File

@ -1,7 +1,10 @@
import json
import whois
from flask import Response, stream_with_context
import app.modules.server.ssh as mod_ssh
import modules.server.server as server_mod
import app.modules.server.server as server_mod
def ping_from_server(server_from: str, server_to: str, action: str) -> Response:
@ -106,3 +109,24 @@ def nslookup_from_server(server_from: str, dns_name: str, record_type: str) -> s
count_string += 1
return output1
def whois_check(domain_name: str) -> str:
try:
whois_data = json.loads(str(whois.whois(domain_name)))
except Exception as e:
return f'error: Cannot get whois from {domain_name}: {e}'
output = (f'<b>Domain name:</b> {whois_data["domain_name"]}<br />'
f'<b>Registrar:</b> {whois_data["registrar"]} <br />'
f'<b>Creation date:</b> {whois_data["creation_date"]} <br />'
f'<b>Expiration date:</b> {whois_data["expiration_date"]} <br />'
f'<b>Name servers:</b> {whois_data["name_servers"]} <br />'
f'<b>Status:</b> {whois_data["status"]} <br />')
if 'emails' in whois_data:
output += f'<b>Emails:</b> {whois_data["emails"]} <br />'
if 'org' in whois_data:
output += f'<b>Organization:</b> {whois_data["org"]} <br />'
return output

View File

@ -7,7 +7,6 @@ import ansible
import ansible_runner
import app.modules.db.sql as sql
import app.modules.db.waf as waf_sql
import app.modules.db.ha_cluster as ha_sql
import app.modules.db.server as server_sql
import app.modules.db.service as service_sql
@ -41,82 +40,6 @@ def show_success_installation(service):
return render_template('include/show_success_installation.html', service=service, lang=lang)
def waf_install(server_ip: str):
script = "waf.sh"
proxy = sql.get_setting('proxy')
haproxy_dir = sql.get_setting('haproxy_dir')
ver = service_common.check_haproxy_version(server_ip)
service = ' WAF'
proxy_serv = ''
ssh_settings = return_ssh_keys_path(server_ip)
full_path = '/var/www/haproxy-wi/app'
os.system(f"cp {full_path}/scripts/{script} {full_path}/{script}")
if proxy is not None and proxy != '' and proxy != 'None':
proxy_serv = proxy
commands = [
f"chmod +x {full_path}/{script} && {full_path}/{script} PROXY={proxy_serv} HAPROXY_PATH={haproxy_dir} VERSION='{ver}' "
f"SSH_PORT={ssh_settings['port']} HOST={server_ip} USER={ssh_settings['user']} PASS='{ssh_settings['password']}' "
f"KEY={ssh_settings['key']}"
]
return_out = server_mod.subprocess_execute_with_rc(commands[0])
try:
show_installation_output(return_out['error'], return_out['output'], service, rc=return_out['rc'])
except Exception as e:
raise Exception(e)
try:
waf_sql.insert_waf_metrics_enable(server_ip, "0")
waf_sql.insert_waf_rules(server_ip)
except Exception as e:
return str(e)
os.remove(f'{full_path}/{script}')
return show_success_installation(service)
def waf_nginx_install(server_ip: str):
script = "waf_nginx.sh"
proxy = sql.get_setting('proxy')
nginx_dir = sql.get_setting('nginx_dir')
service = ' WAF'
proxy_serv = ''
ssh_settings = return_ssh_keys_path(server_ip)
full_path = '/var/www/haproxy-wi/app'
os.system(f"cp {full_path}/scripts/{script} {full_path}/{script}")
if proxy is not None and proxy != '' and proxy != 'None':
proxy_serv = proxy
commands = [
f"chmod +x {full_path}/{script} && {full_path}/{script} PROXY={proxy_serv} NGINX_PATH={nginx_dir} SSH_PORT={ssh_settings['port']} "
f"HOST={server_ip} USER={ssh_settings['user']} PASS='{ssh_settings['password']}' KEY={ssh_settings['key']}"
]
return_out = server_mod.subprocess_execute_with_rc(commands[0])
try:
show_installation_output(return_out['error'], return_out['output'], service, rc=return_out['rc'])
except Exception as e:
raise Exception(e)
try:
waf_sql.insert_nginx_waf_rules(server_ip)
waf_sql.insert_waf_nginx_server(server_ip)
except Exception as e:
return str(e)
os.remove(f'{full_path}/{script}')
return show_success_installation(service)
def geoip_installation(serv, geoip_update, service):
proxy = sql.get_setting('proxy')
maxmind_key = sql.get_setting('maxmind_key')
@ -189,7 +112,7 @@ def grafana_install():
return f'success: Grafana and Prometheus servers were installed. You can find Grafana on http://{host}:3000<br>'
def generate_kp_inv(json_data: json, install_service) -> object:
def generate_kp_inv(json_data: json, installed_service) -> object:
inv = {"server": {"hosts": {}}}
server_ips = []
cluster_id = int(json_data['cluster_id'])
@ -229,7 +152,23 @@ def generate_kp_inv(json_data: json, install_service) -> object:
return inv, server_ips
def generate_haproxy_inv(json_data: json, install_service: str) -> object:
def generate_waf_inv(server_ip: str, installed_service: str) -> object:
inv = {"server": {"hosts": {}}}
server_ips = []
if installed_service == "waf":
service_dir = sql.get_setting('haproxy_dir')
else:
service_dir = sql.get_setting('nginx_dir')
inv['server']['hosts'][server_ip] = {
'SERVICE_PATH': service_dir
}
server_ips.append(server_ip)
return inv, server_ips
def generate_haproxy_inv(json_data: json, installed_service: str) -> object:
inv = {"server": {"hosts": {}}}
slaves = []
server_ips = []
@ -280,24 +219,24 @@ def generate_haproxy_inv(json_data: json, install_service: str) -> object:
return inv, server_ips
def generate_service_inv(json_data: json, install_service: str) -> object:
def generate_service_inv(json_data: json, installed_service: str) -> object:
inv = {"server": {"hosts": {}}}
server_ips = []
stats_user = sql.get_setting(f'{install_service}_stats_user')
stats_password = sql.get_setting(f'{install_service}_stats_password')
stats_port = str(sql.get_setting(f'{install_service}_stats_port'))
stats_page = sql.get_setting(f'{install_service}_stats_page')
config_path = sql.get_setting(f'{install_service}_config_path')
service_dir = sql.get_setting(f'{install_service}_dir')
container_name = sql.get_setting(f'{install_service}_container_name')
is_docker = json_data['services'][install_service]['docker']
stats_user = sql.get_setting(f'{installed_service}_stats_user')
stats_password = sql.get_setting(f'{installed_service}_stats_password')
stats_port = str(sql.get_setting(f'{installed_service}_stats_port'))
stats_page = sql.get_setting(f'{installed_service}_stats_page')
config_path = sql.get_setting(f'{installed_service}_config_path')
service_dir = sql.get_setting(f'{installed_service}_dir')
container_name = sql.get_setting(f'{installed_service}_container_name')
is_docker = json_data['services'][installed_service]['docker']
if install_service == 'nginx' and not os.path.isdir('/var/www/haproxy-wi/app/scripts/ansible/roles/nginxinc.nginx'):
if installed_service == 'nginx' and not os.path.isdir('/var/www/haproxy-wi/app/scripts/ansible/roles/nginxinc.nginx'):
os.system('ansible-galaxy install nginxinc.nginx,0.23.2 --roles-path /var/www/haproxy-wi/app/scripts/ansible/roles/')
for k, v in json_data['servers'].items():
server_ip = v['ip']
if install_service == 'apache':
if installed_service == 'apache':
correct_service_name = service_common.get_correct_apache_service_name(server_ip=server_ip, server_id=None)
if service_dir == '/etc/httpd' and correct_service_name == 'apache2':
service_dir = '/etc/apache2'
@ -314,7 +253,7 @@ def generate_service_inv(json_data: json, install_service: str) -> object:
"SYN_FLOOD": "0",
"CONFIG_PATH": config_path,
"STAT_PAGE": stats_page,
"service": install_service,
"service": installed_service,
}
server_ips.append(server_ip)

View File

@ -197,7 +197,8 @@ def history_metrics(server_id: int) -> dict:
curr_con = ''
for i in reversed(metric):
labels += f'{i.date.time()},'
metric_time = common.get_time_zoned_date(i.date, '%H:%M:%S')
labels += f'{metric_time},'
curr_con += f'{i.response_time},'
metrics['chartData']['labels'] = labels

View File

@ -15,8 +15,6 @@ import app.modules.roxy_wi_tools as roxy_wi_tools
import app.modules.server.server as server_mod
get_config = roxy_wi_tools.GetConfigVar()
time_zone = sql.get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
@bp.before_request

View File

@ -8,7 +8,7 @@ import app.modules.db.sql as sql
import app.modules.db.config as config_sql
import app.modules.db.server as server_sql
import app.modules.db.service as service_sql
from middleware import check_services, get_user_params
from app.middleware import check_services, get_user_params
import app.modules.common.common as common
import app.modules.roxywi.auth as roxywi_auth
import app.modules.roxywi.common as roxywi_common

View File

@ -2,8 +2,9 @@ from flask import render_template, request, g
from flask_login import login_required
from app.routes.install import bp
from middleware import get_user_params, check_services
from app.middleware import get_user_params, check_services
import app.modules.db.sql as sql
import app.modules.db.waf as waf_sql
import app.modules.common.common as common
import app.modules.roxywi.auth as roxywi_auth
import app.modules.server.server as server_mod
@ -87,17 +88,31 @@ def install_waf(service, server_ip):
if service == 'haproxy':
try:
return service_mod.waf_install(server_ip)
inv, server_ips = service_mod.generate_waf_inv(server_ip, 'waf')
ansible_status = service_mod.run_ansible(inv, server_ips, 'waf'), 201
except Exception as e:
return str(e)
try:
waf_sql.insert_waf_metrics_enable(server_ip, "0")
waf_sql.insert_waf_rules(server_ip)
except Exception as e:
return str(e)
elif service == 'nginx':
try:
return service_mod.waf_nginx_install(server_ip)
inv, server_ips = service_mod.generate_waf_inv(server_ip, 'waf_nginx')
ansible_status = service_mod.run_ansible(inv, server_ips, 'waf_nginx'), 201
except Exception as e:
return str(e)
try:
waf_sql.insert_nginx_waf_rules(server_ip)
waf_sql.insert_waf_nginx_server(server_ip)
except Exception as e:
return str(e)
else:
return 'error: Wrong service'
return ansible_status
@bp.post('/geoip')
def install_geoip():

View File

@ -2,7 +2,7 @@ import os
import sys
import pytz
from flask import render_template, request, session, g, abort
from flask import render_template, request, session, g, abort, jsonify
from flask_login import login_required
sys.path.append(os.path.join(sys.path[0], '/var/www/haproxy-wi/app'))
@ -26,6 +26,11 @@ import app.modules.service.common as service_common
import app.modules.service.haproxy as service_haproxy
@app.template_filter('strftime')
def _jinja2_filter_datetime(date, fmt=None):
return common.get_time_zoned_date(date, fmt)
@app.errorhandler(403)
@get_user_params()
def page_is_forbidden(e):
@ -110,9 +115,9 @@ def nettools():
return render_template('nettools.html', lang=g.user_params['lang'])
@bp.post('/nettols/<check>')
@bp.post('/nettools/<check>')
@login_required
def nettols_check(check):
def nettools_check(check):
server_from = common.checkAjaxInput(request.form.get('server_from'))
server_to = common.is_ip_or_dns(request.form.get('server_to'))
action = common.checkAjaxInput(request.form.get('nettools_action'))
@ -120,6 +125,7 @@ def nettols_check(check):
dns_name = common.checkAjaxInput(request.form.get('nettools_nslookup_name'))
dns_name = common.is_ip_or_dns(dns_name)
record_type = common.checkAjaxInput(request.form.get('nettools_nslookup_record_type'))
domain_name = common.is_ip_or_dns(request.form.get('nettools_whois_name'))
if check == 'icmp':
return nettools_mod.ping_from_server(server_from, server_to, action)
@ -127,6 +133,8 @@ def nettols_check(check):
return nettools_mod.telnet_from_server(server_from, server_to, port_to)
elif check == 'dns':
return nettools_mod.nslookup_from_server(server_from, dns_name, record_type)
elif check == 'whois':
return jsonify(nettools_mod.whois_check(domain_name))
else:
return 'error: Wrong check'

View File

@ -15,8 +15,6 @@ import app.modules.roxywi.common as roxywi_common
import app.modules.config.config as config_mod
get_config = roxy_wi_tools.GetConfigVar()
time_zone = sql.get_setting('time_zone')
get_date = roxy_wi_tools.GetDate(time_zone)
@bp.before_request

View File

@ -1,6 +1,6 @@
---
- name: Install WAF
hosts: "{{ variable_host }}"
hosts: all
become: yes
become_method: sudo
gather_facts: yes

View File

@ -1,13 +1,9 @@
---
- name: Installing WAF
block:
- name: Set SSH port
set_fact:
ansible_port: "{{SSH_PORT}}"
- name: Check that WAF has been installed
stat:
path: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
path: "{{ SERVICE_PATH }}/waf/modsecurity.conf"
register: stat_result
- name: Fail if has been installed
@ -179,7 +175,7 @@
- name: Make WAF rules directory
file:
path: "{{ HAPROXY_PATH }}/waf/{{ item }}"
path: "{{ SERVICE_PATH }}/waf/{{ item }}"
state: directory
with_items:
- rules
@ -188,59 +184,59 @@
- name: Copy Modsec module to HAProxy dir
copy:
src: "{{ mod_sec_dir }}/modsecurity"
dest: "{{ HAPROXY_PATH }}/waf/bin"
dest: "{{ SERVICE_PATH }}/waf/bin"
mode: '0744'
remote_src: true
- name: Download modsecurity conf
get_url:
url: https://github.com/SpiderLabs/ModSecurity/raw/v2/master/modsecurity.conf-recommended
dest: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
dest: "{{ SERVICE_PATH }}/waf/modsecurity.conf"
- name: Insert Modsec rules
blockinfile:
path: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
path: "{{ SERVICE_PATH }}/waf/modsecurity.conf"
block: |
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_10_ignore_static.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_10_setup.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_11_avs_traffic.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_11_brute_force.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_11_dos_protection.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_13_xml_enabler.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_16_authentication_tracking.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_16_scanner_integration.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_16_username_tracking.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_20_protocol_violations.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_21_protocol_anomalies.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_23_request_limits.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_25_cc_known.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_25_cc_track_pan.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_30_http_policy.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_35_bad_robots.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_40_generic_attacks.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_40_http_parameter_pollution.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_41_sql_injection_attacks.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_41_xss_attacks.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_42_comment_spam.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_42_tight_security.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_45_trojans.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_av_scanning.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_scanner_integration.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_slr_et_xss_attacks.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_slr_et_lfi_attacks.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_46_slr_et_sqli_attacks.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_47_common_exceptions.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_49_inbound_blocking.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_50_outbound.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_55_marketing.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_56_pvi_checks.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_59_outbound_blocking.conf
Include {{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_60_correlation.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_10_ignore_static.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_10_setup.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_11_avs_traffic.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_11_brute_force.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_11_dos_protection.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_13_xml_enabler.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_16_authentication_tracking.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_16_scanner_integration.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_16_username_tracking.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_20_protocol_violations.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_21_protocol_anomalies.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_23_request_limits.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_25_cc_known.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_25_cc_track_pan.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_30_http_policy.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_35_bad_robots.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_40_generic_attacks.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_40_http_parameter_pollution.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_41_sql_injection_attacks.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_41_xss_attacks.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_42_comment_spam.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_42_tight_security.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_45_trojans.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_46_av_scanning.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_46_scanner_integration.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_46_slr_et_xss_attacks.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_46_slr_et_lfi_attacks.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_46_slr_et_sqli_attacks.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_47_common_exceptions.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_49_inbound_blocking.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_50_outbound.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_55_marketing.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_56_pvi_checks.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_59_outbound_blocking.conf
Include {{ SERVICE_PATH }}/waf/rules/modsecurity_crs_60_correlation.conf
- name: Download unicode.mapping
get_url:
url: https://github.com/SpiderLabs/ModSecurity/raw/v2/master/unicode.mapping
dest: "{{ HAPROXY_PATH }}/waf/unicode.mapping"
dest: "{{ SERVICE_PATH }}/waf/unicode.mapping"
- name: Download owasp-modsecurity-crs
get_url:
@ -263,7 +259,7 @@
- name: Copy owasp files
copy:
src: "/tmp/owasp-modsecurity-crs-2.2.9/owasp-modsecurity-crs-2.2.9/{{ item }}"
dest: "{{ HAPROXY_PATH }}/waf/rules"
dest: "{{ SERVICE_PATH }}/waf/rules"
remote_src: yes
with_items:
- base_rules/
@ -274,25 +270,25 @@
- name: Copy Modsec crs conf file
copy:
src: /tmp/owasp-modsecurity-crs-2.2.9/owasp-modsecurity-crs-2.2.9/modsecurity_crs_10_setup.conf.example
dest: "{{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_10_setup.conf"
dest: "{{ SERVICE_PATH }}/waf/rules/modsecurity_crs_10_setup.conf"
remote_src: true
- name: Ensure ModSec engine mode on
ansible.builtin.lineinfile:
path: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
path: "{{ SERVICE_PATH }}/waf/modsecurity.conf"
regexp: '^SecRuleEngine DetectionOnly'
line: SecRuleEngine On
- name: Change ModSec audit log
ansible.builtin.lineinfile:
path: "{{ HAPROXY_PATH }}/waf/modsecurity.conf"
path: "{{ SERVICE_PATH }}/waf/modsecurity.conf"
regexp: '^SecAuditLogParts ABIJDEFHZ'
line: SecAuditLogParts ABIJDEH
- name: Create modsecurity_crs_10_setup
template:
src: modsecurity_crs_10_setup.conf.j2
dest: "{{ HAPROXY_PATH }}/waf/rules/modsecurity_crs_10_setup.conf"
dest: "{{ SERVICE_PATH }}/waf/rules/modsecurity_crs_10_setup.conf"
- name: Create WAF service file
template:
@ -310,12 +306,12 @@
- name: Create WAF conf file
template:
src: waf.conf.j2
dest: "{{ HAPROXY_PATH }}/waf.conf"
dest: "{{ SERVICE_PATH }}/waf.conf"
mode: 0644
- name: Insert Modsec backend
blockinfile:
path: "{{ HAPROXY_PATH }}/haproxy.cfg"
path: "{{ SERVICE_PATH }}/haproxy.cfg"
block: |
backend waf
mode tcp
@ -342,7 +338,6 @@
with_items:
- /tmp/modsecurity.tar.gz
- "{{ mod_sec_dir }}"
- "/tmp/haproxy-{{ VERSION }}"
- /tmp/owasp.tar.gz
- /tmp/owasp-modsecurity-crs-2.2.9
- /tmp/spoa-modsecurity

View File

@ -1,6 +1,6 @@
---
- name: Install WAF
hosts: "{{ variable_host }}"
hosts: all
become: yes
become_method: sudo
gather_facts: yes

View File

@ -1,13 +1,9 @@
---
- name: Installing WAF
block:
- name: Set SSH port
set_fact:
ansible_port: "{{SSH_PORT}}"
- name: Check that WAF has been installed
stat:
path: "{{ NGINX_PATH }}/waf/modsecurity.conf"
path: "{{ SERVICE_PATH }}/waf/modsecurity.conf"
register: stat_result
- name: Fail if has been installed
@ -149,7 +145,7 @@
- name: Enable module for Ubuntu
lineinfile:
path: "{{ NGINX_PATH }}/nginx.conf"
path: "{{ SERVICE_PATH }}/nginx.conf"
line: load_module modules/ngx_http_modsecurity_module.so;
insertbefore: BOF
when: ansible_facts['os_family'] == 'Debian' or ansible_facts['os_family'] == 'Ubuntu'
@ -157,29 +153,29 @@
- name: Create WAF directory
become: false
file:
path: "{{ NGINX_PATH }}/waf/"
path: "{{ SERVICE_PATH }}/waf/"
state: directory
- name: Create WAF rules directory
become: false
file:
path: "{{ NGINX_PATH }}/waf/rules"
path: "{{ SERVICE_PATH }}/waf/rules"
state: directory
- name: Download modsecurity.conf
ansible.builtin.get_url:
url: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
dest: "{{ NGINX_PATH }}/waf/modsecurity.conf"
dest: "{{ SERVICE_PATH }}/waf/modsecurity.conf"
- name: Download unicode.mapping
ansible.builtin.get_url:
url: https://github.com/SpiderLabs/ModSecurity/blob/v3/master/unicode.mapping
dest: "{{ NGINX_PATH }}/waf/unicode.mapping"
dest: "{{ SERVICE_PATH }}/waf/unicode.mapping"
- name: Create WAF config
template:
src: waf.conf.j2
dest: "{{ NGINX_PATH }}/waf/waf.conf"
dest: "{{ SERVICE_PATH }}/waf/waf.conf"
- name: Download OWASP rules
ansible.builtin.get_url:
@ -196,16 +192,16 @@
- name: Copy Modsec crs activated_rules files
copy:
src: "/tmp/coreruleset-{{ coreruleset_ver }}/rules/"
dest: "{{ NGINX_PATH }}/waf/rules/"
dest: "{{ SERVICE_PATH }}/waf/rules/"
remote_src: yes
- name: Copy module
become: true
command: "chdir=/tmp/coreruleset-{{ coreruleset_ver }} cp crs-setup.conf.example {{ NGINX_PATH }}/waf/rulescrs-setup.conf"
command: "chdir=/tmp/coreruleset-{{ coreruleset_ver }} cp crs-setup.conf.example {{ SERVICE_PATH }}/waf/rulescrs-setup.conf"
- name: Add waf Mod on
ansible.builtin.blockinfile:
path: "{{ NGINX_PATH }}/nginx.conf"
path: "{{ SERVICE_PATH }}/nginx.conf"
marker: "#-- {mark} WAF BLOCK --#"
insertafter: "http {"
block: |

View File

@ -1,50 +0,0 @@
#!/bin/bash
for ARGUMENT in "$@"
do
KEY=$(echo "$ARGUMENT" | cut -f1 -d=)
VALUE=$(echo "$ARGUMENT" | cut -f2 -d=)
case "$KEY" in
PROXY) PROXY=${VALUE} ;;
VERSION) VERSION=${VALUE} ;;
HAPROXY_PATH) HAPROXY_PATH=${VALUE} ;;
HOST) HOST=${VALUE} ;;
USER) USER=${VALUE} ;;
PASS) PASS=${VALUE} ;;
KEY) KEY=${VALUE} ;;
SSH_PORT) SSH_PORT=${VALUE} ;;
*)
esac
done
VERSION=$(echo "$VERSION"| awk -F"-" '{print $1}')
VERSION_MAJ=$(echo "$VERSION" | awk -F"." '{print $1"."$2}')
if (( $(awk 'BEGIN {print ("'$VERSION_MAJ'" < "'1.8'")}') )); then
echo 'error: Need HAProxy version 1.8 or later'
exit 1
fi
export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False
export ACTION_WARNINGS=False
export LOCALHOST_WARNING=False
export COMMAND_WARNINGS=False
PWD=/var/www/haproxy-wi/app/scripts/ansible/
echo "$HOST ansible_port=$SSH_PORT" > $PWD/$HOST
if [[ $KEY == "" ]]; then
ansible-playbook $PWD/roles/waf.yml -e "ansible_user=$USER ansible_ssh_pass='$PASS' variable_host=$HOST PROXY=$PROXY HAPROXY_PATH=$HAPROXY_PATH VERSION=$VERSION VERSION_MAJ=$VERSION_MAJ SSH_PORT=$SSH_PORT" -i $PWD/$HOST
else
ansible-playbook $PWD/roles/waf.yml --key-file $KEY -e "ansible_user=$USER variable_host=$HOST PROXY=$PROXY HAPROXY_PATH=$HAPROXY_PATH VERSION=$VERSION VERSION_MAJ=$VERSION_MAJ SSH_PORT=$SSH_PORT" -i $PWD/$HOST
fi
if [ $? -gt 0 ]
then
echo "error: Cannot install WAF"
exit 1
else
echo "success"
fi
rm -f $PWD/$HOST

View File

@ -1,43 +0,0 @@
#!/bin/bash
for ARGUMENT in "$@"
do
KEY=$(echo "$ARGUMENT" | cut -f1 -d=)
VALUE=$(echo "$ARGUMENT" | cut -f2 -d=)
case "$KEY" in
PROXY) PROXY=${VALUE} ;;
NGINX_PATH) NGINX_PATH=${VALUE} ;;
HOST) HOST=${VALUE} ;;
USER) USER=${VALUE} ;;
PASS) PASS=${VALUE} ;;
KEY) KEY=${VALUE} ;;
SSH_PORT) SSH_PORT=${VALUE} ;;
*)
esac
done
export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False
export ACTION_WARNINGS=False
export LOCALHOST_WARNING=False
export COMMAND_WARNINGS=False
PWD=/var/www/haproxy-wi/app/scripts/ansible/
echo "$HOST ansible_port=$SSH_PORT" > $PWD/$HOST
if [[ $KEY == "" ]]; then
ansible-playbook $PWD/roles/waf_nginx.yml -e "ansible_user=$USER ansible_ssh_pass='$PASS' variable_host=$HOST PROXY=$PROXY NGINX_PATH=$NGINX_PATH SSH_PORT=$SSH_PORT" -i $PWD/$HOST
else
ansible-playbook $PWD/roles/waf_nginx.yml --key-file $KEY -e "ansible_user=$USER variable_host=$HOST PROXY=$PROXY NGINX_PATH=$NGINX_PATH SSH_PORT=$SSH_PORT" -i $PWD/$HOST
fi
if [ $? -gt 0 ]
then
echo "error: Cannot install WAF"
exit 1
else
echo "success"
fi
rm -f $PWD/$HOST

View File

@ -109,6 +109,11 @@ pre {
font-size: 12px;
z-index: 99;
}
.menu-active {
padding-left: 30px;
background-color: var(--right-menu-blue-rolor) !important;
border-left: 4px solid var(--right-menu-blue-rolor);
}
.logoText {
color: #EBF1F1;
font-size: 25px;

View File

@ -335,6 +335,16 @@ function cloneBackup(id) {
$('#backup-credentials').val($('#backup-credentials-'+id+' option:selected').val()).change()
$('#backup-credentials').selectmenu("refresh");
}
function cloneS3Backup(id) {
$( "#add-backup-s3-button" ).trigger( "click" );
$('#s3_server').val($('#s3-server-'+id).text())
$('#s3_bucket').val($('#bucket-'+id).text())
$('#s3-backup-description').val($('#s3-backup-description--'+id).text())
$('#s3-backup-server').val($('#backup-s3-server-'+id).text()).change();
$('#s3-backup-server').selectmenu("refresh");
$('#s3-backup-time').val($('#s3-backup-time-'+id).text()).change();
$('#s3-backup-time').selectmenu("refresh");
}
function removeBackup(id) {
$("#backup-table-" + id).css("background-color", "#f2dede");
$.ajax({

View File

@ -143,4 +143,33 @@ $( function() {
});
event.preventDefault();
});
$("#nettools_whois_form").on("click", ":submit", function (e) {
$('#ajax-nettools').html('');
var frm = $('#nettools_whois_form');
if ($('#nettools_whois_name').val() == '') {
toastr.warning('Enter a Domain name');
return false;
}
$.ajax({
url: frm.attr('action'),
data: frm.serialize() + "&nettools_action=" + $(this).val(),
type: frm.attr('method'),
dataType: 'text',
success: function (data) {
data = data.replaceAll('"', '');
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1' || data.indexOf('Error(s)') != '-1') {
toastr.clear();
toastr.error(data);
} else if (data.indexOf('warning: ') != '-1') {
toastr.clear();
toastr.warning(data)
} else {
toastr.clear();
console.log(data)
$('#ajax-nettools').html('<div class="ping_pre">' + data + '</div>');
}
}
});
event.preventDefault();
});
});

View File

@ -41,7 +41,7 @@
<tbody>
{% if smon != '' %}
{% for t in smon %}
{% set date_time = t.4|string %}
{# {% set date_time = t.4|string %}#}
<tr>
<td class="padding10" style="width: 10%; padding: 7px 7px 7px 10px;">
{% if t.1 == 'info' %}
@ -64,9 +64,9 @@
<td>{{t.3}}</td>
{% endif %}
<td>{{t.0}}</td>
<td>{{date_time.split(' ')[0]}}
<td>{{t.4|strftime('%Y %m %d')}}
</td>
<td>{{date_time.split(' ')[1]}}</td>
<td>{{t.4|strftime('%H:%M:%S')}}</td>
</tr>
{% endfor %}
{% else %}

View File

@ -22,7 +22,6 @@
{% set is_service_stopped_title = lang.words.stop|title()+" "+lang.words.and+" "+lang.words.disable+" "+services_name[service.0]['name']+" "+lang.words.service %}
<tr class="{{ loop.cycle('odd', 'even') }}" id="{{service.0}}">
<td class="padding10 first-collumn">
{{ service }}
{% if service.1 == 'active' or service.1 == 'RUNNING' %}
<span title="{{lang.words.service|title()}} {{services_name[service.0]['name']}} {{lang.words.started}}"><span class="serverUp server-status"></span></span>
{% set is_service_started_class = 'disabled-button' %}

View File

@ -101,7 +101,7 @@
</div>
{% endif %}
</td>
<td>{{c.date}}</td>
<td>{{c.date|strftime}}</td>
<td style="padding-top: 10px;">
<a href="/app/config/versions/{{service}}/{{server_ip}}/{{c.local_path.split('/')[-1]}}"
class="ui-button ui-widget ui-corner-all" title="{{lang1.phrases.view_and_upload}}" style="margin-top: -6px;">

View File

@ -5,10 +5,10 @@
{% if s.smon_id.en == 1 %}
{% if s.smon_id.status == 1 and s.smon_id.body_status == 1 %}
{% set additional_classes = 'good div-server-head-up' %}
{% set uptime_desc = lang.words.uptime + ': <time class="timeago" datetime='+s.smon_id.time_state|string()+'>'+s.smon_id.time_state|string()+'</time>' %}
{% set uptime_desc = lang.words.uptime + ': <time class="timeago" datetime="'+s.smon_id.time_state|string()+'">'+s.smon_id.time_state|string()+'</time>' %}
{% elif s.smon_id.status == 0 or s.smon_id.body_status == 0 %}
{% set additional_classes = 'err div-server-head-down' %}
{% set uptime_desc = lang.words.downtime + ': <time class="timeago" datetime='+s.smon_id.time_state|string()+'>'+s.smon_id.time_state|string()+'</time>' %}
{% set uptime_desc = lang.words.downtime + ': <time class="timeago" datetime="'+s.smon_id.time_state|string()+'">'+s.smon_id.time_state|string()+'</time>' %}
{% else %}
{% set additional_classes = 'err div-server-head-unknown' %}
{% set uptime_desc = lang.words.uptime + ': N/A' %}

View File

@ -5,5 +5,5 @@
{% else %}
{% set add_class = 'serverDown' %}
{% endif %}
<div class="smon_server_statuses {{add_class}}" title="" data-help="{{s.date}} {{s.mes}}" style=""></div>
<div class="smon_server_statuses {{add_class}}" title="" data-help="{{s.date|strftime}} {{s.mes}}" style=""></div>
{% endfor %}

View File

@ -89,7 +89,7 @@
<div class="footer-div">
<div id="useful-links">
<a href="https://roxy-wi.org" class="footer-link" target="_blank" title="{{lang.words.about|title()}} Roxy-WI">{{lang.words.about|title()}}</a>
<a href="https://github.com/hap-wi/roxy-wi/issues" class="footer-link" target="_blank" title="Community help">{{lang.words.help|title()}}</a>
<a href="https://github.com/roxy-wi/roxy-wi/issues" class="footer-link" target="_blank" title="Community help">{{lang.words.help|title()}}</a>
<a href="https://sd.roxy-wi.org" class="footer-link" target="_blank" title="Service Desk">SD</a>
<a href="https://roxy-wi.org/contacts" class="footer-link" target="_blank">{{lang.words.contacts|title()}}</a>
<a href="https://roxy-wi.org/cabinet" class="footer-link" target="_blank" title="Private cabinet">{{lang.words.cabinet|title()}}</a>

View File

@ -21,7 +21,7 @@
dom: 'Blfrtip',
colReorder: true,
"pageLength": 25,
"order": [ 4, "desc" ],
"order": [ 5, "desc" ],
stateSave: true,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
"columnDefs": [
@ -47,6 +47,7 @@
<th style="width: 100px">{%if service == 'cluster' %}{{lang.words.cluster|title()}} {%else%}{{lang.words.server|title()}}{% endif %}</th>
<th>{{lang.words.action|title()}}</th>
<th>{{lang.words.date|title()}}</th>
<th>{{lang.words.time|title()}}</th>
</tr>
</thead>
<tbody>
@ -71,7 +72,8 @@
{% endif %}
</td>
<td>{{h.action}}</td>
<td>{{h.date}}</td>
<td>{{h.date|strftime('%Y %m %d')}}</td>
<td>{{h.date|strftime('%H:%M:%S')}}</td>
</tr>
{% endfor %}
</tbody>

View File

@ -126,7 +126,7 @@
<td style="width: 15%">{{lang.words.period|title()}}</td>
<td style="width: 100%">{{lang.words.desc|title()}}</td>
<td style="margin-left: 5px;"></td>
<!-- <td></td>-->
<td></td>
</tr>
</thead>
<tbody id="tbody-s3">
@ -154,11 +154,11 @@
<span id="s3-backup-description-{{b.id}}"></span>
{% endif %}
</td>
<!-- <td>-->
<!-- <a class="add" onclick="cloneS3Backup({{b.id}})" id="clone-s3-backup{{b.id}}" title="Clone S3 {{b.server}}" style="cursor: pointer;"></a>-->
<!-- </td>-->
<td>
<a class="delete" onclick="confirmDeleteS3Backup({{b.id}})" title="Delete S3 backup {{b.server}}" style="cursor: pointer;"></a>
<a class="add" onclick="cloneS3Backup({{b.id}})" id="clone-s3-backup{{b.id}}" title="{{lang.words.clone|title()}} S3 {{b.server}}" style="cursor: pointer;"></a>
</td>
<td>
<a class="delete" onclick="confirmDeleteS3Backup({{b.id}})" title="{{lang.words.delete|title()}} S3 {{lang.words.backup}} {{b.server}}" style="cursor: pointer;"></a>
</td>
</tr>
{% endif %}

View File

@ -9,11 +9,11 @@
<div id="top-link" class="top-link">
<nav id="menu">
<ul class="menu">
<li><a href="{{ url_for('overview.index') }}" title="{{lang.menu_links.overview.title}}" class="overview-link ">{{lang.menu_links.overview.link}}</a></li>
<li><a href="{{ url_for('overview.index') }}" title="{{lang.menu_links.overview.title}}" class="overview-link {% if request.url_rule.endpoint == 'overview.index' %} menu-active{% endif %}">{{lang.menu_links.overview.link}}</a></li>
{% if '5' in g.user_params['user_services'] %}
{% if g.user_params['role'] <= 3 %}
{% endif %}
<li><a href="{{ url_for('ha.cluster_function', service='cluster') }}" title="{{lang.menu_links.ha.title}}" class="keepalived">HA {{lang.words.cluster}}</a></li>
<li><a href="{{ url_for('ha.cluster_function', service='cluster') }}" title="{{lang.menu_links.ha.title}}" class="keepalived {% if request.url_rule.endpoint == 'ha.cluster_function' %} menu-active{% endif %}">HA {{lang.words.cluster}}</a></li>
{% endif %}
{% if '1' in g.user_params['user_services'] %}
<li class="p_menu">

View File

@ -508,6 +508,12 @@
"save_apply": "<b>Save</b> - means saving the HA cluster settings for Roxy-WI, without changing the component settings on the cluster members. <br /> <b>Apply</b> - recreate the HA cluster configuration on the cluster member servers and install additional services.",
}
%}
{% set nettools_page = {
"ip_or_name": "Enter IP or Name",
"dns_name": "Enter a DNS name",
"server_portscann": "Enter a server for port scanning",
}
%}
{% set words = {
"apply": "apply",
"true": "true",

View File

@ -508,6 +508,12 @@
"save_apply": "<b>Enregistrer</b> - signifie enregistrer les paramètres du cluster HA pour Roxy-WI, sans modifier les paramètres des composants sur les membres du cluster. <br /> <b>Appliquer </b>: recréez la configuration du cluster HA sur les serveurs membres du cluster et installez des services supplémentaires.",
}
%}
{% set nettools_page = {
"ip_or_name": "Entrez l'adresse IP ou le nom",
"dns_name": "Entrez un nom DNS",
"server_portscann": "Entrez un serveur pour l'analyse des ports",
}
%}
{% set words = {
"apply": "appliquer",
"true": "vrai",

View File

@ -508,6 +508,12 @@
"save_apply": "<b>Salvar</b> - significa salvar as configurações do cluster HA para Roxy-WI, sem alterar as configurações do componente nos membros do cluster. <br /> <b>Aplicar</b> recrie a configuração do cluster HA nos servidores membros do cluster e instale serviços adicionais.",
}
%}
{% set nettools_page = {
"ip_or_name": "Digite IP ou nome",
"dns_name": "Insira um nome DNS",
"server_portscann": "Insira um servidor para verificação de porta",
}
%}
{% set words = {
"apply": "aplicar",
"true": "verídico",

View File

@ -508,6 +508,12 @@
"save_apply": "<b>Сохранить</b> - подразумевает сохранение настроек HА кластера для Roxy-WI, без изменения настроек компонентов на участниках кластера. <br /> <b>Применить</b> - пересоздать конфигурацию HА кластера на серверах участниках кластера и установит дополнительные сервисы."
}
%}
{% set nettools_page = {
"ip_or_name": "Введите IP или доменное имя",
"dns_name": "Введите доменное имя",
"server_portscann": "Введите сервер для сканирования портов",
}
%}
{% set words = {
"apply": "применить",
"true": "да",

View File

@ -3,8 +3,8 @@
{% block h2 %}{{ lang.menu_links.monitoring.net_tools }}{% endblock %}
{% block content %}
{% from 'include/input_macros.html' import input, checkbox, select %}
<script src="/inc/nettools.js"></script>
<form name="nettools_icmp_form" id="nettools_icmp_form" method="post" action="/app/nettols/icmp">
<script src="/app/static/js/nettools.js"></script>
<form name="nettools_icmp_form" id="nettools_icmp_form" method="post" action="/app/nettools/icmp">
<table class="overview">
<caption><h3>ICMP</h3></caption>
<tr class="overviewHead">
@ -24,19 +24,19 @@
</select>
</td>
<td class="padding10 first-collumn">
{{ input('nettools_icmp_server_to', name='server_to', title='Enter IP or Name') }}
{{ input('nettools_icmp_server_to', name='server_to', title=lang.nettools_page.ip_or_name) }}
{{ input('token', value=token, type='hidden') }}
</td>
<td class="padding10 first-collumn">
<button type="submit" title="Run Ping" id="nettools_ping" name="nettools_ping" value="nettools_ping">Ping</button>
<button type="submit" title="{{lang.words.run|title()}} Ping" id="nettools_ping" name="nettools_ping" value="nettools_ping">Ping</button>
</td>
<td>
<button type="submit" title="Run Traceroute" id="nettools_trace" name="nettools_trace" value="nettools_trace">Traceroute</button>
<button type="submit" title="{{lang.words.run|title()}} Traceroute" id="nettools_trace" name="nettools_trace" value="nettools_trace">Traceroute</button>
</td>
</tr>
</table>
</form>
<form name="nettools_telnet_form" id="nettools_telnet_form" method="post" action="/app/nettols/tcp">
<form name="nettools_telnet_form" id="nettools_telnet_form" method="post" action="/app/nettools/tcp">
<table class="overview">
<caption><h3>Check port</h3></caption>
<tr class="overviewHead">
@ -56,11 +56,11 @@
</select>
</td>
<td class="padding10 first-collumn">
{{ input('nettools_telnet_server_to', name='server_to', title='Enter IP or Name') }}
{{ input('nettools_telnet_server_to', name='server_to', title=lang.nettools_page.ip_or_name) }}
{{ input('token', value=token, type='hidden') }}
</td>
<td class="padding10 first-collumn">
{{ input('nettools_telnet_port_to', title='Enter port', type='number', style='width: 60px;') }}
{{ input('nettools_telnet_port_to', title=lang.words.port|title() + ' ' + lang.words.port, type='number', style='width: 60px;') }}
</td>
<td>
<button type="submit" title="{{lang.words.run|title()}} Telnet" id="nettools_telnet" name="nettools_telnet" value="nettools_telnet">{{lang.words.connect|title()}}</button>
@ -68,7 +68,7 @@
</tr>
</table>
</form>
<form name="nettools_nslookup_form" id="nettools_nslookup_form" method="post" action="/app/nettols/dns">
<form name="nettools_nslookup_form" id="nettools_nslookup_form" method="post" action="/app/nettools/dns">
<table class="overview">
<caption><h3>NSLookup</h3></caption>
<tr class="overviewHead">
@ -94,7 +94,7 @@
{{ select('nettools_nslookup_record_type', values=values, selected='A', required='required') }}
</td>
<td class="padding10 first-collumn">
{{ input('nettools_nslookup_name', title='Enter a DNS name') }}
{{ input('nettools_nslookup_name', title=lang.nettools_page.dns_name) }}
{{ input('token', value=token, type='hidden') }}
</td>
<td>
@ -103,8 +103,8 @@
</tr>
</table>
</form>
<form name="nettools_portscanner_form" id="nettools_portscanner_form" method="post" action="/app/nettols/portscan">
<table class="overview">
<form name="nettools_portscanner_form" id="nettools_portscanner_form" method="post" action="/app/nettools/portscan">
<table class="overview" style="width: 40%;float: left;">
<caption><h3>Port scanner</h3></caption>
<tr class="overviewHead">
<th class="padding10 first-collumn">{{lang.words.server|title()}}</th>
@ -112,7 +112,7 @@
</tr>
<tr>
<td class="padding10 first-collumn">
{{ input('nettools_portscanner_server', title='Enter a server for port scanning') }}
{{ input('nettools_portscanner_server', title=lang.nettools_page.server_portscann) }}
</td>
<td class="padding10" style="width: 0">
<button type="submit" title="{{lang.words.run|title()}} port scanning" id="nettools_portscan" name="nettools_portscan" value="nettools_portscan">{{lang.words.run|title()}}</button>
@ -120,6 +120,23 @@
</tr>
</table>
</form>
<form name="nettools_whois_form" id="nettools_whois_form" method="post" action="/app/nettools/whois">
<table class="overview" style="width: 60%;">
<caption><h3>Whois</h3></caption>
<tr class="overviewHead">
<th class="padding10 first-collumn">{{lang.words.name|title()}}</th>
<th></th>
</tr>
<tr>
<td class="padding10 first-collumn">
{{ input('nettools_whois_name', title=lang.nettools_page.dns_name) }}
</td>
<td class="padding10" style="width: 0">
<button type="submit" title="{{lang.words.check|title()}}" id="nettools_whois" name="nettools_whois" value="nettools_whois">{{lang.words.check|title()}}</button>
</td>
</tr>
</table>
</form>
<div id="ajax-nettools" style="padding: 20px;"></div>
<div id="show_scans_ports" style="display: none; padding: 0;">
<div id="show_scans_ports_body"></div>

View File

@ -18,3 +18,4 @@ pika>=1.2.0
websockets>=9.0
ansible-core>=2.11.12
ansible-runner==2.3.2
python-whois>=0.8.0

View File

@ -19,3 +19,4 @@ pika>=1.2.0
websockets>=9.0
ansible-core>=2.11.12
ansible-runner==2.3.1
python-whois>=0.8.0

View File

@ -20,3 +20,4 @@ pika>=1.2.0
websockets>=9.0
ansible-core>=2.11.12
ansible-runner==2.3.1
python-whois>=0.8.0

View File

@ -20,3 +20,4 @@ websockets>=9.0
tzlocal==2.0.0
ansible-core>=2.11.12
ansible-runner==2.3.1
python-whois>=0.8.0

View File

@ -23,3 +23,4 @@ Flask-APScheduler==1.13.0
Flask-Caching==2.1.0
ansible-core>=2.11.12
ansible-runner==2.3.1
python-whois>=0.8.0