From 1cabf7fff91251fc7574260343b0aff1befce7b5 Mon Sep 17 00:00:00 2001 From: Aidaho Date: Wed, 21 May 2025 10:00:20 +0300 Subject: [PATCH] v8.2.0 --- app/modules/service/common.py | 2 + app/modules/service/haproxy.py | 13 +- app/routes/main/routes.py | 4 +- app/routes/service/routes.py | 11 - app/static/js/edit_config.js | 4 - app/static/js/overview.js | 14 +- app/static/js/script.js | 26 +- app/templates/languages/languages.html | 1 + app/templates/languages/zh.html | 962 +++++++++++++++++++++++++ 9 files changed, 983 insertions(+), 54 deletions(-) create mode 100644 app/templates/languages/zh.html diff --git a/app/modules/service/common.py b/app/modules/service/common.py index 3b8c7127..17140ace 100644 --- a/app/modules/service/common.py +++ b/app/modules/service/common.py @@ -233,6 +233,8 @@ def get_stat_page(server_ip: str, service: str, group_id: int) -> str: except requests.exceptions.HTTPError as errh: return f'error: Http Error: {errh}' except requests.exceptions.ConnectionError as errc: + if "Max retries exceeded" in str(errc): + raise Exception(f"error: Max retries exceeded") return f'error: Error Connecting: {errc}' except requests.exceptions.Timeout as errt: return f'error: Timeout Error: {errt}' diff --git a/app/modules/service/haproxy.py b/app/modules/service/haproxy.py index 42aa576d..cbfd5644 100644 --- a/app/modules/service/haproxy.py +++ b/app/modules/service/haproxy.py @@ -2,6 +2,7 @@ import os import requests from flask import request, g +from requests.exceptions import ConnectionError, Timeout, RequestException import app.modules.db.sql as sql import app.modules.server.server as server_mod @@ -16,6 +17,7 @@ def stat_page_action(server_ip: str, group_id: int) -> bytes: haproxy_pass = haproxy_pass.replace("'", "") stats_port = sql.get_setting('haproxy_stats_port', group_id=group_id) stats_page = sql.get_setting('haproxy_stats_page', group_id=group_id) + url = f'http://{server_ip}:{stats_port}/{stats_page}' postdata = { 'action': request.form.get('action'), @@ -30,7 +32,16 @@ def stat_page_action(server_ip: str, group_id: int) -> bytes: 'Accept-Encoding': 'gzip, deflate' } - data = requests.post(f'http://{server_ip}:{stats_port}/{stats_page}', headers=headers, data=postdata, auth=(haproxy_user, haproxy_pass), timeout=5) + try: + data = requests.post(url, headers=headers, data=postdata, auth=(haproxy_user, haproxy_pass), timeout=5) + except ConnectionError as e: + if "Max retries exceeded" in str(e): + raise Exception(f"error: Max retries exceeded with url: {url}") + raise Exception(f"error: Cannot connect to {url} {e}") + except Timeout as e: + raise Exception(f"error: Timeout for {url}: {e}") + except Exception as e: + raise Exception(f"error: Cannot connect to {url}: {e}") return data.content diff --git a/app/routes/main/routes.py b/app/routes/main/routes.py index e93ee21e..6650cecc 100644 --- a/app/routes/main/routes.py +++ b/app/routes/main/routes.py @@ -69,12 +69,12 @@ def show_stats(service: Literal['haproxy', 'apache', 'nginx'], server_ip: Union[ try: return service_common.get_stat_page(server_ip, service, g.user_params['group_id']) except Exception as e: - return f'error: {e}' + return e else: try: return service_haproxy.stat_page_action(server_ip, g.user_params['group_id']) except Exception as e: - return f'error: {e}' + return str(e) @bp.route('/nettools') diff --git a/app/routes/service/routes.py b/app/routes/service/routes.py index f4b309dd..a539d4d9 100644 --- a/app/routes/service/routes.py +++ b/app/routes/service/routes.py @@ -259,14 +259,3 @@ def update_tools_enable(service): roxywi_common.logging(server_ip, f'The server {name} has been updated ', keep_history=1, service=service) return 'ok' - - -@bp.route('/check-restart/') -@validate() -def check_restart(server_ip: Union[IPvAnyAddress, DomainName]): - servers = roxywi_common.get_dick_permit(ip=str(server_ip)) - for server in servers: - if server != "": - return 'ok' - - return 'nothing' diff --git a/app/static/js/edit_config.js b/app/static/js/edit_config.js index 28e6a8cc..c45b86a2 100644 --- a/app/static/js/edit_config.js +++ b/app/static/js/edit_config.js @@ -378,8 +378,6 @@ function addProxy(form_name, generate=false) { data.data = data.data.replace(/\n/g, "
"); if (returnNiceCheckingConfig(data.data) === 0) { toastr.info('Section has been added. Do not forget to restart the server'); - let ip = $('select[name=serv]').val(); - localStorage.setItem('restart', ip); resetProxySettings(); } } @@ -413,8 +411,6 @@ function editProxy(form_name, dialog_id, generate=false) { data.data = data.data.replace(/\n/g, "
"); if (returnNiceCheckingConfig(data.data) === 0) { toastr.info('Section has been updated. Do not forget to restart the server'); - let ip = $('select[name=serv]').val(); - localStorage.setItem('restart', ip); $('#edit-section').remove(); showConfig(); $(dialog_id).dialog( "close" ); diff --git a/app/static/js/overview.js b/app/static/js/overview.js index fab84d6f..33e72943 100644 --- a/app/static/js/overview.js +++ b/app/static/js/overview.js @@ -198,10 +198,6 @@ $( function() { if (cur_url[0] == "" || cur_url[0] == "waf" || cur_url[0] == "metrics") { $('#secIntervals').css('display', 'none'); } - $('#apply_close').click( function() { - $("#apply").css('display', 'none'); - localStorage.removeItem('restart'); - }); $( ".server-act-links" ).change(function() { let id = $(this).attr('id').split('-'); @@ -229,15 +225,7 @@ function confirmAjaxAction(action, service, id) { text: action_word, click: function () { $(this).dialog("close"); - if (service === "haproxy") { - ajaxActionServers(action, id, service); - if (action === "restart" || action === "reload") { - if (localStorage.getItem('restart')) { - localStorage.removeItem('restart'); - $("#apply").css('display', 'none'); - } - } - } else if (service === "waf") { + if (service === "waf") { ajaxActionServers(action, id, 'waf_haproxy'); } else { ajaxActionServers(action, id, service); diff --git a/app/static/js/script.js b/app/static/js/script.js index adb9d6c9..b5685a16 100644 --- a/app/static/js/script.js +++ b/app/static/js/script.js @@ -68,29 +68,6 @@ jQuery.expr[':'].regex = function(elem, index, match) { regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags); return regex.test(jQuery(elem)[attr.method](attr.property)); } -if(localStorage.getItem('restart')) { - let ip_for_restart = localStorage.getItem('restart'); - $.ajax({ - url: "/service/check-restart/" + ip_for_restart, - success: function (data) { - if (data.indexOf('ok') != '-1') { - var apply_div = $.find("#apply_div"); - apply_div = apply_div[0].id; - $("#apply").css('display', 'block'); - $('#' + apply_div).css('width', '850px'); - ip_for_restart = escapeHtml(ip_for_restart); - if (cur_url[0] === "service") { - $('#' + apply_div).css('width', '650px'); - $('#' + apply_div).addClass("alert-one-row"); - $('#' + apply_div).html("You have made changes to the server: " + ip_for_restart + ". Changes will take effect only afterrestartX"); - } else { - $('#' + apply_div).html("You have made changes to the server: " + ip_for_restart + ". Changes will take effect only after restart. Go to the HAProxy Overview page and restartX"); - } - $.getScript(overview); - } - } - }); -} $( document ).ajaxSend(function( event, request, settings ) { NProgress.start(); }); @@ -1156,6 +1133,9 @@ function returnNiceCheckingConfig(data) { } if (element.indexOf('[WARNING]') != '-1' || element.indexOf('[ALER]') != '-1' || element.indexOf('[warn]') != '-1') { element = removeEmptyLines(element); + if (element.indexOf('global server state file') != '-1') { + return; + } if (second_alert === false) { alert_warning = alert_warning + element; } else { diff --git a/app/templates/languages/languages.html b/app/templates/languages/languages.html index e29636db..6268aa68 100644 --- a/app/templates/languages/languages.html +++ b/app/templates/languages/languages.html @@ -3,5 +3,6 @@ 'ru': 'Русский', 'fr': 'Français', 'pt-br': 'Português', + 'zh': '中文', } %} diff --git a/app/templates/languages/zh.html b/app/templates/languages/zh.html new file mode 100644 index 00000000..2ede8ffc --- /dev/null +++ b/app/templates/languages/zh.html @@ -0,0 +1,962 @@ +{% set lang_short = 'zh' %} +{% set menu_links = dict() %} +{% set menu_links = { + "overview": { + "link": "概述", + "title": "服务器和服务状态", + "h2": "概述" + }, + "hapservers": { + "link": "概述", + "h2": "服务概览", + "haproxy": { + "title": "HAProxy 服务器概览" + }, + "nginx": { + "title": "NGINX 服务器概览" + }, + "apache": { + "title": "Apache 服务器概览" + }, + "keepalived": { + "title": "Keepalived 服务器概览" + }, + }, + "config": { + "link": "配置", + "h2": "配置管理", + "haproxy": { + "title": "管理 HAProxy 配置" + }, + "nginx": { + "title": "管理 NGINX 配置" + }, + "apache": { + "title": "管理 Apache 配置" + }, + "keepalived": { + "title": "管理 Keepalived 配置" + }, + }, + "stats": { + "link": "统计", + "h2": "统计数据", + "haproxy": { + "title": "HAProxy 统计" + }, + "nginx": { + "title": "NGINX 统计" + }, + "apache": { + "title": "Apache 统计" + }, + }, + "logs": { + "link": "日志", + "title": "日志", + "h2": "日志" + }, + "metrics": { + "link": "指标", + "title": "指标", + "h2": "指标", + }, + "add_proxy": { + "link": "添加代理", + "title": "添加代理:创建代理" + }, + "versions": { + "link": "版本", + "h2": "管理配置版本", + "haproxy": { + "title": "管理 HAProxy 配置版本" + }, + "nginx": { + "title": "管理 NGINX 配置版本" + }, + "apache": { + "title": "管理 Apache 配置版本" + }, + "keepalived": { + "title": "管理 Keepalived 配置版本" + }, + }, + "ssl": { + "link": "SSL", + "title": "添加代理:上传 SSL 证书" + }, + "lists": { + "link": "列表", + "title": "添加代理:创建和上传白名单或黑名单" + }, + "ha": { + "title": "创建和配置高可用集群", + }, + "monitoring": { + "link": "监控", + "title": "监控工具", + "smon": { + "dashboard": "SMON:仪表板", + "status_page": "SMON:状态页面", + "history": "SMON:历史记录", + "agent": "SMON:代理", + }, + "checker_history": "检查器:历史记录", + "port_scan": "端口扫描器", + "net_tools": "网络工具", + }, + "servers": { + "link": "服务器", + "title": "服务器管理" + }, + "admin_area": { + "link": "管理员区域", + "title": "管理员区域" + }, + "history": { + "title": "历史记录" + }, + "udp": { + "title": "UDP 监听器" + } +} +%} +{% set services = { + "hapservers_desc": "检测器监控服务。如果服务状态更改,检测器将通过 Telegram、Slack、电子邮件或 Web 发送警报。", + "last_edit": "上次编辑" + } +%} +{% set errors = { + "cannot_get_info": "无法获取信息", + "something_wrong": "安装过程中发生错误", + "check_logs": "检查日志", + "select_server": "请先选择一台服务器", + "empty_name": "名称不能为空", + } +%} +{% set settings = { + "rabbitmq": { + "rabbitmq_host": "RabbitMQ 服务器主机", + "rabbitmq_port": "RabbitMQ 服务器端口", + "rabbitmq_vhost": "RabbitMQ 服务器虚拟主机", + "rabbitmq_queue": "RabbitMQ 服务器队列", + "rabbitmq_user": "RabbitMQ 服务器用户名", + "rabbitmq_password": "RabbitMQ 服务器密码", + }, + "nginx": { + "nginx_path_logs": "NGINX 日志路径", + "nginx_stats_user": "访问 NGINX 统计页面用户名", + "nginx_stats_password": "访问 NGINX 统计页面密码", + "nginx_stats_port": "NGINX 统计页面端口", + "nginx_stats_page": "NGINX 统计页面 URI", + "nginx_dir": "包含配置文件的 NGINX 目录路径", + "nginx_config_path": "NGINX 主配置文件路径", + "nginx_container_name": "NGINX 服务的 Docker 容器名称", + }, + "monitoring": { + "port_scan_interval": "端口扫描器检查间隔(分钟)", + "portscanner_keep_history_range": "端口扫描器历史保留周期", + "checker_keep_history_range": "检查器历史保留周期", + "checker_maxconn_threshold": "最大连接数警报阈值(%)", + "checker_check_interval": "检查器检查间隔(分钟)", + "action_keep_history_range": "动作历史保留时长(天)", + }, + "smon": { + "master_ip": "连接到 SMON 主服务器的 IP 或名称", + "master_port": "连接到 SMON 主服务器的端口", + "agent_port": "SMON 代理端口", + "smon_keep_history_range": "SMON 历史保留周期", + "smon_ssl_expire_warning_alert": "SSL 证书即将过期警告(天)", + "smon_ssl_expire_critical_alert": "SSL 证书即将过期严重警报(天)", + }, + "main": { + "time_zone": "时区", + "license": "许可证密钥", + "proxy": "代理服务器的 IP 地址和端口。使用协议格式 proto://ip:port", + "session_ttl": "用户会话的存活时间(天)", + "token_ttl": "用户令牌的存活时间(天)", + "tmp_config_path": "临时目录路径。该路径必须有效并由 SSH 设置中指定的用户拥有。", + "cert_path": "SSL 目录路径。文件夹的所有者必须是 SSH 设置中指定的用户。路径必须存在。", + "maxmind_key": "用于下载 GeoLite2 数据库的许可证密钥。您可以在 maxmind.com 上创建它。", + }, + "mail": { + "mail_ssl": "启用 TLS", + "mail_from": "发件人地址", + "mail_smtp_host": "SMTP 服务器地址", + "mail_smtp_port": "SMTP 服务器端口", + "mail_smtp_user": "SMTP 用户名", + "mail_smtp_password": "SMTP 密码", + }, + "logs": { + "syslog_server_enable": "启用从 Syslog 服务器获取日志", + "syslog_server": "Syslog 服务器的 IP 地址", + "log_time_storage": "用户活动日志的保留时长(天)", + "apache_log_path": "Apache 日志路径", + }, + "ldap": { + "ldap_enable": "启用 LDAP", + "ldap_server": "LDAP 服务器的 IP 地址", + "ldap_port": "LDAP 端口(默认使用 389 或 636)", + "ldap_user": "LDAP 用户名", + "ldap_password": "LDAP 密码", + "ldap_base": "基础域。例如:dc=domain, dc=com", + "ldap_domain": "登录所用的 LDAP 域", + "ldap_class_search": "用于搜索用户的类", + "ldap_user_attribute": "用于搜索用户的属性", + "ldap_search_field": "用户的电子邮件地址", + "ldap_type": "使用 LDAPS", + }, + "haproxy": { + "haproxy_path_logs": "HAProxy 日志路径", + "haproxy_stats_user": "访问 HAProxy 统计页面的用户名", + "haproxy_stats_password": "访问 HAProxy 统计页面的密码", + "haproxy_stats_port": "HAProxy 统计页面端口", + "haproxy_stats_page": "HAProxy 统计页面 URI", + "haproxy_dir": "包含配置文件的 HAProxy 目录路径", + "haproxy_config_path": "HAProxy 主配置文件路径", + "server_state_file": "HAProxy 状态文件路径", + "haproxy_sock": "HAProxy 套接字文件路径", + "haproxy_sock_port": "HAProxy 套接字端口", + "haproxy_container_name": "HAProxy 服务的 Docker 容器名称", + }, + "apache": { + "apache_path_logs": "Apache 日志路径", + "apache_stats_user": "访问 Apache 统计页面的用户名", + "apache_stats_password": "访问 Apache 统计页面的密码", + "apache_stats_port": "Apache 统计页面端口", + "apache_stats_page": "Apache 统计页面 URI", + "apache_dir": "包含配置文件的 Apache 目录路径", + "apache_config_path": "Apache 主配置文件路径", + "apache_container_name": "Apache 服务的 Docker 容器名称", + }, + "keepalived": { + "keepalived_config_path": "Keepalived 主配置文件路径", + "keepalived_path_logs": "Keepalived 日志路径", + }, + } +%} +{% set phrases = { + "config_file_name": "配置文件名称", + "no_events_added": "尚未添加任何事件。", + "upload_and_restart": "上传并重启", + "upload_and_reload": "上传并重新加载", + "save_and_restart": "保存并重启", + "save_and_reload": "保存并重新加载", + "save_title": "仅保存,不重启服务", + "return_to_config": "返回配置视图", + "check_config": "检查配置", + "master_slave": "如果您重新配置主服务器,备份服务器将自动重新配置", + "read_about_files": "您可以阅读所有日志文件的说明", + "read_about_parameters": "您可以阅读所有参数的说明", + "read_howto": "在此阅读使用指南", + "howto_user": "如何使用", + "select_file": "选择一个文件", + "read_how_it_works": "您可以阅读其工作原理", + "metrics_not_installed": "您尚未安装指标服务。", + "how_to_install_metrics": "如何安装指标服务", + "checker_not_installed": "您尚未安装检查器服务", + "how_to_install_checker": "如何安装检查器服务", + "auto_start_not_installed": "您尚未安装自启动服务", + "enable_avg_table": "启用平均值表显示", + "disable_avg_table": "禁用平均值表显示", + "protected_title": "启用保护时,除管理员角色外,服务器不可编辑", + "slave_for_title": "主配置上的操作将自动应用到备份服务器", + "server_unknown": "服务器状态未知", + "no_sub": "您尚未订阅", + "pls_sub": "请订阅以访问此功能", + "no_av_feat": "此功能不适用于您的计划", + "fwd_warn": "仅来自 INPUT、IN_public_allow 和 OUTPUT 链的规则", + "search_in_ad": "在 AD 中搜索用户", + "are_you_sure": "您确定吗?", + "delete_dialog": "删除不可恢复,所有数据将丢失", + "fields_mark": "标有", + "are_required": "的字段为必填项", + "scan_title": "扫描服务器以查找 HAProxy、NGINX、Keepalived 和 Firewalld 服务", + "superAdmin_pass": "您无法编辑 superAdmin 角色的密码", + "superAdmin_services": "您无法编辑 superAdmin 角色的服务", + "pass_mismatched": "密码不匹配", + "private_key_note": "私钥。注意:必须在您计划连接的所有服务器上预先安装公钥。", + "send_test_mes": "发送测试消息", + "alert_service_change_status": "服务状态更改警报", + "alert_backend_change_status": "后端状态更改警报", + "alert_number_conn": "连接数接近限制时发出警报", + "alert_master_backup": "主/备状态更改警报", + "new_version": "有新版本的 Roxy-WI。检查", + "all_alerts_enabled": "警报已启用", + "disable_alerts": "禁用警报", + "work_with_prev": "您可以在此使用以前的配置版本", + "roll_back": "回滚到它们、查看或删除", + "files_been_deleted": "以下文件已被删除", + "version_has_been_uploaded": "配置文件的以下版本已上传并保存为", + "new_config_has_been_saved": "新配置已保存为", + "view_and_upload": "查看并上传该版本的配置", + "int_vrrp": "服务器上 VRRP 地址的接口", + "howto_ha": "如何创建高可用集群", + "been_installed": "已安装", + "wait_mess": "请不要关闭或刷新页面。等待任务完成。这可能需要一些时间。", + "you_are_editing": "您正在编辑", + "section_from_server": "服务器的部分", + "how_to_install": "如何安装", + "port_check": "端口检查", + "possible_service_name": "可能的服务名称", + "server_info": "服务器信息", + "user_groups": "用户组", + "comparing_config": "比较配置文件", + "select_older_config": "选择较旧的配置", + "select_newer_config": "选择较新的配置", + "not_checked": "未检查", + "show_not_checked": "显示未检查的服务器", + "read_desc_runtime_api": "您可以阅读所有运行时 API 参数的说明", + "read_desc_statuses": "您可以阅读状态的描述", + "login_or_pass_incorrect": "登录名或密码不正确", + "can_try_again": "您可以在以下时间后重试", + "is_not_installed": "未安装", + "server_is_inaccessible_for_editing": "该服务器无法为非管理员角色编辑", + "creating_ha": "创建新高可用集群", + "adding_vrrp": "添加新 VRRP 地址", + "find_in_log": "在日志文件中查找。支持正则表达式。", + "exclude_in_log": "从日志搜索中排除。支持正则表达式。", + "bytes_in": "进入字节数", + "bytes_out": "输出字节数", + "current_ses": "当前会话数", + "total_ses": "总会话数", + "ReqPerSec": "每秒请求数", + "BytesPerSec": "每秒字节数", + "became_master": "变为主机", + "resource_record_type": "资源记录类型", + "add_to_smon_desc": "添加服务器以通过 SMON Ping 检查", + "create_page_status": "创建状态页面", + "not_in_cluster": "不在集群中", + "ssh_passphrase": "SSH 密钥密码", + "check_interval": "检查间隔。", + "check_interval_title": "检查间隔(以秒为单位)。", + } +%} +{% set roles = { + "superAdmin": "具有最高级别的管理权限,可以控制所有其他用户的操作", + "admin": "除管理员区域外,拥有所有访问权限", + "user": "拥有与管理员相同的权限,但无法访问服务器页面", + "guest": "仅限只读访问" + } +%} +{% set add_page = { + "desc": { + "port_check": "基本的 TCP 层健康检查尝试连接到服务器的 TCP 端口。当服务器返回 SYN/ACK 数据包时,检查被认为是成功的。", + "maxconn": "进程允许的总连接数。这可以防止进程接受过多连接,从而防止内存耗尽。", + "server_template": "根据模板创建服务器列表。", + "def_check": "默认参数。", + "saved_options": "这些是您在“选项”选项卡中保存的选项。", + "press_down": "或者按“向下”按钮。", + "ip_port": "如果监听器的 IP 地址为空,则会监听所有 IP 地址。开始输入 IP 或按下按钮。单击 + 以添加多个 IP 和端口对。如果您使用 VRRP,请将 IP 字段留空。如果分配了 VRRP IP,备份服务器将无法启动。", + "listener_desc1": "“监听”部分定义了一个完整的代理,它的前端和后端部分合并在一个部分中。这通常对仅 TCP 流量非常有用。", + "listener_desc2": "所有代理名称必须由大小写字母、数字、“-”(横线)、“_”(下划线)、“.”(点)和“:”(冒号)组成。ACL 名称是区分大小写的,例如 'www' 和 'WWW' 是两个不同的代理。", + "listener_desc3": "从历史上看,所有代理名称都可以重复,但这会导致日志问题。自引入内容切换以来,两个具有重叠功能(前端/后端)的代理必须具有不同的名称。然而,仍然允许前端和后端共享相同名称,因为这种配置常见。", + "front_desc1": "“前端”部分描述了一组接受客户端连接的监听套接字。", + "back_des1": "“后端”部分描述了一组服务器,代理将连接这些服务器以转发传入的连接。", + "ssl_offloading": "SSL 卸载的意思是,您在网络边缘(例如负载均衡器上)执行所有加密和解密。", + "http_https": "启用从 HTTP 到 HTTPS 的重定向。", + "enable_http2": "启用 HTTP 2。", + "maxconn_desc": "该值不应超过全局 maxconn 值。默认全局 maxconn 值。", + "maxconn_fix": "确定前端的最大并发连接数。", + "antibot": "不幸的是,大量机器人被用于恶意目的。它们的意图包括抓取网页、发送垃圾邮件、请求泛洪、暴力破解以及漏洞扫描。例如,机器人可能抓取您的价格列表,以便竞争对手始终压低您的价格,或利用您的数据创建竞争解决方案。", + "slow_attack": "在慢速 POST 攻击中,攻击者首先发送一个合法的 HTTP POST 标头到 Web 服务器,就像通常情况下那样。标头指定了随后消息体的确切大小。然而,消息体随后会以一个极慢的速率发送——有时每两分钟仅发送 1 字节。", + "http_compression": "HTTP 压缩允许您在将响应转发给客户端之前缩减响应主体的大小,这能减少每个请求使用的网络带宽。从客户端角度看,这减少了延迟。", + "forward_for": "当 HAProxy 企业代理一个 TCP 连接时,它会使用自己的地址覆盖客户端的源 IP 地址与后端服务器通信。然而,它可以在 HTTP 消息的 HTTP 头 `X-Forwarded-For` 中存储客户端的地址。然后,后端服务器可以从此头读取值以检索客户端 IP 地址。", + "redispatch": "在 HTTP 模式下,如果一个由 Cookie 指定的服务器宕机,客户端可能一直连接到该服务器而无法刷新 Cookie,导致无法访问服务。指定“option redispatch”将允许代理打破粘性并重新分配到正在运行的服务器。当然,这要求“retries”设置为非零值。", + "force_close": "由于 HAProxy 以反向代理模式工作,服务器看到的客户 IP 地址是其自身的 IP 地址。当需要在服务器日志中记录客户地址时,可以通过添加 HTTP 头 'X-Forwarded-For' 来解决。此头包含客户的 IP 地址。", + "cookie": "启用基于 Cookie 的会话持久性,以便用户在相同服务器上重用会话。", + "c_prefix": "此关键字表示不依赖专门的 Cookie,而是补全现有的 Cookie。", + "c_nocache": "建议在插入模式下使用此功能,尤其是在客户端和 HAProxy 之间存在缓存时。", + "c_postonly": "此选项确保 Cookie 插入仅在对 POST 请求的响应中执行。", + "c_dynamic": "激活动态 Cookie。当启用时,会为每个服务器动态创建会话 Cookie。", + "def_backend": "如果您想使用默认后台。", + "def_backend_exit": "后端必须存在。", + "port_for_bind": "绑定端口。", + "bind_ip_pair": "绑定一个额外的 IP-端口对。", + "no_def_backend": "如果没有满足条件的定义,将使用“default_backend”定义的后端。如果未定义默认后端,将返回 503 服务不可用响应。", + "circuit_breaking": "断路器是一种设计模式,用于检测故障,并包含防止故障重复的逻辑。它类似于电气断路器,当检测到故障时会立即打开电路。", + "peers_master": "注意:如果要将 HAProxy 服务用作主-主集群,则必须将本地服务器的主机名设置为对等服务器名。否则,对等关系将不起作用。", + "peers_slave": "注意:如果要将 HAProxy 服务用作主-从集群,则必须将主服务器的主机名设置为从服务器的对等服务器名。否则,对等关系将不起作用。", + "peers": "peers 部分允许在两个或更多 HAProxy 实例之间复制粘性表数据。", + "userlist": "在此部分中,您可以创建用户列表。之后可在“添加”部分中使用它们。", + "userlist_name": "用户列表名称。", + "userlist_pass": "用户密码。默认情况下为 insecure-password。", + "userlist_user_grp": "用户的组。", + "userlist_user": "也可以通过使用逗号分隔的组列表连接组。", + "userlist_group": "可以使用逗号分隔的名称列表附加用户到某个组,前缀为 'users' 关键字。", + "userlist_desc": "可以通过创建至少一个用户列表并定义用户,控制对前端、后端或 HTTP 统计的访问。", + "servers": "在此部分中,您可以创建、编辑和删除服务器。之后可在“添加”部分中自动填充它们。", + "options": "您可以在本节中创建、编辑和删除选项。然后在“添加”部分中将它们用作自动填充", + "paste_cert": "粘贴证书文件的内容。", + "paste_cert_desc": "此 pem 文件将用于为 HAProxy、NGINX 或 Apache 创建 HTTPS 连接。", + "lists_howto": "在此部分中,您可以创建和编辑黑名单与白名单,之后可在 HAProxy 配置或“添加代理”页面中使用它们。", + "lists_new_line": "每一个新地址必须从新行定义。", + "was_success_added": "已成功添加。", + "create_ssl_proxy": "在 HAProxy 上创建具有 SSL 卸载功能的 HTTPS 代理。需要提供。", + "create_ssl_front": "在 HAProxy 上创建具有 SSL 卸载功能的 HTTPS 前端。需要提供。", + "create_ssl_backend": "在 HAProxy 上创建具有 SSL 卸载功能的 HTTPS 后端。需要提供。", + "create_https_proxy": "创建没有 SSL 卸载功能的 HTTPS 代理。HAProxy 将向后端发送 HTTPS 流量。", + "create_https_front": "创建没有 SSL 卸载功能的 HTTPS 前端。HAProxy 将向后端发送 HTTPS 流量。", + "create_https_backend": "创建没有 SSL 卸载功能的 HTTPS 后端。HAProxy 将向后端发送 HTTPS 流量。", + "option_temp": "创建、编辑和删除具有给定参数的选项,之后可在“添加”部分中使用。", + "server_temp": "创建、编辑和删除服务器,之后可在“添加”部分中使用。", + "use_add": "并在“添加”部分中使用它。", + "comma_separated": "您可以用逗号或空格分隔多个值。", + "create_nginx_ssl_proxy": "在 NGINX 上创建具有 SSL 卸载功能的 HTTPS 代理。需要提供。", + "create_nginx_proxy": "NGINX 中的代理转发客户端请求到目标服务器(如 Node.js 或 Python),并将响应返回客户端。" + }, + "buttons": { + "disable_ssl_check": "禁用 SSL 检查。", + "disable_ssl_verify": "禁用服务器的 SSL 验证。", + "set_options": "设置选项。", + "set_options_m": "手动设置选项。", + "show_full_settings": "显示完整设置列表。", + "show_full_settings": "隐藏完整设置列表。" + } +} +%} +{% set add_nginx_page = { + "desc": { + "upstream_desc1": "upstream 模块用于定义服务器组。", + "upstream_desc2": "定义一组服务器。服务器可以监听不同的端口。此外,监听 TCP 和 UNIX 域套接字的服务器可以混合使用。", + "upstream_desc3": "默认情况下,请求在服务器之间按照加权轮询负载均衡方法分配。", + "keepalive": "connections 参数设置每个工作进程中作为缓存保留的上游服务器的最大空闲 keepalive 连接数。当超过此数量时,最久未使用的连接将被关闭。", + "fail_timeout": "在指定时间内发生指定次数的与服务器通信失败,以将服务器视为不可用的时间;以及服务器将被视为不可用的时间段。", + "max_fails": "设置在 fail_timeout 参数定义的时间段内,与服务器通信失败的最大尝试次数,以将服务器视为不可用。此失败时间段同样由 fail_timeout 参数定义。默认情况下,失败的最大尝试次数为 1。", + } + } +%} +{% set admin_page = { + "desc": { + "latest_repo": "Roxy-WI 将尝试从官方库安装服务的最新版本。", + "install_as_docker": "将服务作为 Docker 容器安装。", + "no_ansible": "您尚未安装", + "before_install": "在安装任何 exporters 之前,请先安装", + "been_installed": "服务器已安装。", + "there_are_no": "没有 Grafana 和 Prometheus 服务器。", + "country_codes": "国家代码。", + "smon_desc": "SMON 表示 简单监控(Simple MONitoring)。", + "checker_desc": "Checker 设计用于监控 HAProxy、Nginx、Apache 和 Keepalived 服务,以及 HAProxy 后端和 maxconn。", + "auto_start_desc": "自动启动服务允许在 HAProxy、NGINX、Apache 和 Keepalived 服务停止时重新启动它们。", + "metrics_desc": "收集 HAProxy、NGINX、Apache 和 HAProxy WAF 服务的连接数。", + "p_s_desc": "检查服务器的开放端口并保存历史记录。", + "socket_desc": "Socket 是一个用于发送警报和通知的服务。", + "a_new_version": "有新版本可用。", + "no_new_version": "没有新版本可用。", + "main_app": "主应用程序。", + "for_updating": "要更新,您必须使用 Roxy-WI 的 RPM 或 DEB。", + "how_to_using_repo": "如何开始使用仓库。", + "proxy_settings": "如果 Roxy-WI 服务器通过代理连接到互联网,请在 yum.conf 中添加代理配置。", + } + } +%} +{% set smon_page = { + "desc": { + "before_use": "使用前", + "smon_is_not_run": "SMON 服务未运行。", + "run_smon": "运行 SMON 服务", + "not_installed": "您尚未安装 SMON 服务", + "not_added": "您未在 SMON 服务中添加任何服务器", + "create_server": "创建您的第一个服务器", + "see_check": "查看是否已添加新的检查", + "do_not_sort": "不排序", + "do_not_sort_by_status": "不按状态排序", + "sort_status": "按状态排序", + "status_summary": "状态摘要", + "enabled_checks": "已启用检查", + "http_status_check": "HTTP 状态检查", + "body_status_check": "响应正文检查", + "resp_time": "响应时间", + "last_resp_time": "最后响应时间", + "UP": "正常", + "DOWN": "异常", + "HTTP_FAILURE": "HTTP 失败", + "BODY_FAILURE": "响应正文失败", + "UNKNOWN": "未知", + "PORT_DOWN": "端口关闭", + "DISABLED": "禁用", + "packet_size": "数据包大小", + "add_agent": "添加代理", + "total_checks": "检查总数", + "not_assign_to_agent": "该检查未分配给任何代理" + } + } +%} +{% set p_s_page = { + "desc": { + "is_enabled_and_up": "端口扫描器已启用且服务正常运行", + "is_enabled_and_down": "端口扫描器已启用,但服务未运行", + "scanning_ports": "扫描服务器的开放/过滤端口", + "total_open_ports": "打开端口总数", + "p_s_title": "端口扫描仪仪表板", + "p_s_title_history": "端口扫描仪历史记录", + } + } +%} +{% set ha_page = { + "ha": "高可用集群", + "has": "高可用集群", + "create_virt_server": "Roxy-WI 将 VRRP 地址添加为单独服务器", + "return_master_desc": "返回主服务器", + "return_master": "如果选中此选项,则当服务重新运行时,Keepalived 主服务器会返回 VRRP。", + "try_install": "Roxy-WI 将安装", + "as_docker": "作为 Docker 容器", + "add_vip": "将 VIP 添加到高可用集群", + "create_ha": "创建高可用集群", + "start_enter": "开始输入网络接口名称以添加 VIP", + "roxywi_timeout": "Roxy-WI 响应超时", + "check_apache_log": "检查 Apache 错误日志 以获取更多信息。", + "was_installed": "已安装于", + "start_enter": "开始输入网络接口以添加 VIP", + "use_src": "将 VIP 地址作为源使用", + "use_src_help": "将 VIP 地址用作与后端的出站连接的源地址", + "save_apply": "保存 - 表示将高可用集群设置保存到 Roxy-WI,而不更改集群成员的组件设置。
应用 - 在集群成员服务器上重新创建高可用集群配置并安装其他服务。", + } +%} +{% set udp_page = { + "save_apply": "保存 - 表示将 UDP 监听器设置保存到 Roxy-WI,而不更改集群成员或独立服务器的组件设置。
应用 - 在集群成员或独立服务器上重新创建 UDP 监听器配置。", + "listener_ip": "绑定 UDP 监听器的 IP。开始输入", + "listener_port": "绑定 UDP 监听器的端口", + "balancing_type": "负载均衡类型", + "check_backends": "启用后端检查", + "retry": "重试次数", + "retry_title": "最大重试次数", + "delay_before_retry_title": "两次连续重试之间的延迟", + "delay_before_retry": "重试之间的延迟", + "delay_loop_title": "以秒为单位指定检查间隔", + "delay_loop": "检查间隔", + } +%} +{% set nettools_page = { + "ip_or_name": "输入 IP 或名称", + "dns_name": "输入 DNS 名称", + "server_portscann": "输入用于端口扫描的服务器", + } +%} +{% set words = { + "apply": "应用", + "true": "真", + "false": "假", + "cache": "缓存", + "compression": "压缩", + "acceleration": "加速", + "start": "开始", + "start2": "开始", + "stop": "停止", + "restart": "重启", + "service": "服务", + "service2": "服务", + "services": "服务", + "services2": "服务", + "services3": "服务", + "services4": "服务", + "started": "已启动", + "reload": "重载", + "reloading": "正在重载", + "stopped": "已停止", + "no_desc": "没有描述", + "process_num": "进程数", + "version": "版本", + "version2": "版本", + "versions": "版本", + "error": "错误", + "addresses": "地址", + "address": "地址", + "virtual": "虚拟", + "hosts": "主机", + "time_range": "时间范围", + "server": "服务器", + "server2": "服务器", + "status": "状态", + "current": "当前", + "current2": "当前", + "total": "总计", + "server_status": "服务器状态", + "services_status": "服务状态", + "compare": "比较", + "map": "地图", + "about": "关于", + "help": "帮助", + "contacts": "联系人", + "cabinet": "柜子", + "legal": "法律", + "alert": "警告", + "alert2": "警告", + "alerts": "警告", + "manage": "管理", + "user": "用户", + "user2": "用户", + "user3": "用户", + "users": "用户", + "users2": "用户", + "username": "用户名", + "servers": "服务器", + "servers2": "服务器", + "creds": "凭据", + "creds2": "凭据", + "settings": "设置", + "settings2": "设置", + "install": "安装", + "installation": "安装", + "installing": "正在安装", + "proxy": "代理", + "provisioning": "配置", + "backup": "备份", + "backup2": "备份", + "configs": "配置文件", + "configs2": "配置文件", + "config": "配置", + "from": "来自", + "view": "查看", + "internal": "内部", + "internal2": "内部", + "log": "日志", + "logs": "日志", + "logs2": "日志", + "admin_area": "管理员区域", + "group": "组", + "group2": "组", + "groups": "组", + "groups2": "组", + "groups3": "组", + "w_update": "更新", + "updating": "正在更新", + "monitoring": "监控", + "auto": "自动", + "refresh": "刷新", + "refresh2": "刷新", + "no": "否", + "not": "不", + "yes": "是", + "interval": "间隔", + "desc": "描述", + "login": "登录", + "login2": "登录", + "role": "角色", + "roles": "角色", + "subs": "订阅", + "show_all": "显示全部", + "plan": "计划", + "pay_method": "支付方式", + "active": "活动", + "actives": "活动的", + "open": "打开", + "opened": "已打开", + "edit": "编辑", + "delete": "删除", + "add": "添加", + "added": "已添加", + "save": "保存", + "saved": "已保存", + "saving": "正在保存", + "expand_all": "展开全部", + "collapse_all": "折叠全部", + "raw": "原始", + "stats": "统计", + "note": "注释", + "back": "返回", + "show": "显示", + "run": "运行", + "running": "正在运行", + "running2": "正在运行", + "statistics": "统计", + "rollback": "回滚", + "previous": "上一个", + "to": "到", + "listener": "监听器", + "frontends": "前端", + "frontend": "前端", + "backends": "后端", + "backend": "后端", + "maintain": "维护", + "drain": "排出", + "drains": "排出", + "number": "数字", + "rows": "行", + "row": "行", + "find": "查找", + "exclude": "排除", + "file": "文件", + "file2": "文件", + "files": "文件", + "here": "这里", + "action": "操作", + "actions": "操作", + "command": "命令", + "change": "更改", + "change2": "更改", + "changes": "更改", + "enter": "输入", + "enter2": "输入", + "lists": "列表", + "list": "列表", + "sessions": "会话", + "session": "会话", + "and": "和", + "select": "选择", + "select2": "选择", + "new": "新", + "new2": "新", + "new3": "新", + "new4": "新", + "port": "端口", + "ports": "端口", + "table": "表", + "w_get": "获取", + "dynamically": "动态地", + "set": "设置", + "type": "类型", + "typing": "输入", + "size": "大小", + "is": "是", + "w_empty": "空", + "used": "使用", + "w_clear": "清空", + "this": "这个", + "this2": "这个", + "this3": "这个", + "this4": "这个", + "entry": "条目", + "age": "年龄", + "protocol": "协议", + "rate": "速率", + "expire": "过期", + "more": "更多", + "info": "信息", + "source": "来源", + "overview": "概览", + "personal": "个人", + "read": "读取", + "second": "秒", + "seconds": "秒", + "seconds2": "秒", + "minute": "分钟", + "minute2": "分钟", + "minutes": "分钟", + "minutes2": "分钟", + "hour": "小时", + "hours": "小时", + "hours2": "小时", + "day": "天", + "days": "天", + "metrics": "指标", + "every": "每", + "every2": "每", + "every3": "每", + "hide": "隐藏", + "average": "平均", + "peak": "峰值", + "connect": "连接", + "connections": "连接", + "connections2": "连接", + "enable": "启用", + "enabled": "已启用", + "enabled2": "已启用", + "virt": "虚拟", + "virtual": "虚拟", + "check": "检查", + "check2": "检查", + "checks": "检查", + "checking": "正在检查", + "protected": "受保护", + "slave_for": "从属于", + "name": "名称", + "article": "文章", + "w_copy": "复制", + "for": "为", + "history": "历史", + "history2": "历史", + "history3": "历史", + "rule": "规则", + "rules": "规则", + "rules2": "规则", + "on": "开", + "dest": "目标", + "target": "目标", + "w_input": "输入", + "output": "输出", + "password": "密码", + "email": "电子邮箱", + "w_a": "一个", + "w_an": "一", + "key": "密钥", + "token": "令牌", + "channel": "通道", + "channels": "通道", + "job": "任务", + "cancel": "取消", + "repository": "存储库", + "init": "初始化", + "period": "时段", + "the": "这个", + "scan": "扫描", + "is_there": "是否存在", + "confirm": "确认", + "confirmation": "确认", + "one": "一", + "one2": "一", + "or": "或", + "upload": "上传", + "uploading": "正在上传", + "uploaded": "已上传", + "test": "测试", + "test2": "测试", + "disabled": "已禁用", + "via": "通过", + "web_panel": "网页面板", + "message": "消息", + "menu": "菜单", + "language": "语言", + "logout": "登出", + "last": "最后", + "last2": "最后", + "activity": "活动", + "never": "从不", + "is_online": "在线", + "is_offline": "离线", + "valid": "有效", + "remote": "远程", + "remote2": "远程", + "local": "本地", + "path": "路径", + "create": "创建", + "created": "已创建", + "creating": "正在创建", + "diff": "差异", + "diff2": "差异", + "diff3": "差异", + "master": "主机", + "slave": "从机", + "slaves": "从机", + "interface": "接口", + "as": "作为", + "stay": "保持", + "protection": "保护", + "return": "返回", + "cluster": "集群", + "existing": "存在", + "existing2": "存在", + "success": "成功", + "option": "选项", + "option2": "选项", + "options": "选项", + "template": "模板", + "templates": "模板", + "userlists": "用户列表", + "whitelist": "白名单", + "whitelists": "白名单", + "blacklist": "黑名单", + "blacklists": "黑名单", + "mode": "模式", + "balance": "平衡", + "health": "健康", + "cert": "证书", + "cert_name": "证书名称", + "certs": "证书", + "certs2": "证书", + "advanced": "高级", + "generate": "生成", + "generated": "已生成", + "server_template": "服务器模板", + "custom": "自定义", + "param": "参数", + "param2": "参数", + "params": "参数", + "of": "的", + "display": "显示", + "default_backend": "默认后端", + "existing": "存在", + "domain": "域名", + "domains": "域名", + "all": "全部", + "just": "仅", + "without": "无", + "work": "工作", + "working": "工作中", + "section": "部分", + "section2": "部分", + "use": "使用", + "available": "可用", + "external": "外部", + "in": "在", + "folder": "文件夹", + "folder2": "文件夹", + "clone": "克隆", + "date": "日期", + "time": "时间", + "page": "页面", + "pages": "页面", + "body": "正文", + "level": "级别", + "host": "主机", + "uptime": "正常运行时间", + "downtime": "停机时间", + "record_type": "记录类型", + "upstream": "上游", + "haproxy": "HAProxy", + "nginx": "NGINX", + "apache": "Apache", + "keepalived": "Keepalived", + "scan": "扫描", + "notify": "通知", + "notification": "通知", + "keeping": "保持", + "keep": "保持", + "close": "关闭", + "state": "状态", + "latest": "最新", + "cloud": "云", + "provider": "提供商", + "region": "区域", + "OS": "操作系统", + "created_at": "创建时间", + "edited_at": "编辑时间", + "instance_type": "实例类型", + "filter": "过滤器", + "rule_name": "规则名称", + "send": "发送", + "additions": "新增", + "deletions": "删除", + "recent": "最近", + "already": "已经", + "disable": "禁用", + "worker": "工作者", + "worker2": "工作者", + "processes": "进程", + "position": "位置", + "global": "全局", + "none": "无", + "headers": "头部", + "value": "值", + "if": "如果", + "then": "那么", + "response": "响应", + "average": "平均", + "average2": "平均", + "cert_expire": "证书过期", + "Hostname": "主机名", + "maps": "地图", + "method": "方法", + "tools": "工具", + "next": "下一步", + "agent": "代理", + "agent2": "代理", + "reconfigure": "重新配置", + "listener": "监听器", + "listeners": "监听器", + "weight": "权重", + "where": "哪里", + "shared": "共享", + "retries": "重试", + "address": "地址", + "calculate": "计算", + "calculator": "计算器", + "netmask": "子网掩码", + "theme": "主题", + "dark": "黑暗", + "light": "明亮", + "types": "类型", + "min": "最小值", + "length": "长度", +} +%}