Вылетает удаленное подключение к серверу

Вылетает удаленное подключение к серверу

Добрый день! Уважаемые читатели и гости, IT блога Pyatilistnik.org. В прошлый раз мы с вами поговорили, про отложенный запуск служб в Windows, сегодня я хочу вам показать еще один не приятный момент в работе терминальных служб удаленного рабочего стола, а именно ошибка подключения «Произошла внутренняя ошибка«, после чего подключение разрывается. Такое я встречал уже в Windows Server 2012 R2 и 2016. Давайте разбираться в чем дело.

Описание проблемы

Есть сервер с операционной системой Windows Server 2012 R2, сотрудник пытается к нему подключиться, через классическую утилиту «Подключение к удаленному рабочему столу», в момент авторизации, выскакивает окно с ошибкой «Произошла внутренняя ошибка».

В английском варианте ошибка звучит вот так:

После этого у вас разрывается соединение. Когда мы видели моргающий экран по RDP, там хотя бы вы попадали на сервер и могли открыть диспетчер устройств, тут сразу все обрубается на корню. Давайте смотреть, что можно сделать.

🆘 Что есть в логах?

Если посмотреть журналы событий на удаленном сервере, куда вы пытаетесь подключиться, то там порядок событий будет такой:

  • 1️⃣ Первым будет идти событие ID 131 «The server accepted a new TCP connection from client IP-адрес:60050.». Тут вы увидите IP-адрес с которого идет попытка входа.

  • 2️⃣ Далее событие ID 65 «Connection RDP-Tcp#11 created «.

  • 3️⃣ Затем событие 141 «PerfCounter session started with instance ID 11». Тут сессии будет назначен ID.

  • 4️⃣ За ним будет идти ID 142 «TCP socket READ operation failed, error 1236».

  • 5️⃣ Потом вы увидите ID 72 «Interface method called: OnDisconnected»

  • 6️⃣ И же после этого вам покажут, что сервер разорвал подключение: «ID 102 The server has terminated main RDP connection with the client.»

  • 7️⃣ В событии ID 145 так же появляются подробности «During this connection, server has not sent data or graphics update for 0 seconds (Idle1: 0, Idle2: 0).».

  • 8️⃣ Могут быть события с ID 148 «Channel rdpinpt has been closed between the server and the client on transport tunnel: 0.» или «Channel rdpcmd has been closed between the server and the client on transport tunnel: 0.» или «Channel rdplic has been closed between the server and the client on transport tunnel: 0.»
  • 9️⃣ Ну и вишенка на торте, ошибка ID 227 «‘Failed to get property Disconnect Reason’ in CUMRDPConnection::Close at 2212 err=[0x80070057]»

Исправляем ошибку «Произошла внутренняя ошибка»

Так как по RDP подключиться не получается, то первым делом нужно проверить отвечает ли порт, по умолчанию это 3389. О том, как проверить порт на удаленном сервере я вам описывал, там все сводилось к выполнению команды Telnet, ознакомьтесь. Если порт отвечает, то делаем следующее.

Нужно удаленно перезапустить службу на этом сервере, чтобы сам сервер не перезагружать, так как в этот момент, он может выполнять важные задачи, можно использовать утилиту «Управление компьютером». Открыть ее можно через команду вызова оснастки, вызываем окно «Выполнить», через одновременное нажатие клавиш WIN и R, в котором пишем:

В открывшейся оснастке, щелкните в самом верху по пункту «Управление компьютером» правым кликом мыши, и выберите пункт «Подключиться к удаленному компьютеру».

Выберите пункт «Другим компьютером» и укажите его DNS имя, или найдите его через кнопку обзор.

Когда вы подключитесь к нужному серверу, перейдите в пункт «Службы и приложения — Службы», в списке сервисов найдите службу удаленных рабочих столов (Remote Desktop Services), и перезапускаем ее. После этого ошибка подключения по RDP «Произошла внутренняя ошибка», у вас должна пропасть.

Рекомендуем:  Как правильно заложить проводку

Так же вы можете использовать оболочку PowerShell запущенную от имени пользователя, у которого есть права на удаленный сервер, где будет перезапускаться служба RDP. Выполните:

Дополнительные методы решения

Если вам не помог первый метод, перезапускающий службу удаленных рабочих столов, то можно попробовать выполнить правку реестра. Открываете редактор реестра Windows, если у вас физического доступа к серверу нет или он далеко и вам лень до него идти, то можно попробовать подключиться к реестру удаленного сервера.

