Ошибка рукопожатия HTTP-клиента golang

Попробуйте получить веб-страницу:

    tr := &http.Transport{
        TLSHandshakeTimeout: 30 * time.Second,
        DisableKeepAlives: true,
    }

    client := &http.Client{Transport: tr}

    req, err := http.NewRequest("GET", "https://www.fl.ru/", nil)
    if err != nil {
        log.Fatalf("%s\n", err);
    }

    resp, err := client.Do(req);
    if err != nil {
        log.Fatalf("%s\n", err);
    }
    defer resp.Body.Close()

Получите https://www.fl.ru/: удаленная ошибка: сбой рукопожатия.

Если я попытаюсь получить еще одну страницу HTTPS - все в порядке.


person Nikolay    schedule 11.09.2015    source источник
comment
@ Ainar-G Да, это 1.5   -  person Nikolay    schedule 11.09.2015


Ответы (1)


Этот сервер поддерживает только несколько слабых шифров:

TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)   DH 1024 bits (p: 128, g: 1, Ys: 128)   FS   WEAK
TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33)   DH 1024 bits (p: 128, g: 1, Ys: 128)   FS   WEAK
TLS_RSA_WITH_RC4_128_SHA (0x5)   WEAK

Если вам действительно необходимо подключиться к этому серверу, Go поддерживает последний шифр в списке, но не по умолчанию. Создайте клиента с новым tls.Config, указав нужный шифр:

t := &http.Transport{
    Proxy: http.ProxyFromEnvironment,
    Dial: (&net.Dialer{
        Timeout:   30 * time.Second,
        KeepAlive: 30 * time.Second,
    }).Dial,
    TLSHandshakeTimeout: 10 * time.Second,
    TLSClientConfig: &tls.Config{
        CipherSuites: []uint16{tls.TLS_RSA_WITH_RC4_128_SHA},
    },
}
person JimB    schedule 11.09.2015
comment
Это круто. Не могли бы вы рассказать, как вы это отлаживали? Кроме того, есть идеи, почему это могло работать в 1.4.2 и сломаться в 1.5? - person Ainar-G; 11.09.2015
comment
@ Ainar-G: RC4 был отключен, потому что он очень слаб, и теперь запрещен: tools.ietf.org / html / rfc7465. - person JimB; 11.09.2015
comment
@ Ainar-G: повторная отладка; Распространенная причина сбоев рукопожатия - отсутствие общих шифров, поэтому я смотрю, что поддерживает сервер, и проверяю их с константами, определенными в crypto / tls. (Я также проверяю, поддерживает ли сервер tls1.1, tls1.2 и т. Д. Go1.5 теперь немного лучше справляется с ошибками серверов, поэтому он, как правило, более снисходительный) - person JimB; 11.09.2015
comment
@JimB Спасибо! Именно то, что нужно. Как вы можете проверить поддерживаемые протоколы? - person Nikolay; 11.09.2015
comment
@Nikolay: самый простой способ - это ssllabs.com. Вы также можете создать сценарий с любым клиентом tls, а также с некоторыми другими методами, упомянутыми здесь: superuser.com/questions/109213/, - person JimB; 11.09.2015