Вопрос или проблема
Я использую Windows Server 2012 в качестве рабочей станции. Проблема заключается в том, что HTTPS-соединения, инициируемые node.js, случайным образом терпят неудачу. Возможно, это системная проблема, и не только node затрагивается, но это чаще всего проявляется именно с node.
Поскольку любой HTTPS-запрос может случайным образом потерпеть неудачу, npm install
становится лотереей, и для больших пакетов он всегда завершится с ECONNRESET
на ошибке TLSWrap.onread
после бесконечных попыток. Другой пример — это мой скрипт node для получения содержимого папки из Github, который почти всегда терпит неудачу, пытаясь скачать первый файл, но иногда он может получить несколько, а затем снова потерпеть неудачу.
На этом компьютере установлены только стандартный брандмауэр Windows и System Center Endpoint Protection (также известный как Microsoft Security Essentials), и я пытался отключить их обоих — без результата. Также замена сетевой карты, IP-адреса, шлюза или даже провайдера интернета не помогла. Я также попытался удалить и затем снова установить некоторые обновления Windows, связанные с SSL, и это также не помогло. Однако все работает нормально на другом ПК, подключенном к тому же коммутатору, и даже на этом ПК под управлением Linux. Время и дата установлены правильно, просмотр веб-страниц (HTTP и HTTPS) также в порядке, за исключением редких ошибок сброса соединения на некоторых, но не на всех сайтах с поддержкой HTTPS (например, imgur.com).
Вот два вывода из openssl, выполненных с разницей в несколько секунд: первый проходит, второй терпит неудачу.
openssl s_client -msg -debug -state -connect www.npmjs.com:443
Первый вывод слишком велик для вставки в сообщение, поэтому вот ссылка на pastebin.
Второй:
CONNECTED(00000138)
write to 0xf4e608 [0xf87210] (307 bytes => 307 (0x133))
0000 - 16 03 01 01 2e 01 00 01-2a 03 03 4b 71 63 8e 02 ........*..Kqc..
0010 - 73 68 40 9b 77 eb 06 5f-47 58 c5 3e d5 0f 33 1d [email protected].._GX.>..3.
0020 - 76 73 d1 b0 0a 11 b8 84-29 32 e3 00 00 ac c0 30 vs......)2.....0
0030 - c0 2c c0 28 c0 24 c0 14-c0 0a 00 a5 00 a3 00 a1 .,.(.$..........
0040 - 00 9f 00 6b 00 6a 00 69-00 68 00 39 00 38 00 37 ...k.j.i.h.9.8.7
0050 - 00 36 00 88 00 87 00 86-00 85 c0 32 c0 2e c0 2a .6.........2...*
0060 - c0 26 c0 0f c0 05 00 9d-00 3d 00 35 00 84 c0 2f .&.......=.5.../
0070 - c0 2b c0 27 c0 23 c0 13-c0 09 00 a4 00 a2 00 a0 .+.'.#..........
0080 - 00 9e 00 67 00 40 00 3f-00 3e 00 33 00 32 00 31 ...g.@.?.>.3.2.1
0090 - 00 30 00 9a 00 99 00 98-00 97 00 45 00 44 00 43 .0.........E.D.C
00a0 - 00 42 c0 31 c0 2d c0 29-c0 25 c0 0e c0 04 00 9c .B.1.-.).%......
00b0 - 00 3c 00 2f 00 96 00 41-00 07 c0 11 c0 07 c0 0c .<./...A........
00c0 - c0 02 00 05 00 04 c0 12-c0 08 00 16 00 13 00 10 ................
00d0 - 00 0d c0 0d c0 03 00 0a-00 ff 01 00 00 55 00 0b .............U..
00e0 - 00 04 03 00 01 02 00 0a-00 1c 00 1a 00 17 00 19 ................
00f0 - 00 1c 00 1b 00 18 00 1a-00 16 00 0e 00 0d 00 0b ................
0100 - 00 0c 00 09 00 0a 00 23-00 00 00 0d 00 20 00 1e .......#..... ..
0110 - 06 01 06 02 06 03 05 01-05 02 05 03 04 01 04 02 ................
0120 - 04 03 03 01 03 02 03 03-02 01 02 02 02 03 00 0f ................
0130 - 00 01 01 ...
>>> TLS 1.2 [length 0005]
16 03 01 01 2e
>>> TLS 1.2 Handshake [length 012e], ClientHello
01 00 01 2a 03 03 4b 71 63 8e 02 73 68 40 9b 77
eb 06 5f 47 58 c5 3e d5 0f 33 1d 76 73 d1 b0 0a
11 b8 84 29 32 e3 00 00 ac c0 30 c0 2c c0 28 c0
24 c0 14 c0 0a 00 a5 00 a3 00 a1 00 9f 00 6b 00
6a 00 69 00 68 00 39 00 38 00 37 00 36 00 88 00
87 00 86 00 85 c0 32 c0 2e c0 2a c0 26 c0 0f c0
05 00 9d 00 3d 00 35 00 84 c0 2f c0 2b c0 27 c0
23 c0 13 c0 09 00 a4 00 a2 00 a0 00 9e 00 67 00
40 00 3f 00 3e 00 33 00 32 00 31 00 30 00 9a 00
99 00 98 00 97 00 45 00 44 00 43 00 42 c0 31 c0
2d c0 29 c0 25 c0 0e c0 04 00 9c 00 3c 00 2f 00
96 00 41 00 07 c0 11 c0 07 c0 0c c0 02 00 05 00
04 c0 12 c0 08 00 16 00 13 00 10 00 0d c0 0d c0
03 00 0a 00 ff 01 00 00 55 00 0b 00 04 03 00 01
02 00 0a 00 1c 00 1a 00 17 00 19 00 1c 00 1b 00
18 00 1a 00 16 00 0e 00 0d 00 0b 00 0c 00 09 00
0a 00 23 00 00 00 0d 00 20 00 1e 06 01 06 02 06
03 05 01 05 02 05 03 04 01 04 02 04 03 03 01 03
02 03 03 02 01 02 02 02 03 00 0f 00 01 01
read from 0xf4e608 [0xf8c770] (7 bytes => -1 (0xFFFFFFFF))
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 307 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1457623360
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:error in SSLv2/v3 read server hello A
write:errno=10054
Вот ответ от API www.howsmyssl.com, запрошенный через node.js
{
"given_cipher_suites":[
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_DH_DSS_WITH_AES_256_GCM_SHA384",
"TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
"TLS_DH_RSA_WITH_AES_256_GCM_SHA384",
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
"TLS_DH_RSA_WITH_AES_256_CBC_SHA256",
"TLS_DH_DSS_WITH_AES_256_CBC_SHA256",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
"TLS_DH_RSA_WITH_AES_256_CBC_SHA",
"TLS_DH_DSS_WITH_AES_256_CBC_SHA",
"TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_AES_256_GCM_SHA384",
"TLS_RSA_WITH_AES_256_CBC_SHA256",
"TLS_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_DH_DSS_WITH_AES_128_GCM_SHA256",
"TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
"TLS_DH_RSA_WITH_AES_128_GCM_SHA256",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
"TLS_DH_RSA_WITH_AES_128_CBC_SHA256",
"TLS_DH_DSS_WITH_AES_128_CBC_SHA256",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
"TLS_DH_RSA_WITH_AES_128_CBC_SHA",
"TLS_DH_DSS_WITH_AES_128_CBC_SHA",
"TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_128_GCM_SHA256",
"TLS_RSA_WITH_AES_128_CBC_SHA256",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
"TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
"TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA",
"TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_EMPTY_RENEGOTIATION_INFO_SCSV"
],
"ephemeral_keys_supported":true,
"session_ticket_supported":true,
"tls_compression_supported":false,
"unknown_cipher_suite_supported":false,
"beast_vuln":false,
"able_to_detect_n_minus_one_splitting":false,
"insecure_cipher_suites":{
},
"tls_version":"TLS 1.2",
"rating":"Вероятно, нормально"
}
Я уже потратил бесконечные часы, пытаясь решить эту проблему, но ничего не помогает. Я не могу использовать node на этом ПК, и в современном мире это существенно, поэтому я публикую это здесь в надежде избежать переустановки ОС и всего программного обеспечения.
Вы можете сбросить стек TCP/IP, запустив эти команды в командной строке от имени администратора :
- Сбросить записи WINSOCK на значения по умолчанию:
netsh winsock reset catalog
- Сбросить стек TCP/IP IPv4 на значения по умолчанию:
netsh int ipv4 reset reset.log
- Сбросить стек TCP/IP IPv6 на значения по умолчанию:
netsh int ipv6 reset reset.log
- Сбросить каталог winsock:
netsh winsock reset catalog
- Или просто:
netsh int ip reset reset.log
- И
netsh winsock reset catalog
Возможно, некоторые команды выше дублируются, но это все команды сброса, которые я знаю.
Если все не помогает, не помешает отключить IPv6 и даже sfc /scannow, чтобы проверить компоненты Windows.
Ответ или решение
Проблема с SSL/TLS и сбоями соединения в Windows Server 2012
Проблема, с которой вы столкнулись, связана с ненадежностью HTTPS-соединений на Windows Server 2012, которые порой завершаются ошибкой ECONNRESET
в Node.js. Это сбои могут быть системной природой и затрагивать не только Node.js, но и другие приложения. Давайте разберем возможные причины и рекомендации по их устранению.
Возможные Причины Ошибки
-
Версии Программного Обеспечения: Обратите внимание на наличие обновлений для Windows и пакетов Node.js и npm. Убедитесь, что у вас установлены последние версии, так как устаревшие версии могут содержать известные уязвимости или ошибки.
-
Настройки Сети: Проверьте ваш сетевой интерфейс и настройки маршрутизатора. Иногда настройки MTU (Maximum Transmission Unit) могут вызывать проблемы с установлением SSL-соединений. Попробуйте уменьшить MTU до 1400 или ниже.
-
Защитный Мягкий Программный Обеспечению: Хотя отключение брандмауэра и Microsoft Security Essentials не привело к результатам, стоит проверить и другие параметры, такие как DPI (Deep Packet Inspection) или VPN-программное обеспечение, которые могут ограничивать соединения.
-
Проблемы с Протоколами SSL/TLS: Ваша система может неправильно обрабатывать протоколы SSL/TLS. Проверьте, включены ли все необходимые версии. Для Windows Server 2012 важно активировать TLS 1.2 и отключить устаревшие протоколы, такие как SSL 2.0 и SSL 3.0.
-
Проблемы с Драйверами Сетевых Карт: Устаревшие или несоответствующие драйверы могут привести к сбоям соединения. Убедитесь, что у вас стоят последние версии драйверов для сетевых карт.
Рекомендации по Устранению Ошибки
-
Сброс TCP/IP Стека: Используйте командную строку (CMD) с повышенными правами для сброса стека TCP/IP. Введите следующие команды:
netsh winsock reset catalog netsh int ipv4 reset reset.log netsh int ipv6 reset reset.log
-
Отключение IPv6: Если ваша сеть не использует IPv6, рассмотреть возможность его отключения может быть полезно. Это можно сделать через Панель управления или командную строку.
-
Проверка Поврежденных Файлов Windows: Выполните команду:
sfc /scannow
Это проверит целостность системных файлов и исправит поврежденные.
-
Тестирование через OpenSSL: Протестируйте соединение с помощью OpenSSL, для этого достаточно выполнить следующую команду:
openssl s_client -connect www.example.com:443
Это поможет вам увидеть, на каком этапе происходит сбой.
-
Логирование и Анализ: Включите детализированное логирование для Node.js и сетевых запросов, чтобы отслеживать, в какой момент происходит сбой.
-
Использование Альтернативных Библиотек: Если Node.js продолжает выдавать сбои только на вашем сервере, подумайте о возможности использования альтернативных библиотек для обращения к HTTPS-ресурсам (например,
axios
вместоnode-fetch
).
Заключение
Эта ситуация может быть вызвана множеством факторов, от настроек системы и сети до программного обеспечения. Подходя к решению метода последовательно и системно, можно значительно уменьшить вероятность возникновения ошибок соединения. Если все перечисленные шаги не помогают, возможно, стоит подумать о переустановке операционной системы как последнем средстве для восстановления функциональности сетевых приложений.