Ниже — набор практических шагов и настроек, которые в реальности решают большую часть «виснущих» SSH‑сессий с Remote SSH (VS Code / Cursor) и устраняют последствия Fail2ban / NAT таймаутов. Сначала — короткий план, потом примеры конфигураций и команды для диагностики.
Коротко что делать
- Включить keep‑alive (на клиенте и/или на сервере).
- Включить SSH‑multiplexing (ControlMaster / ControlPersist) — сильно ускоряет и уменьшает шанс зависаний при частых подключениях.
- Проверить и при необходимости добавить в белый список IP в fail2ban (или ослабить правила).
- Посмотреть логи Remote SSH (Cursor) и серверные логи (/var/log/auth.log / journalctl) — найти точную причину разрывов.
- Рассмотреть альтернативы: CI/CD/rsync/контейнерный registry, если надо «надёжно и быстро» выкатывать в продакшн.
- Проверить версию Remote SSH — при подозрении на баг — откат/обновление и тест.
Диагностика (что посмотреть сначала)
- На сервере: смотреть логи sshd:
- sudo tail -n200 /var/log/auth.log
- sudo journalctl -u sshd -f
- Fail2ban:
- sudo fail2ban-client status
- sudo fail2ban-client status sshd
- /var/log/fail2ban.log
- На клиенте (Cursor/VS Code): Output → Remote‑SSH (или соответствующий лог Cursor). Там часто видно “Timed out while waiting for server to start” и т. п.
- Сеть: проверить нет ли packet loss / долгой latency:
- ping, mtr, traceroute.
- Проверить, не срабатывает ли NAT idle timeout на промежуточном роутере/Firewall (особенно если вы в офисе или через мобильный интернет).
Рекомендованные конфигурации
1) На клиенте (~/.ssh/config) — keepalive + multiplexing (пример)
Host prod-server
HostName your.server.example
User deploy
IdentityFile ~/.ssh/deploy_key
TCPKeepAlive yes
ServerAliveInterval 60
ServerAliveCountMax 3
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10m
Пояснения:
- ServerAliveInterval=60 отправляет keep‑alive каждые 60 секунд; если соединение побито сетевыми таймаутами, это поможет «держать» NAT/файрвол.
- ServerAliveCountMax=3 — после ~3 пропущенных ответов SSH разорвет соединение быстрее, что избежит очень долгих подвисаний.
- ControlPersist держит мастер‑соединение (10 минут здесь) и позволяет повторно использовать канал без нового полного TCP/SSH handshake — это существенно ускоряет частые операции (rsync, git push через ssh и пр.).
2) На сервере (/etc/ssh/sshd_config) — принимать keepalive, отключить лишнее
ClientAliveInterval 60
ClientAliveCountMax 3
UseDNS no
GSSAPIAuthentication no
Затем:
- sudo systemctl restart sshd
Пояснение: эти настройки заставляют сервер тоже поддерживать keep‑alive и быстрее закрывать «зависшие» клиенты; UseDNS/GSSAPI отключают задержки при аутентификации.
3) Fail2ban — белый список / правила
Если Fail2ban блокирует вас при частых попытках:
- Проверить статус: sudo fail2ban-client status sshd
- Добавить ваш IP/сеть в ignoreip в /etc/fail2ban/jail.local, например:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.45
- Или уменьшить чувствительность (maxretry, bantime) для sshd‑jail.
Перезапустить fail2ban: sudo systemctl restart fail2ban
4) Опции Remote SSH / Cursor
- Посмотрите настройки Remote SSH в Cursor/VS Code: есть timeout‑параметры (connectTimeout). Увеличение connect timeout иногда помогает при медленных сетях.
- Если подозреваете баг в версии 1.0.46 — попробуйте временно откатить расширение на предыдущую версию или обновить до новейшей, где баг исправлен. В VS Code можно установить .vsix старой версии или выбрать "Install Another Version" в менеджере расширений.
5) Используйте SSH‑агент и безпарольный доступ
- ssh-agent / keychain — чтобы не вводить пароль/фразовую строку каждый раз, и чтобы ControlMaster мог реиспользовать сессию.
6) Быстрые рабочие альтернативы для надежной доставки
- Если цель — просто выгрузить файлы: rsync —avz -e 'ssh -o ControlMaster=auto -o ControlPath=~/.ssh/cm-%r@%h:%p -o ControlPersist=10m' ./build/ deploy@server:/srv/app/
- CI/CD: настроить Github Actions / GitLab CI — пуш в репозиторий инициирует деплой на сервер (webhook, ssh key), это избавит от прямых ручных SSH.
- Контейнеры: пушить образ в registry (Docker Hub / private registry) и на сервере делать docker pull + docker run — это обычно надёжнее, чем копирование файлов по SSH.
Дополнительные полезные команды
- Проверить активные SSH‑подключения: ss -tnp | grep sshd
- Посмотреть процессы Remote‑Server на сервере (если Remote SSH разворачивает серверную часть): ps aux | grep vscode-server (или code-server)
- Перезапустить sshd: sudo systemctl restart sshd
- Очистить бан в fail2ban: sudo fail2ban-client set sshd unbanip <ваш_IP>
Короткие рекомендации по порядку действий (быстрое исправление)
1. Добавьте в ~/.ssh/config ServerAliveInterval + ControlPersist, как в примере выше.
2. Посмотрите fail2ban status и при необходимости добавьте ваш IP в ignoreip.
3. Посмотрите логи Remote‑SSH в Cursor и /var/log/auth.log — если видите блокировку или частые таймауты, принимайте меры по fail2ban/файрволу.
4. Если после всего остаются зависания — откатите/обновите Remote SSH расширение (проверьте changelog версии).
Почему это часто происходит
- NAT/firewall закрывает «простые» TCP соединения после минуты−нескольких минут без активности -> keepalive решает.
- Fail2ban может временно блокировать повторные подключения (особенно при множественных попытках).
- Баги в Remote‑SSH/VSCode серверной части (иногда в конкретной версии) — тогда помогает откат или обновление.
- Плохая сеть / packet loss — решать на уровне сети или использовать инструменты, устойчивые к нестабильности (mosh не для порт‑форвардинга/VSCode, поэтому не всегда применим).
Если хотите — помогу конкретно:
- пришлите вывод: лог Remote‑SSH (из Cursor/VS Code) + последние 30 строчек /var/log/auth.log + конфигурацию вашего ~/.ssh/config и /etc/ssh/sshd_config, а также информацию по fail2ban (sudo fail2ban-client status). По ним скажу точную настройку и подскажу, что можно безопасно менять прямо сейчас.