VPN Terminal Doctor
Запуск Навыка
При явном вызове или однозначном смысловом совпадении применяйте навык сразу. Перед первым шагом покажите ровно одну короткую контекстную строку (не более 30 слов) и продолжайте работу в том же ответе, не ожидая реакции:
Применяю экспериментальный навык «Диагностика сети терминала при VPN» (обратная связь — @kir-kopylov): <кратко назовите конкретную пользу для текущего запроса>; продолжаю без ожидания.
Не включайте в строку author_github, внутреннее имя папки или пересказ всего запроса. Не спрашивайте, применять ли навык.
Stop-gate: если терминал агента доступен, до отправки первого ответа обязательно выполните в нём read-only определение оболочки и две HTTP-пробы из шага 1 с таймаутом. Первый ответ должен уже содержать наблюдаемые коды обеих проб; обещание «сначала проверю» запрещено. Если болит git и текущий repo однозначен, также read-only определите транспорт remote. Только при фактически недоступном целевом терминале назовите наблюдаемый blocker и одно минимальное действие человека.
Если одновременно подходят совместимые навыки, выберите минимальный набор и покажите одну общую строку. Если подходы ведут к несовместимым результатам и запрос не позволяет выбрать, спросите только о желаемом результате, не о разрешении применить навык.
Запуск навыка не расширяет полномочия. Выполните всю безопасную и уже разрешённую часть; запросите подтверждение только непосредственно перед ещё не разрешённым внешним или изменяющим действием. Не запрашивайте повторно уже данное разрешение и не дублируйте системное окно подтверждения.
Обзор
Классическая ловушка VPN-клиентов с локальным прокси (v2rayN, Happ, Clash, sing-box и похожие): браузер ходит в интернет, а терминал — нет. Причин почти всегда три семьи: залипшие переменные окружения на мёртвый локальный прокси; мёртвый туннель в прокси-режиме; смешение режимов после переключения. Симптом один («ничего не работает»), лечение разное — поэтому сначала снять полные показания, потом дёргать переключатели, не наоборот.
Каркас дерева проверен боем на одной ветке (залипшие переменные при живом туннеле); ветки про мёртвый туннель и не-VPN-причину — обоснованные гипотезы, отмечены как таковые. Поэтому финал всегда через контрольную пробу, а не через «должно заработать».
Роли: команды диагностики агент выполняет сам (терминал ему доступен). Человеку остаются только действия в окне VPN-приложения — агент даёт одну конкретную инструкцию и ждёт.
Естественные Входы
- «терминал без интернета, а браузер работает»;
- «git push / gh / curl висит или даёт
000при VPN»; - «включил VPN — терминал отвалился»;
- «почини сеть терминала»;
- отправка чего-либо из терминала упала по сети, при этом сайты в браузере открываются.
Жёсткие Правила
- Сначала полные показания, потом переключатели: не просить человека дёргать VPN, пока не сняты симптом, транспорт
git, переменные,git configи обходная проба. - Одна проверка за раз; после каждой развязки — контрольная проба той же командой и тем же инструментом, что болел.
- Агент НЕ переключает VPN-приложение, не меняет его сервер и не выключает VPN — это делает человек по одной инструкции агента.
- Команды давать в раскладке той оболочки, где сидит исполнитель (см. «Команды по оболочкам»). Не диктовать
env -uи голыйcurlвPowerShell/cmd— там их нет или они значат другое. - Обходы (
env -u,--noproxy,git -c http.proxy=) — сессионные: честно называть их обходом и предлагать постоянное лечение (убрать источник переменных или выключить системный прокси в VPN-приложении). - Не редактировать реестр, профили оболочки и глобальный конфиг
gitбез явного согласия человека; для разовой команды использовать обход в самой команде. - Адреса
198.18.x.xв ответахDNS— только ПОЛОЖИТЕЛЬНЫЙ признак перехвата; их отсутствие НЕ доказывает, что туннеля нет (туннель без подменыDNS— массовая конфигурация). Не ветвиться на отрицании этого признака. - Не верить показометрам VPN-приложения (пинг
2msпри мёртвом туннеле — норма); верить только контрольной пробе из терминала.
Команды По Оболочкам
Определите оболочку исполнителя (Git Bash / PowerShell / cmd) и давайте команды из нужного столбца. У самого агента обычно Git Bash, но человек может сидеть в другом.
| Действие | Git Bash |
PowerShell 5.1+ |
cmd |
|---|---|---|---|
| HTTP-проба с кодом и таймаутом | curl -s -m 10 -o /dev/null -w "%{http_code} %{exitcode}\n" URL |
curl.exe -s -m 10 -o NUL -w "%{http_code} %{exitcode}\n" URL |
curl.exe -s -m 10 -o NUL -w "%{http_code} %{exitcode}\n" URL |
| Проба в обход прокси | добавить --noproxy "*" |
то же, curl.exe ... --noproxy "*" |
то же |
| Разовый запуск без прокси-переменных | env -u HTTP_PROXY -u HTTPS_PROXY -u http_proxy -u https_proxy -u ALL_PROXY -u all_proxy КОМАНДА |
Remove-Item Env:HTTP_PROXY,Env:HTTPS_PROXY,Env:http_proxy,Env:https_proxy,Env:ALL_PROXY,Env:all_proxy -ErrorAction SilentlyContinue; КОМАНДА (в новой сессии, чтобы не потерять значения) |
cmd /c "set HTTP_PROXY=&& set HTTPS_PROXY=&& КОМАНДА" |
| Показать прокси-переменные | env | grep -i proxy |
Get-ChildItem Env: | Where-Object Name -match 'proxy' |
set | findstr /i proxy |
Ключевое: в PowerShell curl — это псевдоним Invoke-WebRequest, и curl -s -m 10 там падает на разборе флагов ещё до сети; всегда писать curl.exe. Команды env в PowerShell/cmd не существует.
Дерево Диагностики
Шаги едины для всех оболочек; конкретные команды берите из таблицы выше.
Класс маяка и симптом. Пробьте ДВА маяка разных классов: внутристрановой доступный (для РФ —
ya.ru) и внешний целевой (github.comили тот сервис, что болит). Разберите по таблице 2×2:внутристрановой внешний вывод 000000терминал вообще не видит сеть → шаг 2 200000сеть жива, целевой класс заблокирован → это ПРИЧИНА включить VPN, а не поломка сети; если VPN уже включён — шаг 2 200200терминал в порядке — проблема не здесь (проверьте, тот ли инструмент/адрес болит) Не брать оба маяка из блокируемого класса (
google.com+github.comв РФ без VPN дают000при живой сети — ложный «сеть мертва»).Транспорт
git(если болит именноgit):git remote -v.- Адрес
https://…→ прокси-механика применима, идём дальше. - Адрес
git@host:…(ssh) →HTTP_PROXY/HTTPS_PROXYиgit config http.proxyна него НЕ влияют вообще:gitзапускаетssh, аsshне знает про HTTP-прокси. Здесь дерево прокси неприменимо — см. «Веткаssh-remote». Часто в цензурируемой сети умирает сам порт 22.
- Адрес
Залипшие переменные и конфиг (главные подозреваемые после переключения режимов): показать прокси-переменные (таблица) и
git config --global --get http.proxy. Запомнить ОБА источника — развязка будет зависеть от того, который из них живёт.Безусловная проба в обход. Сразу, не глядя на
DNS: HTTP-проба целевого адреса с--noproxy "*".200— туннель/прямой путь жив, терминал душили только прокси-настройки: диагноз готов, переходите к развязке А.000— прокси-настройки ни при чём, идём к шагу 5.Живость локального прокси (если шаг 4 дал
000, а переменные из шага 3 указывают на127.0.0.1:ПОРТ): слушается ли порт (Git Bash/cmd:netstat -ano | grep LISTEN | grep 127.0.0.1;PowerShell:Get-NetTCPConnection -State Listen -LocalAddress 127.0.0.1) и проходит ли проба ЧЕРЕЗ него. Порт слушается, но проба000— прокси жив, а туннель за ним мёртв → развязка Б.Режим туннеля по
DNS(только как пояснение, НЕ как развилка):nslookup github.com. Адреса198.18.x.x— активна подменаDNS(fake-ip), туннель точно перехватывает трафик. Реальные адреса — вывод сделать НЕЛЬЗЯ: туннель без подменыDNSтоже возвращает реальные адреса. Решает исход проба шага 4, а не этот шаг.
Развязки
А. Туннель жив + залипшие настройки (шаг 4 дал
200): обход одной командой.- Причина в переменных → запуск без прокси-переменных (таблица, столбец нужной оболочки).
- Причина в
git config http.proxy(переменные чистые, аgitвсё равно идёт через мёртвый прокси — конфиг замещает окружение) → универсальный обход дляgit:git -c http.proxy= -c https.proxy= push(пустое значение отключает прокси и перебивает и конфиг, и переменные). - Постоянное лечение: выключить «системный прокси» в VPN-приложении (туннельному режиму он не нужен) или вычистить переменные из профиля оболочки; затем новый терминал и контрольная проба.
Б. Прокси-режим, туннель мёртв (шаг 5: порт слушается, проба
000): инструкция человеку — в VPN-приложении сменить сервер или включить туннельный режим («для всей системы»,TUN); после переключения повторить дерево с шага 1.В. Переменных нет, обходная проба
000, порт прокси не слушается: проблема вне VPN-прослойки (сеть, файрвол) либо VPN оборвал сеть целиком. Инструкция человеку — выключить VPN и повторить шаг 1: сеть вернулась (внутристрановой маяк дал200) — проблема в VPN-приложении (сервер/режим); не вернулась — это не задача этого skill, честно передать в обычную диагностику сети.
Ветка ssh-remote
Если шаг 2 показал git@host:…, прокси-дерево не применяется — им нельзя ни поставить ложный диагноз, ни вылечить. Варианты:
- перевести remote на
https(git remote set-url), тогда работает всё дерево выше; - либо настроить сам
ssh:ProxyCommand/ProxyJumpв~/.ssh/config, илиsshчерез порт 443 (ssh.github.com:443), или прокинуть черезGIT_SSH_COMMAND/core.sshCommand. Правки~/.ssh/config— с явного согласия человека. Контрольная проба:ssh -T git@host(или-p 443), затем реальныйgit ls-remote.
Контрольная Проба
Финал — только через пробу той же командой и тем же инструментом, что болел: для git — реальная лёгкая операция (git ls-remote origin) с тем обходом, что сработал, а не абстрактный curl. Слова «должно заработать» финалом не считаются.
Быстрый Снимок (опционально)
Чтобы не снимать показания по одной и не терять их при эскалации, можно собрать всё за один запуск. Git Bash:
echo "== маяки =="; for u in https://ya.ru https://github.com; do curl -s -m 10 -o /dev/null -w "$u %{http_code} exit=%{exitcode}" "$u"; echo; done
echo "== обход =="; curl -s -m 10 --noproxy "*" -o /dev/null -w "github %{http_code} exit=%{exitcode}" https://github.com; echo
echo "== переменные =="; env | grep -i proxy || echo "(нет)"
echo "== git =="; git remote -v 2>/dev/null | head -2; git config --global --get http.proxy || echo "(конфиг пуст)"
echo "== dns =="; nslookup github.com 2>&1 | tail -3
Замечание для Git Bash: в цикле не используйте \n внутри -w (MSYS печатает его как /n и склеивает строки) — перевод строки делайте отдельным echo, как выше.
Код выхода curl уже сортирует причину: 6 — не резолвится DNS, 7 — не коннектится, 28 — таймаут, 35/56 — TLS/прокси. Это ускоряет диагноз, но не заменяет дерево: выводы делать по нему.
Границы
Не используйте skill для: обхода блокировок и настройки самого VPN; диагностики полностью мёртвой сети (когда и браузер не работает); правки реестра, профилей и глобальных конфигов без явного согласия; починки DNS и файрвола; сетевых проблем внутри контейнеров и виртуальных машин.
Опрос После Использования
После каждого использования skill запустите короткий опрос — это обязательный post-use блок, а не скрытая автоматизация. Спросите:
Опрос по skill:
1. Что в этом использовании lechenie-terminala-pri-vpn было полезно?
2. Что стоит доработать в skill или его формате?
Можно ответить коротко или написать "пропустить".
Если человек ответил, сохраните sanitized карточку в приватный локальный лог ~/.codex/skill-runs/lechenie-terminala-pri-vpn/usage-feedback.jsonl; при наличии bundled-скрипта используйте python3 scripts/log_usage_feedback.py --liked "..." --improve "...". Если запись невозможна, не делайте вид, что лог сохранён: скажите об этом и покажите короткую карточку для ручного сохранения. Приватные пути, адреса, аккаунты и секреты не коммитить.
Логирование Сбоев
Перед выполнением прочитайте локальный known-exceptions.yaml и применяйте подходящее do_next_time без нового поиска. Если дерево не сошлось, развязка не сработала, человек поправил процесс или всплыла новая конфигурация VPN — запишите приватную карточку в:
~/.codex/skill-runs/lechenie-terminala-pri-vpn/exception-log.jsonl
Пишите факты: что хотели, что сделали, где сломалось, какая предпосылка была ложной и что делать в следующий раз. Если поле неизвестно, пишите unknown. Raw logs не коммитить.