Для этого в окне «Редактор реестра» пункт меню «Файл — Подключить сетевой реестр».

В открывшемся окне «Выбор компьютера» указываем его DNS-имя или ip-адрес и нажимаем ок. У вас будет установлено подключение к удаленному реестру сервера, что испытывает проблемы.

Находим ключ CheckMode по пути

Выставляем ему значение о, чтобы отключить у программы КриптоПРО CSP проверку контрольных сумм. Еще один важный момент, если у вас старая версия КриптоПРО, то это так же может быть источником, проблем, недавний пример, это ошибка «Windows installer service could not be accessed». Для этого удаляем правильно КриптоПРО CSP и ставим последнюю доступную версию.

Еще можно попробовать изменить значение вот такого ключа реестра:

Найдите ключ SessionImageSize и задайте ему значение 0x00000020.

Дополнительные настройки RDP клиента

Например ошибка «An internal error has occurred» у меня встретилась на Windows Server 2022 и там мне помогло в настройках клиента RDP отключение некой опции. Перейдите в дополнительные настройки клиента для удаленного подключения, где н вкладке «Experiens (Взаимодействие)» вам нужно убрать галку с опции «Восстановить подключение при разрыве (Reconnect if the connection is droped)«

На каких-то сайтах предлагалось именно активировать данный пункт.

Удаление кэша подключений

Еще одним методом решения внутренней ошибки подключения по RDP может выступать поврежденный кэш, который хранится на локальном компьютере пользователя. Для его отображения вам необходимо включить отображение скрытых папок и удалить содержимое папки:

Источник

Преодоление разрыва удаленного соединения при отсутствии действий пользователя

При работе с GUI и терминальными приложениями нередко случается, что пользователь, работая в режиме удаленного доступа (как правило, через Интернет), покинув компьютер минут на 15, по возвращении обнаруживает, что программа зависла. На любое действие она отвечает ошибкой, содержащей примерно такие фразы: «Потеряна связь с сервером», «[WINSOCK] virtual circuit reset by host» и т.п. Наблюдается такое и при выполнении «долгоиграющих» методов (запросов к серверу), в которых не предусмотрен вывод прогресс-бара или какая-либо интерактивность.

Данная проблема характерна не только для GUI и терминальных решений на базе СУБД Caché и Ensemble компании InterSystems, а вообще для любого клиент-серверного взаимодействия по протоколу TCP/IP. Обычно она решается на прикладном уровне путём периодического обмена пустыми сообщениями специального вида, предназначенными лишь для того, чтобы просигнализировать о том, что приложение «живо».

Ниже о том, как можно решать эту проблему без программирования.

Источник проблемы

Источник проблемы лежит в природе протокола TCP/IP. Как правило, источник сеанса TCP/IP и его приемник находятся в различных сетях, и на пути сеанса встречается несколько маршрутизаторов. Хотя бы один из них обычно выполняет NAT-преобразование адресов. Ресурсы маршрутизатора всегда ограничены, поэтому некоторые из них выполняют очистку NAT-таблиц от «мёртвых» сеансов. Сеанс считается «мёртвым», если по нему не передавались пакеты в течение некоторого заданного интервала времени (назовем его интервал очистки). Таким образом, «молчаливый» сеанс может быть принят за «мёртвый» и вычищен из NAT-таблицы. При этом ни источник, ни приемник об этом не уведомляются («не царское дело»), и оба они остаются в уверенности, что сеанс ещё «жив» (в чем легко убедиться командой netstat, выполнив ее на клиенте или на сервере в момент возникновения ошибки, но до нажатия на ОК). Когда пользователь, получивший сообщение об ошибке, нажмет на ОК, о разрыве сеанса узнает клиент; серверный же процесс завершится, когда «умерший» сеанс распознает ОС.

Экспериментально установлено, что интервал очистки у многих маршутизаторов (по крайней мере, с прошитым Linux 2.4/iptables) составляет около 10 минут. Постараемся заставить наш TCP-сеанс автоматически поддерживать себя в активном состоянии, даже когда не передается никаких пакетов с данными.

Рекомендуем:  Rgb led контроллер схема подключения

Предлагаемое решение

На уровне ОС обнаружением разорванных TCP-соединений управляют следующие параметры ядра, управляющие работой механизма tcp_keepalive [1]:
tcp_keepalive_time — интервал времени с момента отправки последнего пакета с данными; по истечении этого срока соединение помечается как требующее проверки; после начала проверки параметр не используется;
tcp_keepalive_intvl — интервал между проверочными пакетами (отправка которых начинается по истечении tcp_keepalive_time);
tcp_keepalive_probes — количество неподтвержденных проверочных пакетов; по исчерпании этого счетчика соединение считается разорванным.

