fix(launcher): показывать ошибку ingest MikroTik и повторять без src-address
Docker / build (push) Failing after 23s
Docker / build (push) Failing after 23s
RouterOS скрывает HTTP 4xx как fetch error. ros-5 печатает код и тело ответа, затем повторяет POST без src-address. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -94,7 +94,7 @@ vps-tracker/
|
||||
|
||||
Ручная проверка с VPS: `curl -fsSL https://vt.shnt.top/cc | bash` (тот же контейнер, Traefik dual Host).
|
||||
Раз в сутки: `curl -fsSL https://vt.shnt.top/cc | bash -s -- --daily` (cron, свежий HMAC-токен на каждый запуск).
|
||||
MikroTik 7.22+: `:global vt-srcIp "1.2.3.4"; /tool fetch url="https://vt.shnt.top/cc.rsc" dst-path=vt-cc.rsc; /import file-name=vt-cc.rsc` (ежедневно: `?daily=1`; все пробы через `src-address` этого IP).
|
||||
MikroTik 7.22+: `:global "vt-srcIp" "1.2.3.4"; /tool fetch url="https://vt.shnt.top/cc.rsc" dst-path=vt-cc.rsc; /import file-name=vt-cc.rsc` (ежедневно: `?daily=1`; все пробы через `src-address` этого IP).
|
||||
|
||||
- **Vendor:** `apps/api/scripts/censorcheck/censorcheck.sh` (pin SHA `12c5839`, MIT)
|
||||
- **Launcher:** `GET /cc` минтит HMAC ingest-токен (TTL 20 мин); по `/etc/os-release` ставит `jq`/`dig`/`column` без prompt; прогресс-бар в stderr; `GET /cc/vendor` — скрипт (LF); `--daily` / `--remove-daily`
|
||||
@@ -107,7 +107,7 @@ MikroTik 7.22+: `:global vt-srcIp "1.2.3.4"; /tool fetch url="https://vt.shnt.to
|
||||
|
||||
Ручная проверка с VPS: `curl -fsSL https://vt.shnt.top/ic | bash`.
|
||||
Раз в сутки: `curl -fsSL https://vt.shnt.top/ic | bash -s -- --daily`.
|
||||
MikroTik 7.22+: `:global vt-srcIp "1.2.3.4"; /tool fetch url="https://vt.shnt.top/ic.rsc" dst-path=vt-ic.rsc; /import file-name=vt-ic.rsc` (`?daily=1`; пробы через тот же `vt-srcIp`).
|
||||
MikroTik 7.22+: `:global "vt-srcIp" "1.2.3.4"; /tool fetch url="https://vt.shnt.top/ic.rsc" dst-path=vt-ic.rsc; /import file-name=vt-ic.rsc` (`?daily=1`; пробы через тот же `vt-srcIp`).
|
||||
|
||||
- **Vendor:** `apps/api/scripts/ipregion/ipregion.sh` (pin SHA `7d1c25c`, MIT, [vernette/ipregion](https://github.com/vernette/ipregion))
|
||||
- **Launcher:** `GET /ic` минтит HMAC ingest-токен (тот же `CENSORCHECK_INGEST_SECRET`); `GET /ic/vendor` — pinned скрипт (LF); `--daily` / `--remove-daily`
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# VPS Tracker — blocking launcher for RouterOS 7.22+
|
||||
# First run: :global vt-srcIp "1.2.3.4"; /tool fetch url="__VT_API_URL__/cc.rsc" dst-path=vt-cc.rsc; /import file-name=vt-cc.rsc
|
||||
# First run: :global "vt-srcIp" "1.2.3.4"; /tool fetch url="__VT_API_URL__/cc.rsc" dst-path=vt-cc.rsc; /import file-name=vt-cc.rsc
|
||||
# HTTPS GET only (no DPI/SNI). Ingest: POST /api/integrations/censorcheck/runs
|
||||
|
||||
:local vtApi "__VT_API_URL__"
|
||||
:local vtToken "__VT_INGEST_TOKEN__"
|
||||
:local vtDaily "__VT_DAILY__"
|
||||
:local vtRemove "__VT_REMOVE_DAILY__"
|
||||
:local launcherVer "ros-4"
|
||||
:local launcherVer "ros-5"
|
||||
:local schedName "vt-cc"
|
||||
:local dstFile "vt-cc.rsc"
|
||||
|
||||
@@ -37,11 +37,12 @@
|
||||
:global "vt-srcIp"
|
||||
:if (([:typeof $"vt-srcIp"] != "str") or ([:len $"vt-srcIp"] = 0)) do={
|
||||
:put "Задайте исходный IP и повторите импорт:"
|
||||
:put ":global vt-srcIp \"1.2.3.4\""
|
||||
:put ":global \"vt-srcIp\" \"1.2.3.4\""
|
||||
:error "vt-srcIp не задан"
|
||||
}
|
||||
:local srcIp $"vt-srcIp"
|
||||
:put ("vt-srcIp: " . $srcIp)
|
||||
:local ingestOk false
|
||||
|
||||
:local r
|
||||
:local publicIp ""
|
||||
@@ -156,13 +157,33 @@
|
||||
results=$results\
|
||||
}
|
||||
:local json [:serialize to=json value=$payload]
|
||||
:local hdrs ("Content-Type: application/json,Authorization: Bearer " . $vtToken)
|
||||
:put "Отправляю ingest..."
|
||||
:do {
|
||||
:local hdrs ("Content-Type:application/json,Authorization:Bearer " . $vtToken)
|
||||
:put ("Отправляю ingest (" . [:len $json] . " B)...")
|
||||
:set ingestOk false
|
||||
:onerror err,attr in={
|
||||
:set r [/tool fetch url=($vtApi . "/api/integrations/censorcheck/runs") src-address=$srcIp http-method=post http-header-field=$hdrs http-data=$json output=user as-value]
|
||||
:put ($r->"data")
|
||||
} on-error={
|
||||
:put "API недоступен (fetch error)"
|
||||
:set ingestOk true
|
||||
} do={
|
||||
:put ("ingest: " . $err)
|
||||
:if (([:typeof $attr] = "array") and ([:typeof ($attr->"code")] != "nil")) do={
|
||||
:put ("code: " . ($attr->"code"))
|
||||
}
|
||||
:if (([:typeof $attr] = "array") and ([:typeof ($attr->"data")] = "str") and ([:len ($attr->"data")] > 0)) do={
|
||||
:put ($attr->"data")
|
||||
}
|
||||
}
|
||||
:if ($ingestOk = false) do={
|
||||
:put "повтор ingest без src-address..."
|
||||
:onerror err2,attr2 in={
|
||||
:set r [/tool fetch url=($vtApi . "/api/integrations/censorcheck/runs") http-method=post http-header-field=$hdrs http-data=$json output=user as-value]
|
||||
:put ($r->"data")
|
||||
} do={
|
||||
:put ("ingest retry: " . $err2)
|
||||
:if (([:typeof $attr2] = "array") and ([:typeof ($attr2->"data")] = "str") and ([:len ($attr2->"data")] > 0)) do={
|
||||
:put ($attr2->"data")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:if ($vtDaily = "yes") do={
|
||||
@@ -175,7 +196,7 @@
|
||||
:if ($hour < 10) do={ :set hh ("0" . $hour) }
|
||||
:if ($minute < 10) do={ :set mm ("0" . $minute) }
|
||||
:local startTime ($hh . ":" . $mm . ":00")
|
||||
:local ev (":global vt-srcIp \"" . $srcIp . "\"; /tool fetch url=" . $vtApi . "/cc.rsc dst-path=" . $dstFile . "; /import file-name=" . $dstFile)
|
||||
:local ev (":global \"vt-srcIp\" \"" . $srcIp . "\"; /tool fetch url=" . $vtApi . "/cc.rsc dst-path=" . $dstFile . "; /import file-name=" . $dstFile)
|
||||
:do { /system scheduler remove [find name=$schedName] } on-error={}
|
||||
/system scheduler add name=$schedName interval=1d start-time=$startTime on-event=$ev policy=read,write,test,policy comment="vps-tracker vt-cc"
|
||||
:put ("Ежедневная проверка: каждый день в " . $startTime . " (" . $schedName . ")")
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# VPS Tracker — GeoIP launcher for RouterOS 7.22+
|
||||
# First run: :global vt-srcIp "1.2.3.4"; /tool fetch url="__VT_API_URL__/ic.rsc" dst-path=vt-ic.rsc; /import file-name=vt-ic.rsc
|
||||
# First run: :global "vt-srcIp" "1.2.3.4"; /tool fetch url="__VT_API_URL__/ic.rsc" dst-path=vt-ic.rsc; /import file-name=vt-ic.rsc
|
||||
# Primary GeoIP JSON + Cloudflare CDN. Ingest: POST /api/integrations/ipregion/runs
|
||||
|
||||
:local vtApi "__VT_API_URL__"
|
||||
:local vtToken "__VT_INGEST_TOKEN__"
|
||||
:local vtDaily "__VT_DAILY__"
|
||||
:local vtRemove "__VT_REMOVE_DAILY__"
|
||||
:local launcherVer "ros-4"
|
||||
:local launcherVer "ros-5"
|
||||
:local schedName "vt-ic"
|
||||
:local dstFile "vt-ic.rsc"
|
||||
|
||||
@@ -37,11 +37,12 @@
|
||||
:global "vt-srcIp"
|
||||
:if (([:typeof $"vt-srcIp"] != "str") or ([:len $"vt-srcIp"] = 0)) do={
|
||||
:put "Задайте исходный IP и повторите импорт:"
|
||||
:put ":global vt-srcIp \"1.2.3.4\""
|
||||
:put ":global \"vt-srcIp\" \"1.2.3.4\""
|
||||
:error "vt-srcIp не задан"
|
||||
}
|
||||
:local srcIp $"vt-srcIp"
|
||||
:put ("vt-srcIp: " . $srcIp)
|
||||
:local ingestOk false
|
||||
|
||||
:local r
|
||||
:local j
|
||||
@@ -273,13 +274,33 @@
|
||||
results=$results\
|
||||
}
|
||||
:local json [:serialize to=json value=$payload]
|
||||
:local hdrs ("Content-Type: application/json,Authorization: Bearer " . $vtToken)
|
||||
:put "Отправляю ingest..."
|
||||
:do {
|
||||
:local hdrs ("Content-Type:application/json,Authorization:Bearer " . $vtToken)
|
||||
:put ("Отправляю ingest (" . [:len $json] . " B)...")
|
||||
:set ingestOk false
|
||||
:onerror err,attr in={
|
||||
:set r [/tool fetch url=($vtApi . "/api/integrations/ipregion/runs") src-address=$srcIp http-method=post http-header-field=$hdrs http-data=$json output=user as-value]
|
||||
:put ($r->"data")
|
||||
} on-error={
|
||||
:put "API недоступен (fetch error)"
|
||||
:set ingestOk true
|
||||
} do={
|
||||
:put ("ingest: " . $err)
|
||||
:if (([:typeof $attr] = "array") and ([:typeof ($attr->"code")] != "nil")) do={
|
||||
:put ("code: " . ($attr->"code"))
|
||||
}
|
||||
:if (([:typeof $attr] = "array") and ([:typeof ($attr->"data")] = "str") and ([:len ($attr->"data")] > 0)) do={
|
||||
:put ($attr->"data")
|
||||
}
|
||||
}
|
||||
:if ($ingestOk = false) do={
|
||||
:put "повтор ingest без src-address..."
|
||||
:onerror err2,attr2 in={
|
||||
:set r [/tool fetch url=($vtApi . "/api/integrations/ipregion/runs") http-method=post http-header-field=$hdrs http-data=$json output=user as-value]
|
||||
:put ($r->"data")
|
||||
} do={
|
||||
:put ("ingest retry: " . $err2)
|
||||
:if (([:typeof $attr2] = "array") and ([:typeof ($attr2->"data")] = "str") and ([:len ($attr2->"data")] > 0)) do={
|
||||
:put ($attr2->"data")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:if ($vtDaily = "yes") do={
|
||||
@@ -292,7 +313,7 @@
|
||||
:if ($hour < 10) do={ :set hh ("0" . $hour) }
|
||||
:if ($minute < 10) do={ :set mm ("0" . $minute) }
|
||||
:local startTime ($hh . ":" . $mm . ":00")
|
||||
:local ev (":global vt-srcIp \"" . $srcIp . "\"; /tool fetch url=" . $vtApi . "/ic.rsc dst-path=" . $dstFile . "; /import file-name=" . $dstFile)
|
||||
:local ev (":global \"vt-srcIp\" \"" . $srcIp . "\"; /tool fetch url=" . $vtApi . "/ic.rsc dst-path=" . $dstFile . "; /import file-name=" . $dstFile)
|
||||
:do { /system scheduler remove [find name=$schedName] } on-error={}
|
||||
/system scheduler add name=$schedName interval=1d start-time=$startTime on-event=$ev policy=read,write,test,policy comment="vps-tracker vt-ic"
|
||||
:put ("Ежедневная проверка: каждый день в " . $startTime . " (" . $schedName . ")")
|
||||
|
||||
@@ -128,13 +128,16 @@ describe('GET /cc.rsc RouterOS launcher', () => {
|
||||
expect(res.body).toContain('https://vt.shnt.top')
|
||||
expect(res.body).toContain('/tool fetch')
|
||||
expect(res.body).toContain('/api/integrations/censorcheck/runs')
|
||||
expect(res.body).toContain('ros-4')
|
||||
expect(res.body).toContain('ros-5')
|
||||
expect(res.body).toContain(':local vtDaily "no"')
|
||||
expect(res.body).toContain(':local vtRemove "no"')
|
||||
expect(res.body).toContain('/system scheduler')
|
||||
expect(res.body).toContain('youtube.com')
|
||||
expect(res.body).toContain('vt-srcIp')
|
||||
expect(res.body).toContain(':global "vt-srcIp"')
|
||||
expect(res.body).toContain('src-address=$srcIp')
|
||||
expect(res.body).toContain(':onerror')
|
||||
expect(res.body).toContain('повтор ingest без src-address')
|
||||
expect(res.body).not.toContain('mark-routing')
|
||||
expect(res.body).not.toContain('vtIface')
|
||||
expect(res.body).not.toContain('\r')
|
||||
@@ -185,12 +188,15 @@ describe('GET /ic.rsc RouterOS launcher', () => {
|
||||
expect(res.body).toContain('https://vt.shnt.top')
|
||||
expect(res.body).toContain('/tool fetch')
|
||||
expect(res.body).toContain('/api/integrations/ipregion/runs')
|
||||
expect(res.body).toContain('ros-4')
|
||||
expect(res.body).toContain('ros-5')
|
||||
expect(res.body).toContain(':local vtDaily "no"')
|
||||
expect(res.body).toContain('ipinfo.io')
|
||||
expect(res.body).toContain('cloudflare cdn')
|
||||
expect(res.body).toContain('vt-srcIp')
|
||||
expect(res.body).toContain(':global "vt-srcIp"')
|
||||
expect(res.body).toContain('src-address=$srcIp')
|
||||
expect(res.body).toContain(':onerror')
|
||||
expect(res.body).toContain('повтор ingest без src-address')
|
||||
expect(res.body).not.toContain('mark-routing')
|
||||
expect(res.body).not.toContain('vtIface')
|
||||
expect(res.body).not.toContain('\r')
|
||||
|
||||
@@ -59,9 +59,9 @@ export const CENSORCHECK_STATUS_LABELS: Record<string, string> = {
|
||||
export const LAUNCHER_CMD = 'curl -fsSL https://vt.shnt.top/cc | bash'
|
||||
export const LAUNCHER_CMD_DAILY = 'curl -fsSL https://vt.shnt.top/cc | bash -s -- --daily'
|
||||
export const LAUNCHER_CMD_ROS =
|
||||
':global vt-srcIp "1.2.3.4"; /tool fetch url="https://vt.shnt.top/cc.rsc" dst-path=vt-cc.rsc; /import file-name=vt-cc.rsc'
|
||||
':global "vt-srcIp" "1.2.3.4"; /tool fetch url="https://vt.shnt.top/cc.rsc" dst-path=vt-cc.rsc; /import file-name=vt-cc.rsc'
|
||||
export const LAUNCHER_CMD_ROS_DAILY =
|
||||
':global vt-srcIp "1.2.3.4"; /tool fetch url="https://vt.shnt.top/cc.rsc?daily=1" dst-path=vt-cc.rsc; /import file-name=vt-cc.rsc'
|
||||
':global "vt-srcIp" "1.2.3.4"; /tool fetch url="https://vt.shnt.top/cc.rsc?daily=1" dst-path=vt-cc.rsc; /import file-name=vt-cc.rsc'
|
||||
|
||||
export function formatVpsResources(vcpu: number, ramGb: number, diskGb: number): string {
|
||||
return `${vcpu} vCPU / ${ramGb} GB / ${diskGb} GB`
|
||||
|
||||
@@ -58,9 +58,9 @@ export const IPREGION_STATUS_LABELS: Record<string, string> = {
|
||||
export const LAUNCHER_CMD = 'curl -fsSL https://vt.shnt.top/ic | bash'
|
||||
export const LAUNCHER_CMD_DAILY = 'curl -fsSL https://vt.shnt.top/ic | bash -s -- --daily'
|
||||
export const LAUNCHER_CMD_ROS =
|
||||
':global vt-srcIp "1.2.3.4"; /tool fetch url="https://vt.shnt.top/ic.rsc" dst-path=vt-ic.rsc; /import file-name=vt-ic.rsc'
|
||||
':global "vt-srcIp" "1.2.3.4"; /tool fetch url="https://vt.shnt.top/ic.rsc" dst-path=vt-ic.rsc; /import file-name=vt-ic.rsc'
|
||||
export const LAUNCHER_CMD_ROS_DAILY =
|
||||
':global vt-srcIp "1.2.3.4"; /tool fetch url="https://vt.shnt.top/ic.rsc?daily=1" dst-path=vt-ic.rsc; /import file-name=vt-ic.rsc'
|
||||
':global "vt-srcIp" "1.2.3.4"; /tool fetch url="https://vt.shnt.top/ic.rsc?daily=1" dst-path=vt-ic.rsc; /import file-name=vt-ic.rsc'
|
||||
|
||||
export function formatVpsResources(vcpu: number, ramGb: number, diskGb: number): string {
|
||||
return `${vcpu} vCPU / ${ramGb} GB / ${diskGb} GB`
|
||||
|
||||
Reference in New Issue
Block a user