mirror of https://github.com/Aidaho12/haproxy-wi
v8.2.2: Add security headers and HTTP/2 support for Nginx configuration in models, templates, and JS
- Introduced `NginxProxyPassSecurity` model for managing security headers and server token settings. - Enhanced templates and JavaScript to support `hide_server_tokens`, `security_headers`, and `hsts` options. - Updated Ansible and migration files to align with new security and HTTP/2 features.master v8.2.2
parent
9755fe1513
commit
20157572c6
|
@ -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.2').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.1').execute()
|
||||
except Exception as e:
|
||||
print(f"Error rolling back migration: {str(e)}")
|
||||
raise e
|
|
@ -475,6 +475,7 @@ class HaproxyConfigRequest(BaseModel):
|
|||
backends: Optional[str] = None
|
||||
circuit_breaking: Optional[HaproxyCircuitBreaking] = None
|
||||
action: Optional[Literal['save', 'test', 'reload', 'restart']] = "save"
|
||||
http2: Optional[bool] = False
|
||||
|
||||
|
||||
class HaproxyUserListUser(BaseModel):
|
||||
|
@ -645,6 +646,11 @@ class NginxLocationRequest(BaseModel):
|
|||
return values
|
||||
|
||||
|
||||
class NginxProxyPassSecurity(BaseModel):
|
||||
security_headers: bool = False
|
||||
hide_server_tokens: bool = False
|
||||
|
||||
|
||||
class NginxProxyPassRequest(BaseModel):
|
||||
locations: List[NginxLocationRequest]
|
||||
name: Union[IPvAnyAddress, DomainName]
|
||||
|
@ -655,9 +661,11 @@ class NginxProxyPassRequest(BaseModel):
|
|||
ssl_crt: Optional[str] = None
|
||||
ssl_key: Optional[str] = None
|
||||
ssl_offloading: Optional[bool] = False
|
||||
hsts: Optional[bool] = False
|
||||
http2: Optional[bool] = False
|
||||
action: Optional[Literal['save', 'test', 'reload', 'restart']] = 'reload'
|
||||
compression: bool = False
|
||||
compression_level: Annotated[int, Gt(0), Le(10)] = 6
|
||||
compression_min_length: Optional[int] = 1024
|
||||
compression_types: Optional[str] = 'text/plain text/css application/json application/javascript text/xml'
|
||||
security: Optional[NginxProxyPassSecurity]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{ config.type }} {{ config.name }}
|
||||
{% if config.binds != 'None' -%}
|
||||
{% for bind in config.binds -%}
|
||||
bind {{ bind.ip }}:{{ bind.port }} {% if config.ssl != 'None' and config.mode == 'http' and config.ssl.cert %} ssl crt {{cert_path}}/{{ config.ssl.cert }}{% endif %}
|
||||
bind {{ bind.ip }}:{{ bind.port }} {% if config.ssl != 'None' and config.mode == 'http' and config.ssl.cert %} ssl crt {{cert_path}}/{{ config.ssl.cert }} {% if config.http2 %}alpn h2,http/1.1{% endif %}{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
@ -35,6 +35,14 @@
|
|||
tcp-request connection reject if { src -f {{ service_dir }}/black/{{ config.blacklist }} }
|
||||
{% endif %}
|
||||
|
||||
{% if config.ddos -%}
|
||||
{{ ddos }}
|
||||
acl abuse sc1_http_req_rate({{ config.name }}) ge 100
|
||||
acl flag_abuser sc1_inc_gpc0({{ config.name }})
|
||||
tcp-request content reject if abuse flag_abuser
|
||||
# End config for DDOS
|
||||
{% endif -%}
|
||||
|
||||
{% if config.acls != 'None' -%}
|
||||
{% for acl in config.acls -%}
|
||||
{% if acl.acl_if in (1, 2) -%}
|
||||
|
@ -72,14 +80,6 @@
|
|||
{{ ssl_offloading }}
|
||||
{% endif -%}
|
||||
|
||||
{% if config.ddos -%}
|
||||
{{ ddos }}
|
||||
acl abuse sc1_http_req_rate({{ config.name }}) ge 100
|
||||
acl flag_abuser sc1_inc_gpc0({{ config.name }})
|
||||
tcp-request content reject if abuse flag_abuser
|
||||
# End config for DDOS
|
||||
{% endif -%}
|
||||
|
||||
{% if config.waf -%}
|
||||
filter spoe engine modsecurity config {{ service_dir }}/waf.conf
|
||||
http-request deny if { var(txn.modsec.code) -m int gt 0 }
|
||||
|
@ -102,7 +102,7 @@
|
|||
|
||||
{% if config.ssl != 'None' and config.mode == 'http' -%}
|
||||
{%- if config.ssl.ssl_check_backend -%}
|
||||
{%- set ssl_check_option = 'ssl verify' -%}
|
||||
{%- set ssl_check_option = 'ssl verify required' -%}
|
||||
{%- else -%}
|
||||
{%- set ssl_check_option = 'ssl verify none' -%}
|
||||
{%- endif -%}
|
||||
|
@ -130,12 +130,12 @@
|
|||
default-server observe {{ config.circuit_breaking.observe }} error-limit {{ config.circuit_breaking.error_limit }} on-error {{ config.circuit_breaking.on_error }}
|
||||
{% endif -%}
|
||||
|
||||
{% if config.backend_servers != 'None' and config.servers_template == 'None' -%}
|
||||
{% for backend in config.backend_servers -%}
|
||||
{%- if config.backend_servers != 'None' and config.servers_template == 'None' -%}
|
||||
{%- for backend in config.backend_servers -%}
|
||||
server {{ backend.server }} {{ backend.server }}:{{ backend.port }} port {{ backend.port_check }} {{ check_option }} {{ ssl_check_option }} maxconn {{ backend.maxconn }}{% if backend.send_proxy %} send-proxy{% endif %}{% if backend.backup %} backup {% endif %}
|
||||
|
||||
{% endfor -%}
|
||||
{% endif -%}
|
||||
{%- endif -%}
|
||||
|
||||
{% if config.servers_template != 'None' -%}
|
||||
server-template {{ config.servers_template.prefix }} {{ config.servers_template.count }} {{ config.servers_template.servers }}: {{ config.servers_template.port }} {{ check_option }}
|
||||
|
|
|
@ -4,7 +4,7 @@ server {
|
|||
listen {{ config.port }} ssl{% if config.http2 %} http2{% endif %};
|
||||
ssl_certificate {{ config.ssl_crt }};
|
||||
ssl_certificate_key {{ config.ssl_key }};
|
||||
{% if nginx_proxy.security.hsts %}
|
||||
{% if config.hsts %}
|
||||
add_header Strict-Transport-Security "max-age={{ nginx_proxy.security.hsts_max_age }}; includeSubDomains" always;
|
||||
{% endif %}
|
||||
{% else %}
|
||||
|
@ -29,11 +29,11 @@ server {
|
|||
{% endif -%}
|
||||
|
||||
|
||||
{% if nginx_proxy.security.hide_server_tokens %}
|
||||
{% if config.security.hide_server_tokens %}
|
||||
server_tokens off;
|
||||
{% endif %}
|
||||
|
||||
{% if nginx_proxy.security.security_headers %}
|
||||
{% if config.security.security_headers %}
|
||||
# Security headers
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
|
@ -150,7 +150,7 @@ proxy_cache_path {{ nginx_proxy.caching.zones[0].path }}
|
|||
inactive={{ nginx_proxy.caching.zones[0].inactive }};
|
||||
{% endif %}
|
||||
|
||||
{% if config.ssl_offloading -%}
|
||||
{% if config.ssl_offloading and config.scheme == 'https' -%}
|
||||
# HTTP to HTTPS redirect
|
||||
server {
|
||||
listen 80;
|
||||
|
|
|
@ -9,10 +9,7 @@ nginx_proxy:
|
|||
|
||||
# Security configurations
|
||||
security:
|
||||
hide_server_tokens: true # Hide Nginx version in headers
|
||||
hide_backend_headers: true # Hide backend server headers (e.g., X-Powered-By)
|
||||
security_headers: true # Enable security headers (X-Content-Type-Options, etc.)
|
||||
hsts: true # Enable HTTP Strict Transport Security
|
||||
hsts_max_age: 15768000 # HSTS duration in seconds (6 months)
|
||||
content_security_policy: "default-src 'self'" # Content Security Policy rules
|
||||
|
||||
|
|
|
@ -214,6 +214,7 @@ function getNginxFormData($form, form_name) {
|
|||
indexed_array['locations'] = [];
|
||||
indexed_array['backend_servers'] = [];
|
||||
indexed_array['name_aliases'] = [];
|
||||
indexed_array['security'] = {};
|
||||
let headers = [];
|
||||
|
||||
$.map(unindexed_array, function (n, i) {
|
||||
|
@ -244,6 +245,12 @@ function getNginxFormData($form, form_name) {
|
|||
} else {
|
||||
indexed_array['ssl_offloading'] = false;
|
||||
}
|
||||
} else if (n['name'] === 'hsts') {
|
||||
if ($('input[name="hsts"]').is(':checked')) {
|
||||
indexed_array['hsts'] = true;
|
||||
} else {
|
||||
indexed_array['hsts'] = false;
|
||||
}
|
||||
} else if (n['name'] === 'http2') {
|
||||
if ($('input[name="http2"]').is(':checked')) {
|
||||
indexed_array['http2'] = true;
|
||||
|
@ -261,6 +268,15 @@ function getNginxFormData($form, form_name) {
|
|||
}
|
||||
indexed_array['name_aliases'].push(name);
|
||||
});
|
||||
let hide_server_tokens = false;
|
||||
let security_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 (){
|
||||
let server = $(this).children("input[name='servers']").val();
|
||||
if (server === undefined || server === '') {
|
||||
|
@ -274,7 +290,7 @@ 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'
|
||||
'headers_res', 'header_name', 'header_value', 'upstream', 'server', 'name_alias', 'hide_server_tokens', 'security_headers'
|
||||
]
|
||||
for (let element of elementsForDelete) {
|
||||
delete indexed_array[element]
|
||||
|
|
|
@ -105,6 +105,14 @@ function openSection(section) {
|
|||
} else {
|
||||
$('#'+section_type+'_whitelist_checkbox').prop("checked", false);
|
||||
}
|
||||
if (data.ssl) {
|
||||
if ($("#https-" + section_type).is(':checked')) {
|
||||
$("#https-hide-" + section_type).show("fast");
|
||||
$("#path-cert-" + section_type).val(data.ssl['cert']);
|
||||
} else {
|
||||
$("#https-hide-" + section_type).hide("fast");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (section_type === 'listen' || section_type === 'backend') {
|
||||
if (data.config.backend_servers) {
|
||||
|
@ -460,12 +468,10 @@ function getFormData($form, form_name) {
|
|||
}
|
||||
} else if (n['name'] === 'ssl') {
|
||||
if ($('input[name="ssl"]').is(':checked')) {
|
||||
let cert = $('input[name="cert"]').val();
|
||||
let ssl_check_backend = true;
|
||||
if ($('input[name="ssl-check"]').is(':checked')) {
|
||||
ssl_check_backend = 0;
|
||||
} else {
|
||||
ssl_check_backend = true;
|
||||
let cert = $form.find('input[name="cert"]').val();
|
||||
if ($form.find('input[name="ssl-check"]').is(':checked')) {
|
||||
ssl_check_backend = false;
|
||||
}
|
||||
indexed_array['ssl'] = {cert, ssl_check_backend};
|
||||
}
|
||||
|
@ -509,6 +515,10 @@ function getFormData($form, form_name) {
|
|||
if ($('input[name="cache"]').is(':checked')) {
|
||||
indexed_array['cache'] = true;
|
||||
}
|
||||
} else if (n['name'] === 'http2') {
|
||||
if ($('input[name="http2"]').is(':checked')) {
|
||||
indexed_array['http2'] = true;
|
||||
}
|
||||
} else if (n['name'] === 'circuit_breaking') {
|
||||
if ($('input[name="circuit_breaking"]').is(':checked')) {
|
||||
let observe = $('select[name="circuit_breaking_observe"] option:selected').val();
|
||||
|
@ -805,6 +815,23 @@ function openNginxSection(section) {
|
|||
$("#scheme").selectmenu();
|
||||
$("#scheme").selectmenu('refresh');
|
||||
}
|
||||
if (data.security) {
|
||||
if (data.security.hide_server_tokens) {
|
||||
$('#hide_server_tokens').prop("checked", true);
|
||||
} else {
|
||||
$('#hide_server_tokens').prop("checked", false);
|
||||
}
|
||||
if (data.security.security_headers) {
|
||||
$('#security_headers').prop("checked", true);
|
||||
} else {
|
||||
$('#security_headers').prop("checked", false);
|
||||
}
|
||||
}
|
||||
if (data.hsts) {
|
||||
$('#hsts').prop("checked", true);
|
||||
} else {
|
||||
$('#hsts').prop("checked", false);
|
||||
}
|
||||
}
|
||||
$(section_id + ' select[name="server"]').selectmenu();
|
||||
$(section_id + ' select[name="server"]').selectmenu('refresh');
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
<div id="https-hide-frontend" style="display: none;">
|
||||
<br /><span class="tooltip tooltipTop">{{lang.words.enter2|title()}} {{lang.words.name}} {{lang.words.of}} pem {{lang.words.file2}}, {{lang.add_page.desc.press_down}}:</span><br />
|
||||
{{ input('path-cert-frontend', name="cert", placeholder="some_cert.pem", size='39') }}
|
||||
<p>{{ checkbox('frontend-http2', name='http2', title=lang.add_page.desc.enable_http2, desc='Enable HTTP2') }}</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
<br /><span class="tooltip tooltipTop">{{lang.words.enter2|title()}} {{lang.words.name}} {{lang.words.of}} pem {{lang.words.file2}}, {{lang.add_page.desc.press_down}}:</span><br />
|
||||
{{ input('path-cert-listen', name="cert", placeholder="some_cert.pem", size='39') }}<br />
|
||||
<label for="ssl-check-listen" style="margin-top: 5px;">{{lang.add_page.buttons.disable_ssl_verify}}</label><input type="checkbox" id="ssl-check-listen" name="ssl-check" value="ssl-check" checked>
|
||||
<p>{{ checkbox('listen-http2', name='http2', title=lang.add_page.desc.enable_http2, desc='Enable HTTP2') }}</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -58,7 +58,9 @@ Timeouts: Timeouts (proxy_connect_timeout).
|
|||
<br>
|
||||
<br>
|
||||
<div id="hide-scheme" style="display: none;">
|
||||
{{ checkbox('ssl_offloading', title=lang.add_page.desc.http_https, desc='HTTP->HTTPS') }}<br>
|
||||
{{ checkbox('ssl_offloading', title=lang.add_page.desc.http_https, desc='HTTP->HTTPS') }}
|
||||
{{ checkbox('hsts', title=lang.words.enable|title() + ' HSTS', desc='HSTS') }}
|
||||
<br>
|
||||
<span class="tooltip tooltipTop">{{lang.words.enter2|title()}} {{lang.words.name}} {{lang.words.of}} {{lang.words.file2}}, {{lang.add_page.desc.press_down}}:</span><br />
|
||||
{{ input('ssl_key', placeholder='cert.key') }}
|
||||
{{ input('ssl_crt', placeholder='cert.crt') }}
|
||||
|
@ -111,6 +113,16 @@ Timeouts: Timeouts (proxy_connect_timeout).
|
|||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="addName">
|
||||
<td class="addName">{{ lang.words.security|title() }}:</td>
|
||||
<td class="addOption">
|
||||
<div id="security-options">
|
||||
{% 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>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="addName">{{ lang.words.compression|title() }}:</td>
|
||||
<td class="addOption">
|
||||
|
|
|
@ -343,6 +343,8 @@
|
|||
"ssh_passphrase": "SSH key passphrase",
|
||||
"check_interval": "Check interval.",
|
||||
"check_interval_title": "Check interval. In seconds.",
|
||||
"hide_server_tokens": "Hide server tokens",
|
||||
"security_headers": "Enable security headers",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -354,6 +356,8 @@
|
|||
%}
|
||||
{% set add_page = {
|
||||
"desc": {
|
||||
"security_headers": "Enable security headers (X-Content-Type-Options, etc.)",
|
||||
"hide_server_tokens": "Hide Nginx version in headers",
|
||||
"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",
|
||||
|
@ -975,5 +979,6 @@
|
|||
"types": "types",
|
||||
"min": "minimum",
|
||||
"length": "length",
|
||||
"security": "security",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -330,6 +330,8 @@
|
|||
"ssh_passphrase": "Frase de paso para la clave SSH",
|
||||
"check_interval": "Intervalo de comprobación.",
|
||||
"check_interval_title": "Intervalo de comprobación. En segundos.",
|
||||
"hide_server_tokens": "Ocultar tokens del servidor",
|
||||
"security_headers": "Habilitar encabezados de seguridad",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -341,6 +343,8 @@
|
|||
%}
|
||||
{% set add_page = {
|
||||
"desc": {
|
||||
"security_headers": "Habilitar encabezados de seguridad (X-Content-Type-Options, etc.)",
|
||||
"hide_server_tokens": "Ocultar la versión de Nginx en los encabezados",
|
||||
"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",
|
||||
|
@ -959,6 +963,7 @@
|
|||
"light": "claro",
|
||||
"types": "tipos",
|
||||
"min": "mínimo",
|
||||
"length": "longitud"
|
||||
"length": "longitud",
|
||||
"security": "seguridad",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -330,6 +330,8 @@
|
|||
"ssh_passphrase": "Phrase secrète de la clé SSH",
|
||||
"check_interval": "Vérifiez l'intervalle",
|
||||
"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é",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -341,6 +343,8 @@
|
|||
%}
|
||||
{% set add_page = {
|
||||
"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",
|
||||
"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",
|
||||
|
@ -961,5 +965,6 @@
|
|||
"types": "types",
|
||||
"min": "minimum",
|
||||
"length": "longueur",
|
||||
"security": "sécurité",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -330,6 +330,8 @@
|
|||
"ssh_passphrase": "Senha da chave SSH",
|
||||
"check_interval": "Verifique o intervalo",
|
||||
"check_interval_title": "Verifique o intervalo. Em segundos.",
|
||||
"hide_server_tokens": "Ocultar tokens do servidor",
|
||||
"security_headers": "Habilitar cabeçalhos de segurança",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -341,6 +343,8 @@
|
|||
%}
|
||||
{% set add_page = {
|
||||
"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",
|
||||
"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",
|
||||
|
@ -960,5 +964,6 @@
|
|||
"types": "tipos",
|
||||
"min": "mínima",
|
||||
"length": "comprimento",
|
||||
"security": "segurança",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -343,6 +343,8 @@
|
|||
"ssh_passphrase": "Ключевая фраза SSH",
|
||||
"check_interval": "Интервал проверки",
|
||||
"check_interval_title": "Интервал проверки. В секундах.",
|
||||
"hide_server_tokens": "Скрыть токены сервера",
|
||||
"security_headers": "Включить заголовки безопасности",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -354,6 +356,8 @@
|
|||
%}
|
||||
{% set add_page = {
|
||||
"desc": {
|
||||
"security_headers": "Включить заголовки безопасности (X-Content-Type-Options и т. д.)",
|
||||
"hide_server_tokens": "Скрыть версию Nginx в заголовках",
|
||||
"port_check": "Базовая проверка работоспособности на уровне TCP пытается подключиться к TCP-порту сервера. Проверка действительна, когда сервер отвечает пакетом SYN/ACK.",
|
||||
"maxconn": "Общее количество разрешенных подключений для всего процесса. Это не позволяет процессу одновременно принимать слишком много подключений, что защищает его от нехватки памяти.",
|
||||
"server_template": "Создать список серверов из шаблона",
|
||||
|
@ -975,5 +979,6 @@
|
|||
"types": "типы",
|
||||
"min": "минимальная",
|
||||
"length": "длина",
|
||||
"security": "безопасность",
|
||||
}
|
||||
%}
|
||||
|
|
|
@ -330,6 +330,8 @@
|
|||
"ssh_passphrase": "SSH 密钥密码",
|
||||
"check_interval": "检查间隔。",
|
||||
"check_interval_title": "检查间隔(以秒为单位)。",
|
||||
"hide_server_tokens": "隐藏服务器令牌",
|
||||
"security_headers": "启用安全标头",
|
||||
}
|
||||
%}
|
||||
{% set roles = {
|
||||
|
@ -341,6 +343,8 @@
|
|||
%}
|
||||
{% set add_page = {
|
||||
"desc": {
|
||||
"security_headers": "启用安全标头(X-Content-Type-Options 等)",
|
||||
"hide_server_tokens": "在标头中隐藏 Nginx 版本",
|
||||
"port_check": "基本的 TCP 层健康检查尝试连接到服务器的 TCP 端口。当服务器返回 SYN/ACK 数据包时,检查被认为是成功的。",
|
||||
"maxconn": "进程允许的总连接数。这可以防止进程接受过多连接,从而防止内存耗尽。",
|
||||
"server_template": "根据模板创建服务器列表。",
|
||||
|
@ -960,5 +964,6 @@
|
|||
"types": "类型",
|
||||
"min": "最小值",
|
||||
"length": "长度",
|
||||
"security": "安全",
|
||||
}
|
||||
%}
|
||||
|
|
Loading…
Reference in New Issue