Надо сказать, что механизм tcp_keepalive имеет двойное назначение: он может использоваться как для искусственного поддержания активности соединения, так и для выявления разорванных (так называемых «полуоткрытых») соединений. В данной статье обсуждается в основном первое применение, о втором применении, возможно, речь пойдёт в следующей статье на эту тему.

Для того чтобы механизм tcp_keepalive был задействован для TCP-соединений, необходимы два условия:
• поддержка на уровне ОС; к счастью, и в Windows, и в Linux она имеется;
• на одном из концов соединения сокет должен быть открыт с параметром SO_KEEPALIVE. Как оказалось, сервисы Caché открывают сокеты с этим параметром, а сервис OpenSSH несложно заставить поступать аналогично.

Наибольший интерес для нас представляет первый параметр (tcp_keepalive_time), так как именно от него зависит, насколько часто будет выполняться проверка неактивных (с точки зрения отсутствия трафика) соединений. Его значение по умолчанию — и в Windows, и в Linux — равно двум часам (7200 с). Типичное же время бездействия, после которого наступает разрыв, составляет около 10 минут. Поэтому предлагается установить значение параметра в 5 минут, что позволит искусственно поддерживать активность TCP-сеансов, не перегружая сеть избыточным трафиком (5 минут — это не 5 секунд).

Установка параметров tcp_keepalive на сервере Windows

Вы должны обладать правами Администратора к серверу. В разделе реестра
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
создайте параметр DWORD с именем KeepAliveTime и значением 300000 (десятичным). Параметр задаётся в миллисекундах, поэтому предлагаемое значение — это 5 минут. После чего остановите Caché и перезагрузите сервер.

Что касается двух других параметров tcp_keepalive, то их умолчания в Windows таковы:

KeepAliveInterval
Key: Tcpip\Parameters
Value Type: REG_DWORD—time in milliseconds
Valid Range: 0–0xFFFFFFFE
Default: 1000 (1 секунда)

KeepAliveProbes
Такого параметра (устанавливающего количество неподтвержденных проверочных пакетов), в реестре не существует. Согласно [2], в Windows 2000 / XP / 2003 в этом качестве используется значение параметра TcpMaxDataRetransmission (умолчание — 5), а в более поздних версиях [3] — фиксированное значение, равное 10. Поэтому, если менять только значение первого параметра (с 7200 на 300), сохраняя умолчание для второго, сервер Windows 2008 будет узнавать о разрыве TCP-соединения через 1*10 + 300 = 310 секунд.

Установка параметров tcp_keepalive на сервере Linux

Изменить значения параметров можно «на ходу», не перезагружая сервер. Зайдите как root и выполните:

Чтобы сделать изменение долговечным по отношению к возможным перезагрузкам сервера, проще всего отредактировать файл параметров ядра /etc/sysctl.conf, добавив в него строку (лучше две):

Обратите внимание, что в отличие от Windows, значение параметра задается в секундах.
Что касается остальных двух параметров tcp_keepalive, то их умолчания в Linux таковы:

Если менять только значение первого параметра (с 7200 на 300), сохраняя умолчания для остальных двух, сервер Linux будет узнавать о разрыве соединения только через 75*9 + 300 = 975 секунд.

Установка параметра TCPKeepAlive в конфигурации СУБД Caché

Начиная с версии 2008.2, в Caché для платформ Windows и Linux появилась возможность задавать tcp_keepalive_time на уровне сокета, что удобно, так как позволяет избежать изменения настроек операционной системы. Однако «в чистом виде» эта возможность, в основном, представляет интерес лишь для независимых разработчиков сокет-серверов. К счастью, она была дополнена параметром конфигурации TCPKeepAlive=n в секции [SQL], доступным для редактирования со страницы Портала управления системой: Конфигурация > Общие Настройки SQL. Значение по умолчанию — 300 секунд (то, что доктор прописал). Действие параметра распространяется не только на SQL, но и, как нетрудно догадаться, на любые соединения с Caché, обслуживаемые сервисом %Service_Bindings. К ним относится, в частности, и объектный доступ через CacheActiveX.Factory, поэтому если ваше приложение может использовать этот протокол в качестве транспорта, не стоит упускать такую возможность.

