mirror of https://github.com/Aidaho12/haproxy-wi
v8.2.3: Add backend header hiding option and improve UDP listener updates
- Introduced `hide_backend_headers` option in Nginx configuration for enhanced security. - Updated models, templates, and JavaScript to support `hide_backend_headers`. - Improved UDP listener rendering logic by dynamically fetching and syncing listeners via AJAX. - Added new database migration to update version to `8.2.3`.master
parent
20157572c6
commit
dccc2b3e20
|
@ -0,0 +1,22 @@
|
|||
from playhouse.migrate import *
|
||||
from app.modules.db.db_model import connect, Version
|
||||
|
||||
migrator = connect(get_migrator=1)
|
||||
|
||||
|
||||
def up():
|
||||
"""Apply the migration."""
|
||||
try:
|
||||
Version.update(version='8.2.3').execute()
|
||||
except Exception as e:
|
||||
print(f"Error updating version: {str(e)}")
|
||||
raise e
|
||||
|
||||
|
||||
def down():
|
||||
"""Roll back the migration."""
|
||||
try:
|
||||
Version.update(version='8.2.2').execute()
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -135,7 +135,7 @@ location {{ location.location }} {
|
|||
gzip_proxied any;
|
||||
{% endif %}
|
||||
|
||||
{% if nginx_proxy.security.hide_backend_headers %}
|
||||
{% if config.security.hide_backend_headers %}
|
||||
# Hide backend headers
|
||||
proxy_hide_header X-Powered-By;
|
||||
proxy_hide_header Server;
|
||||
|
|
|
@ -9,7 +9,6 @@ nginx_proxy:
|
|||
|
||||
# Security configurations
|
||||
security:
|
||||
hide_backend_headers: true # Hide backend server headers (e.g., X-Powered-By)
|
||||
hsts_max_age: 15768000 # HSTS duration in seconds (6 months)
|
||||
content_security_policy: "default-src 'self'" # Content Security Policy rules
|
||||
|
||||
|
|
|
@ -237,7 +237,14 @@ function getNginxFormData($form, form_name) {
|
|||
let header = {action, name, value};
|
||||
headers.push(header);
|
||||
});
|
||||
let location_config = {location, proxy_connect_timeout, proxy_read_timeout, proxy_send_timeout, headers, upstream};
|
||||
let location_config = {
|
||||
location,
|
||||
proxy_connect_timeout,
|
||||
proxy_read_timeout,
|
||||
proxy_send_timeout,
|
||||
headers,
|
||||
upstream
|
||||
};
|
||||
indexed_array['locations'].push(location_config)
|
||||
} else if (n['name'] === 'ssl_offloading') {
|
||||
if ($('input[name="ssl_offloading"]').is(':checked')) {
|
||||
|
@ -261,7 +268,7 @@ function getNginxFormData($form, form_name) {
|
|||
indexed_array[n['name']] = n['value'];
|
||||
}
|
||||
});
|
||||
$('#name_alias_div p').each(function (){
|
||||
$('#name_alias_div p').each(function () {
|
||||
let name = $(this).children("input[name='name_alias']").val();
|
||||
if (name === undefined || name === '') {
|
||||
return;
|
||||
|
@ -270,14 +277,22 @@ function getNginxFormData($form, form_name) {
|
|||
});
|
||||
let hide_server_tokens = false;
|
||||
let security_headers = false;
|
||||
let hide_backend_headers = false;
|
||||
if ($('#hide_server_tokens').is(':checked')) {
|
||||
hide_server_tokens = true;
|
||||
}
|
||||
if ($('#security_headers').is(':checked')) {
|
||||
security_headers = true;
|
||||
}
|
||||
indexed_array['security'] = {'hide_server_tokens': hide_server_tokens, 'security_headers': security_headers};
|
||||
$('#'+form_name+' span[name="add_servers"] p').each(function (){
|
||||
if ($('#hide_backend_headers').is(':checked')) {
|
||||
hide_backend_headers = true;
|
||||
}
|
||||
indexed_array['security'] = {
|
||||
'hide_server_tokens': hide_server_tokens,
|
||||
'security_headers': security_headers,
|
||||
'hide_backend_headers': hide_backend_headers
|
||||
};
|
||||
$('#' + form_name + ' span[name="add_servers"] p').each(function () {
|
||||
let server = $(this).children("input[name='servers']").val();
|
||||
if (server === undefined || server === '') {
|
||||
return;
|
||||
|
@ -290,7 +305,8 @@ function getNginxFormData($form, form_name) {
|
|||
});
|
||||
let elementsForDelete = [
|
||||
'servers', 'server_port', 'max_fails', 'fail_timeout', 'proxy_connect_timeout', 'proxy_read_timeout', 'proxy_send_timeout',
|
||||
'headers_res', 'header_name', 'header_value', 'upstream', 'server', 'name_alias', 'hide_server_tokens', 'security_headers'
|
||||
'headers_res', 'header_name', 'header_value', 'upstream', 'server', 'name_alias', 'hide_server_tokens', 'security_headers',
|
||||
'hide_backend_headers'
|
||||
]
|
||||
for (let element of elementsForDelete) {
|
||||
delete indexed_array[element]
|
||||
|
|
|
@ -826,6 +826,11 @@ function openNginxSection(section) {
|
|||
} else {
|
||||
$('#security_headers').prop("checked", false);
|
||||
}
|
||||
if (data.security.hide_backend_headers) {
|
||||
$('#hide_backend_headers').prop("checked", true);
|
||||
} else {
|
||||
$('#hide_backend_headers').prop("checked", false);
|
||||
}
|
||||
}
|
||||
if (data.hsts) {
|
||||
$('#hsts').prop("checked", true);
|
||||
|
|
|
@ -615,3 +615,33 @@ function checkUdpBackendStatus(listener_id, backend_ip) {
|
|||
}
|
||||
});
|
||||
}
|
||||
function getUdpListeners() {
|
||||
$.ajax({
|
||||
url: api_prefix + "/udp/listeners",
|
||||
success: function (data) {
|
||||
let clusters = document.querySelectorAll('.up-pannel > [id^="listener-"]');
|
||||
let clusterNumbers = Array.from(clusters).map(div =>
|
||||
parseInt(div.id.replace('listener-', ''), 10)
|
||||
);
|
||||
if (data.status === 'failed') {
|
||||
toastr.error(data.error);
|
||||
return;
|
||||
}
|
||||
if (data.length > 0) {
|
||||
const dataIds = data.map(item => item.id);
|
||||
const idsToDelete = clusterNumbers.filter(id => !dataIds.includes(id));
|
||||
|
||||
for (const [key, value] of Object.entries(data)) {
|
||||
if (!clusterNumbers.includes(value.id)) {
|
||||
getUDPListener(value.id, true);
|
||||
} else {
|
||||
getUDPListener(value.id, false);
|
||||
}
|
||||
}
|
||||
for (let id of idsToDelete) {
|
||||
$('#listener-' + id).remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -120,6 +120,7 @@ Timeouts: Timeouts (proxy_connect_timeout).
|
|||
{% set enable_sec_headers = lang.words.enable|title() + ' ' + lang.words.security + ' ' + lang.words.headers %}
|
||||
<p>{{ checkbox('hide_server_tokens', title=lang.add_page.desc.hide_server_tokens, desc=lang.phrases.hide_server_tokens, checked='checked') }}</p>
|
||||
<p>{{ checkbox('security_headers', title=lang.add_page.desc.security_headers, desc=lang.phrases.security_headers, checked='checked') }}</p>
|
||||
<p>{{ checkbox('hide_backend_headers', title=lang.add_page.desc.hide_backend_headers, desc=lang.phrases.hide_backend_headers, checked='checked') }}</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -345,6 +345,7 @@
|
|||
"check_interval_title": "Check interval. In seconds.",
|
||||
"hide_server_tokens": "Hide server tokens",
|
||||
"security_headers": "Enable security headers",
|
||||
"hide_backend_headers": "Hide backend server headers",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -358,6 +359,7 @@
|
|||
"desc": {
|
||||
"security_headers": "Enable security headers (X-Content-Type-Options, etc.)",
|
||||
"hide_server_tokens": "Hide Nginx version in headers",
|
||||
"hide_backend_headers": "Hide backend server headers (e.g., X-Powered-By)",
|
||||
"port_check": "A basic TCP-layer health check tries to connect to the server's TCP port. The check is valid when the server answers with a SYN/ACK packet.",
|
||||
"maxconn": "The total number of connections allowed, process-wide. This stops the process from accepting too many connections at once, which safeguards it from running out of memory.",
|
||||
"server_template": "Create the list of servers from the template",
|
||||
|
|
|
@ -332,6 +332,7 @@
|
|||
"check_interval_title": "Intervalo de comprobación. En segundos.",
|
||||
"hide_server_tokens": "Ocultar tokens del servidor",
|
||||
"security_headers": "Habilitar encabezados de seguridad",
|
||||
"hide_backend_headers": "Ocultar los encabezados del servidor backend",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -345,6 +346,7 @@
|
|||
"desc": {
|
||||
"security_headers": "Habilitar encabezados de seguridad (X-Content-Type-Options, etc.)",
|
||||
"hide_server_tokens": "Ocultar la versión de Nginx en los encabezados",
|
||||
"hide_backend_headers": "Ocultar los encabezados del servidor backend (por ejemplo, X-Powered-By)",
|
||||
"port_check": "Una verificación básica a nivel TCP intenta conectarse al puerto TCP del servidor. La verificación es válida cuando el servidor responde con un paquete SYN/ACK.",
|
||||
"maxconn": "Número total de conexiones permitidas a nivel de proceso. Esto evita aceptar demasiadas conexiones a la vez, protegiendo de quedarse sin memoria.",
|
||||
"server_template": "Crear la lista de servidores desde la plantilla",
|
||||
|
|
|
@ -332,6 +332,7 @@
|
|||
"check_interval_title": "Vérifiez l'intervalle. En secondes.",
|
||||
"hide_server_tokens": "Masquer les jetons du serveur",
|
||||
"security_headers": "Activer les en-têtes de sécurité",
|
||||
"hide_backend_headers": "Masquer les en-têtes du serveur principal",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -345,6 +346,7 @@
|
|||
"desc": {
|
||||
"security_headers": "Activer les en-têtes de sécurité (X-Content-Type-Options, etc.)",
|
||||
"hide_server_tokens": "Masquer la version Nginx dans les en-têtes",
|
||||
"hide_backend_headers": "Masquer les en-têtes du serveur principal (par exemple, X-Powered-By)",
|
||||
"port_check": "Un contrôle de base de la couche TCP tente de se connecter au port TCP du serveur. Le contrôle est valide lorsque le serveur répond par un paquet SYN/ACK.",
|
||||
"maxconn": "Le nombre total de connexions autorisées, à l\'échelle du processus. Cela empêche le processus d\'accepter trop de connexions à la fois, ce qui lui évite de manquer de mémoire.",
|
||||
"server_template": "Créez la liste des serveurs à partir du modèle",
|
||||
|
|
|
@ -332,6 +332,7 @@
|
|||
"check_interval_title": "Verifique o intervalo. Em segundos.",
|
||||
"hide_server_tokens": "Ocultar tokens do servidor",
|
||||
"security_headers": "Habilitar cabeçalhos de segurança",
|
||||
"hide_backend_headers": "Ocultar cabeçalhos do servidor de backend",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -345,6 +346,7 @@
|
|||
"desc": {
|
||||
"security_headers": "Habilitar cabeçalhos de segurança (X-Content-Type-Options, etc.)",
|
||||
"hide_server_tokens": "Ocultar versão do Nginx nos cabeçalhos",
|
||||
"hide_backend_headers": "Ocultar cabeçalhos do servidor de backend (por exemplo, X-Powered-By)",
|
||||
"port_check": "a verificação de integridade básica do nivel TCP tenta se conectar à porta TCP do servidor. A verificação é válida quando o servidor responde com um pacote SYN/ACK",
|
||||
"maxconn": "número total de conexões permitidas. Isso impede que o processo aceite muitas conexões de uma só vez, o que o protege de ficar sem memória.",
|
||||
"server_template": "Criar uma lista de servidores de um modelo",
|
||||
|
|
|
@ -345,6 +345,7 @@
|
|||
"check_interval_title": "Интервал проверки. В секундах.",
|
||||
"hide_server_tokens": "Скрыть токены сервера",
|
||||
"security_headers": "Включить заголовки безопасности",
|
||||
"hide_backend_headers": "Скрыть заголовки внутреннего сервера",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -358,6 +359,7 @@
|
|||
"desc": {
|
||||
"security_headers": "Включить заголовки безопасности (X-Content-Type-Options и т. д.)",
|
||||
"hide_server_tokens": "Скрыть версию Nginx в заголовках",
|
||||
"hide_backend_headers": "Скрыть заголовки внутреннего сервера (например, X-Powered-By)",
|
||||
"port_check": "Базовая проверка работоспособности на уровне TCP пытается подключиться к TCP-порту сервера. Проверка действительна, когда сервер отвечает пакетом SYN/ACK.",
|
||||
"maxconn": "Общее количество разрешенных подключений для всего процесса. Это не позволяет процессу одновременно принимать слишком много подключений, что защищает его от нехватки памяти.",
|
||||
"server_template": "Создать список серверов из шаблона",
|
||||
|
|
|
@ -332,6 +332,7 @@
|
|||
"check_interval_title": "检查间隔(以秒为单位)。",
|
||||
"hide_server_tokens": "隐藏服务器令牌",
|
||||
"security_headers": "启用安全标头",
|
||||
"hide_backend_headers": "隐藏后端服务器标头",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -345,6 +346,7 @@
|
|||
"desc": {
|
||||
"security_headers": "启用安全标头(X-Content-Type-Options 等)",
|
||||
"hide_server_tokens": "在标头中隐藏 Nginx 版本",
|
||||
"hide_backend_headers": "隐藏后端服务器标头(例如 X-Powered-By)",
|
||||
"port_check": "基本的 TCP 层健康检查尝试连接到服务器的 TCP 端口。当服务器返回 SYN/ACK 数据包时,检查被认为是成功的。",
|
||||
"maxconn": "进程允许的总连接数。这可以防止进程接受过多连接,从而防止内存耗尽。",
|
||||
"server_template": "根据模板创建服务器列表。",
|
||||
|
|
|
@ -22,11 +22,7 @@
|
|||
{% if g.user_params['role'] <= 3 %}
|
||||
<div class="add-button add-button-big" title="{{lang.words.create|title()}} UDP {{ lang.words.listener }}" onclick="createUDPListener();">+ {{lang.words.create|title()}} UDP {{ lang.words.listener }}</div>
|
||||
{% endif %}
|
||||
<div class="up-pannel" class="sortable">
|
||||
{% for listener in listeners %}
|
||||
<div id="listener-{{listener.id}}" class="div-server-hapwi animated-background"></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="up-pannel" class="sortable"></div>
|
||||
<div id="create-udp-step-1" style="display: none;">
|
||||
<table class="overview" id="create-udp-step-1-overview"
|
||||
title="{{lang.words.create|title()}} UDP {{ lang.words.listener }}"
|
||||
|
@ -179,9 +175,8 @@
|
|||
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:3px 12px 20px 0;"></span>{{lang.phrases.are_you_sure}}</p>
|
||||
</div>
|
||||
<script>
|
||||
{% for listener in listeners %}
|
||||
getUDPListener('{{listener.id}}');
|
||||
{% endfor %}
|
||||
getUdpListeners();
|
||||
setInterval(getUdpListeners, 60000);
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -105,7 +105,6 @@ class UDPListener(MethodView):
|
|||
else:
|
||||
if not listener_id:
|
||||
kwargs = {
|
||||
'listeners': udp_sql.select_listeners(g.user_params['group_id']),
|
||||
'lang': g.user_params['lang'],
|
||||
'clusters': ha_sql.select_clusters(g.user_params['group_id']),
|
||||
'is_needed_tool': common.is_tool('ansible'),
|
||||
|
|
Loading…
Reference in New Issue