Сообщение об ошибке
remote error: tls: handshake failure
В HTTP-клиентах строка выглядит так: «Get \"https://…\": remote error: tls: handshake failure». На серверах Go использует ту же форму «remote error: tls: <alert>» в строках журнала «http: TLS handshake error from …», когда оповещение отправляет клиент.
Go crypto/tls client — the server sent TLS alert 40 (handshake_failure)
Что это означает
«remote error» означает, что другая сторона отправила оповещение TLS; здесь сервер отправил клиенту на Go оповещение 40 (handshake_failure). Сервер отверг параметры, которые предложил Go (наборы шифров, группы, алгоритмы подписи), или потребовал клиентский сертификат, которого Go не отправил. Какая из двух причин сработала, Go определить не может — это видно в журнале сервера.
Почему это происходит
Нет общего набора шифров
частоВ списке, который клиент Go предлагает по умолчанию, нет наборов шифров с обменом ключами RSA, с CBC или с 3DES; у серверов, ограниченных только такими наборами, нет с ним ничего общего.
Сервер требует клиентский сертификат
частоСерверы TLS 1.2 в режиме взаимной TLS-аутентификации часто отвечают на отсутствие сертификата оповещением handshake_failure.
Сервер не принимает SNI
иногдаНа CDN и прокси это оповещение может возникнуть при подключении по IP-адресу без ServerName или по имени, которое сервер не обслуживает.
Как исправить
- 1.
Сравните наборы шифров
tls.CipherSuites() перечисляет наборы шифров, которые Go считает безопасными и предлагает; сравните их с конфигурацией сервера.
go // What does this Go client offer by default? for _, s := range tls.CipherSuites() { fmt.Println(s.Name) } - 2.
Отправьте клиентский сертификат для взаимной TLS-аутентификации
Загрузите сертификат и ключ функцией tls.LoadX509KeyPair и укажите их в tls.Config.Certificates.
go // Mutual TLS: present a client certificate cert, err := tls.LoadX509KeyPair("client.pem", "client.key") if err != nil { log.Fatal(err) } client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{ Certificates: []tls.Certificate{cert}, }}} - 3.
Владельцам серверов: обновите наборы шифров
TLS 1.3 и наборы шифров TLS 1.2 на основе ECDHE работают с любым текущим релизом Go.
text Server side: enable TLS 1.3 and TLS 1.2 ECDHE suites with AES-GCM or ChaCha20-Poly1305.