Рекомендуем:  Как понять что сломался шлейф на ноутбуке

Установка параметров KeepAlive в конфигурации сервера OpenSSH

Если вы используете SSH [4] (для работы в режиме командной оболочки или как транспорт для вашего GUI-приложения), то… скорее всего, проделанной настройки ядра будет достаточно, поскольку сервис OpenSSH (по крайней мере, в версии 5.x) по-умолчанию открывает сокет с параметром SO_KEEPALIVE.

На всякий случай стоит проверить конфигурационный файл /etc/ssh/sshd_config. Найдите в нем строку

Если нашли, то делать ничего не надо, так как значения параметров по умолчанию предоставляются в закомментированном виде.

Протокол SSH v.2 имеет альтернативные средства контроля активности сеансов, например, с помощью настройки параметров сервиса OpenSSH ClientAliveInterval и ClientAliveCountMax.
При использовании этих параметров, в отличие от TCPKeepAlive, запросы KeepAlive отправляются через защищённый SSH канал и не могут быть подменены. Приходится признать, что альтернативные средства являются более безопасными, нежели традиционный механизм TCPKeepAlive, для которого существует опасность анализа KeepAlive-пакетов и организации DoS-атак [5].

Устанавливает время ожидания в секундах, по истечении которого, если не поступает информация со стороны клиента, sshd отправляет ему запрос отклика через защищённый канал. По умолчанию используется 0, что означает, что клиенту не будет направлен такой запрос.
Устанавливает количество запросов клиенту, которые могут быть отправлены sshd без получения на них отклика. Если предел достигнут, sshd разъединяется с клиентом и завершает сеанс. Значение по умолчанию: 3. Если вы установите значение параметра ClientAliveInterval равным 60, оставив ClientAliveCountMax без изменений, то не отвечающие ssh-клиенты будут отключены примерно через 180 секунд. При этом следует отключить механизм TCP KeepAlive, установив

Всегда ли это работает?

Существуют категории сетевых проблем, в которых описанный подход может быть малоэффективен.

Одна из них имеет место, когда из-за низкого качества сетевого обслуживания связь может физически пропадать в течение коротких промежутков времени. Если сеанс бездействует, а связь временно пропадает и восстанавливается до того, как клиент или сервер попытаются что-то друг другу послать, то никто из них ничего «не замечает», и TCP-сеанс сохраняется. В случае периодических проверок TCPKeepAlive возрастает вероятность обращения сервера к клиенту в моменты временного исчезновения связи, что может вести к принудительным разрывам TCP-соединения. В такой ситуации можно попробовать увеличить на сервере KeepAliveInterval до 60-75 секунд (вспомнив, что в Windows умолчание — 1 секунда) при максимальном количестве повторов равным 10, в надежде, что за 10 минут любая временная сетевая проблема самоустранится. Правда, если повторные передачи будут длиться слишком долго, и окажется, что
KeepAliveTime + (KeepAliveInterval * кол-во_повторов) > 10 минут
то TCP-сеанс, несмотря на все предпринятые усилия, может быть принят за «мёртвый» и вычищен из NAT-таблицы.

Другая категория проблем связана с недостаточной пропускной способности используемых маршрутизаторов и/или каналов связи, когда при перегрузке могут теряться любые пакеты, в том числе и KeepAlive. В случае маршрутизаторов такие проблемы иногда решаются сменой прошивки (мне, например, это помогло победить Acorp ADSL XXXX), или, в худшем случае, заменой его на более производительную модель. В случае «слишком узких» каналов связи не остаётся ничего другого, кроме как их расширять.

Заключение

Предложенный подход позволяет искусственно поддерживать активность сеансов TCP/IP, по которым в текущий момент не передается никаких данных, исключительно на системном уровне, не внося каких-либо изменений в прикладной код. На сегодня он проверен и успешно используется в Caché for UNIX (Red Hat Enterprise Linux 5 for x86-64) 2010.1.4 (Build 803), Caché for Windows (x86-64) 2010.1.4 (Build 803), а также в более поздних версиях.

Следует признать, что он эффективно работает, если сетевое соединение физически устойчиво, и кроме разрыва неактивных сеансов других сетевых проблем у вас нет.

При развёртывании приложения в агрессивной среде (удалённый доступ, распределённые системы и т.д.), подумайте о реализации KeepAlive не на уровне TCP, а на уровне защищённого протокола более высокого уровня; хорошим кандидатом здесь оказывается SSH.

Источник

Adblock
detector