nginx: путь панели и подписки перед сборкой конфига – только буквы, цифры, _ и -
XUI_WEB_BASE_PATH из install-result.env (при --restore – из копии) шёл в
«location ... {» как есть: строка с фигурными скобками добавляла в nginx
чужие директивы. Значение теперь проверяется при --restore (прошлая правка)
и ещё раз там, где собирается nginx: setup_nginx в 3x-ui.sh, kit net panel
и пути подписки в kit.
This commit is contained in:
@@ -1464,6 +1464,9 @@ setup_nginx() {
|
||||
elif $st.network == "grpc" then ["grpc", $st.grpcSettings.serviceName, .port]
|
||||
else empty end | @tsv' <<<"$list")
|
||||
|
||||
# Пути панели (из install-result.env, при --restore – из копии) и подписки попадают в конфиг nginx.
|
||||
[[ $XUI_WEB_BASE_PATH =~ ^/?[A-Za-z0-9_-]{1,64}/?$ && $SUB_PATH =~ ^/[A-Za-z0-9_-]{1,64}/$ ]] \
|
||||
|| die "Странный путь панели или подписки ($XUI_ENV) – не собираю nginx."
|
||||
local panel_path=/${XUI_WEB_BASE_PATH#/}
|
||||
panel_path=${panel_path%/}/
|
||||
{
|
||||
|
||||
+9
-3
@@ -2096,6 +2096,13 @@ sys.stdout.write(text[:steal[0]] + new + text[steal[1]:])
|
||||
PY
|
||||
}
|
||||
|
||||
# Путь панели (install-result.env) и подписки (kit.env) идут в конфиг nginx: только буквы, цифры, _ и -.
|
||||
panel_web_path() {
|
||||
[[ ${XUI_WEB_BASE_PATH:-} =~ ^/?[A-Za-z0-9_-]{1,64}/?$ && ${SUB_PATH:-} =~ ^/[A-Za-z0-9_-]{1,64}/$ ]] || return 1
|
||||
local p=/${XUI_WEB_BASE_PATH#/}
|
||||
echo "${p%/}/"
|
||||
}
|
||||
|
||||
kit_env_set() { # ключ значение: меняет или добавляет строку в /etc/kit/kit.env
|
||||
python3 - "$KIT_ENV" "$1" "$2" <<'PY'
|
||||
import re, shlex, sys
|
||||
@@ -2130,8 +2137,7 @@ sub_extra_sync() {
|
||||
tmp=$(mktemp); bak=$(mktemp); cp -p "$PANEL_CONF" "$bak"
|
||||
if panel_conf_py addloc "$PANEL_CONF" "$SUB_PATH" "${ex[@]}" >"$tmp" && [[ -s $tmp ]]; then
|
||||
cat "$tmp" >"$PANEL_CONF"
|
||||
if [[ ${PANEL_ON:-ip} == domain ]]; then
|
||||
panel_path=/${XUI_WEB_BASE_PATH#/}; panel_path=${panel_path%/}/
|
||||
if [[ ${PANEL_ON:-ip} == domain ]] && panel_path=$(panel_web_path); then
|
||||
panel_conf_py render "$PANEL_CONF" domain "$SUB_PATH" "$panel_path" "${ex[@]}" >"$tmp" && [[ -s $tmp ]] && cat "$tmp" >"$PANEL_CONF"
|
||||
fi
|
||||
if nginx -t >/dev/null 2>&1; then systemctl reload nginx
|
||||
@@ -2155,7 +2161,7 @@ net_panel() { # [domain|ip]
|
||||
fi
|
||||
[[ $want == domain || $want == ip ]] || die "kit net panel [domain|ip]"
|
||||
[[ $want != "$cur" ]] || { say "Уже так: панель и подписка по $([[ $want == domain ]] && echo "домену $domain" || echo "IP")."; return 0; }
|
||||
panel_path=/${XUI_WEB_BASE_PATH#/}; panel_path=${panel_path%/}/
|
||||
panel_path=$(panel_web_path) || die "Странный путь панели или подписки в $XUI_ENV или $KIT_ENV – не трогаю nginx."
|
||||
if [[ $want == domain ]]; then
|
||||
getent ahostsv4 "$domain" 2>/dev/null | awk '{print $1}' | grep -qx "$(host_ip)" || die "Домен $domain не указывает на этот сервер ($(host_ip)). Исправьте A-запись и повторите."
|
||||
[[ -s $cert && -s $key ]] || die "Нет сертификата домена ($cert) – не трогаю nginx."
|
||||
|
||||
@@ -124,5 +124,31 @@ class SafeEnv(unittest.TestCase):
|
||||
self.rejected("kit-backup.env", GOOD["kit-backup.env"] + bad + "\n")
|
||||
|
||||
|
||||
kit_src = open(os.path.join(root, "scripts", "kit.sh"), encoding="utf-8").read()
|
||||
PANEL_PATH = re.search(r"^panel_web_path\(\) \{.*?^\}\n", kit_src, re.S | re.M).group(0)
|
||||
|
||||
|
||||
class NginxPaths(unittest.TestCase):
|
||||
"""Путь панели и подписки перед сборкой nginx (kit.sh panel_web_path, 3x-ui.sh setup_nginx)."""
|
||||
|
||||
def path(self, base, sub="/AbC123/"):
|
||||
r = subprocess.run(["bash", "-c", PANEL_PATH + 'XUI_WEB_BASE_PATH=$1 SUB_PATH=$2\npanel_web_path || echo NO', "t", base, sub],
|
||||
capture_output=True, text=True)
|
||||
return r.stdout.strip()
|
||||
|
||||
def test_good(self):
|
||||
self.assertEqual(self.path("AbCdEf123456789012"), "/AbCdEf123456789012/")
|
||||
self.assertEqual(self.path("/AbC_d-1/"), "/AbC_d-1/")
|
||||
|
||||
def test_bad(self):
|
||||
for bad in ("x/ { return 200; } location /zz", "", "/", "a/b", "a;b", "a\nb", "$(id)", "a" * 65):
|
||||
self.assertEqual(self.path(bad), "NO", bad)
|
||||
for bad in ("/a b/", "/a/ { }", "", "/../"):
|
||||
self.assertEqual(self.path("AbC", bad), "NO", bad)
|
||||
|
||||
def test_setup_nginx_checks(self):
|
||||
self.assertIn('[[ $XUI_WEB_BASE_PATH =~ ^/?[A-Za-z0-9_-]{1,64}/?$ && $SUB_PATH =~ ^/[A-Za-z0-9_-]{1,64}/$ ]]', src)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user