Heim  >  Artikel  >  Backend-Entwicklung  >  So beheben Sie Proxyconnect TCP: TLS: Der erste Datensatz sieht nicht nach TLS-Handshake aus

So beheben Sie Proxyconnect TCP: TLS: Der erste Datensatz sieht nicht nach TLS-Handshake aus

王林
王林nach vorne
2024-02-11 10:18:07606Durchsuche

如何修复 proxyconnect tcp: tls: 第一条记录看起来不像 TLS 握手

PHP-Editor Apple ist hier, um Ihnen eine Lösung für das Problem „proxyconnect tcp: tls: erster Datensatz sieht nicht nach TLS-Handshake aus“ zu bieten. Dieser Fehler tritt normalerweise bei der Verwendung eines Proxyservers auf und kann zu Netzwerkverbindungsproblemen führen. Bevor wir dieses Problem lösen können, müssen wir zunächst die Ursache des Problems verstehen. Mit den folgenden einfachen Schritten zeigen wir Ihnen, wie Sie dieses Problem beheben können, um sicherzustellen, dass Ihre Netzwerkverbindung ordnungsgemäß funktioniert.

Frageninhalt

In So verwenden Sie die REST-API in Go wird ein voll funktionsfähiger Beispielcode zum Aufrufen der öffentlichen REST-API bereitgestellt. Aber wenn ich das Beispiel versuche, erhalte ich diese Fehlermeldung:

error getting cat fact: 
      Get "https://catfact.ninja/fact": 
      proxyconnect tcp: tls: first record does not look like a TLS handshake

Dokumentation zum http-Status

<code>
For control over proxies, TLS configuration, keep-alives, compression, and other settings, create a Transport:
</code>

Und Überweisungsunterlagen:

<code>    // DialContext specifies the dial function for creating unencrypted TCP connections.
    // If DialContext is nil (and the deprecated Dial below is also nil),
    // then the transport dials using package net.
    //
    // DialContext runs concurrently with calls to RoundTrip.
    // A RoundTrip call that initiates a dial may end up using
    // a connection dialed previously when the earlier connection
    // becomes idle before the later DialContext completes.
    DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
</code>

Ich gehe also davon aus, dass ich den Dialcontext konfigurieren muss, um unsichere Verbindungen vom Client zum Proxy zu ermöglichen without TLS. Aber ich weiß nicht, wie ich es machen soll. Lesen Sie diese:

  • So führen Sie Proxy und TLS in Golang durch;
  • So führen Sie HTTP/HTTPS GET über einen Proxy durch; und
  • Wie führe ich eine https-Anfrage mit einem falschen Zertifikat durch?

Auch nicht hilfreich. Einige haben den gleichen Fehler proxyconnect tcp: tls:first record does not Look like a TLS handshake und erklären warum:

<code>
This is because the proxy answers with an plain HTTP error to the strange HTTP request (which is actually the start of the TLS handshake).
</code>

Aber Steffens Antwort enthält keinen Beispielcode für die Einrichtung DialContext func(ctx context.Context, network, addr string),Bogdan和cyberdelia都建议设置tls.Config{InsecureSkipVerify: true}, zum Beispiel so

<code>    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }
    client := &http.Client{Transport: tr}
</code>

Aber das oben Gesagte hat keine Auswirkung. Ich erhalte immer noch den gleichen Fehler. und die Verbindung ruft immer noch https://* 而不是 http://*

Hier ist Beispielcode, ich habe versucht, die oben genannten Vorschläge einzubeziehen und anzupassen:

<code>var tr = &http.Transport{ TLSClientConfig: 
                           &tls.Config{InsecureSkipVerify: true}, } 
                           // lacks DialContext config
var client*  http.Client = &http.Client{Transport: tr} // modified * added
// var client *http.Client // code from tutorial

type CatFact struct {
    Fact   string `json:"fact"`
    Length int    `json:"length"`
}

func GetCatFact() {
    url := "http://catfact.ninja/fact" // changed from https to http
    var catFact CatFact

    err := GetJson(url, &catFact)
    if err != nil {
        fmt.Printf("error getting cat fact: %s\n", err.Error())
    } else {
        fmt.Printf("A super interesting Cat Fact: %s\n", catFact.Fact)
    }
}

func main() {
    client = &http.Client{Timeout: 10 * time.Second}
    GetCatFact()
    // same error 
    // proxyconnect tcp: tls: first record does 
    //                   not look like a TLS handshake
    // still uses https 
    // for GET catfact.ninja
}
</code>

Wie konfiguriere ich die Verbindung so, dass eine unverschlüsselte Verbindung von myClient zum Server über einen Proxy verwendet wird? Hilft die Einstellung DialContext func(ctx context.Context, network, addr string) dabei? was zu tun?

Lösung

Ich habe es gerade versucht:

package main

import (
    "context"
    "crypto/tls"
    "encoding/json"
    "fmt"
    "net"
    "net/http"
    "time"
)

type CatFact struct {
    Fact   string `json:"fact"`
    Length int    `json:"length"`
}

// Custom dialing function to handle connections
func customDialContext(ctx context.Context, network, addr string) (net.Conn, error) {
    conn, err := net.Dial(network, addr)
    return conn, err
}

// Function to get a cat fact
func GetCatFact(client *http.Client) {
    url := "https://catfact.ninja/fact"  // Reverted back to https
    var catFact CatFact

    err := GetJson(url, &catFact, client)
    if err != nil {
        fmt.Printf("error getting cat fact: %s\n", err.Error())
    } else {
        fmt.Printf("A super interesting Cat Fact: %s\n", catFact.Fact)
    }
}

// Function to send a GET request and decode the JSON response
func GetJson(url string, target interface{}, client *http.Client) error {
    resp, err := client.Get(url)
    if err != nil {
        return fmt.Errorf("error sending GET request: %w", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return fmt.Errorf("received non-OK HTTP status: %d", resp.StatusCode)
    }

    err = json.NewDecoder(resp.Body).Decode(target)
    if err != nil {
        return fmt.Errorf("error decoding JSON response: %w", err)
    }

    return nil
}

func main() {
    // Create a custom Transport with the desired settings
    tr := &http.Transport{
        Proxy: http.ProxyFromEnvironment,  // Use the proxy settings from the environment
        DialContext: customDialContext,    // Use the custom dialing function
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: true,  // Skip certificate verification (not recommended in production)
        },
    }

    // Create a new HTTP client using the custom Transport
    client := &http.Client{
        Transport: tr,
        Timeout:   10 * time.Second,
    }

    // Call the function to get a cat fact
    GetCatFact(client)
}

Es beinhaltet:

  • Benutzerdefinierte WählfunktioncustomDialContext:
    Diese Funktion ist derzeit ein einfacher Wrapper für net.Dial, bietet jedoch die Möglichkeit, bei Bedarf eine benutzerdefinierte Wähllogik einzuführen. Es wird als benutzerdefinierte Wählfunktion zum Erstellen von Netzwerkverbindungen verwendet.

  • Übertragungskonfiguration:

    • Der geänderte Code wird angepasst http.Transport mit spezifischer Einstellungskonfiguration, einschließlich benutzerdefinierter Wählfunktion, Proxy-Einstellungen in der Umgebung und einer TLS-Konfiguration, die die Zertifikatsüberprüfung überspringt (zu Testzwecken).
    • Der ursprüngliche Code versuchte auch, benutzerdefinierte http.Transport zu konfigurieren, enthielt jedoch nur eine TLS-Konfiguration, die die Zertifikatsüberprüfung übersprang und keine benutzerdefinierten Einwahlfunktionen oder Proxy-Einstellungen festlegte.
  • Client-Konfiguration:

    • Der geänderte Code verwendet ein benutzerdefiniertes http.Transport 创建新的 http.Client, um einen neuen http.Client zu erstellen und das Timeout auf 10 Sekunden festzulegen.
    • Der ursprüngliche Code versucht auch, einen neuen http.Client mit benutzerdefiniertem http.Transport 创建新的 http.Client ,但后来在 main 函数中,它使用新的 http.Client 覆盖了 client 变量,其中包含默认的 Transport 和超时10秒的,有效丢弃自定义的 Transport zu erstellen, verwendet dann aber in der Funktion main den neuen http.Client > Überschreibt die Variable client, die den Standard-Transport und ein Zeitlimit von 10 Sekunden enthält, wodurch der benutzerdefinierte Transport effektiv verworfen wird.
  • Funktionssignatur:

    • Der geänderte Code wurde geändert GetCatFactGetJson 函数以接受 *http.Client 参数,允许它们使用在 main 中创建的自定义 http.Client.
    • Der Originalcode enthielt nicht http.Client 传递给这些函数,因此它们将使用 net/http 包提供的默认 http.Client .
  • Website:

    • Der geänderte Code stellt die URL in der Funktion GetCatFact auf „https://catfact.ninja/fact“ wieder her, da der Server HTTP-Anfragen ohnehin auf HTTPS umleitet.
    • Der ursprüngliche Code hat die URL in „http://catfact.ninja/fact“ geändert, um TLS-Handshake-Fehler zu vermeiden.

Die customDialContext 函数不包含任何专门忽略 TLS 握手错误或将 TLS 握手更改为非 TLS 连接的逻辑。它只提供了自定义拨号功能,在提供的形式中,直接调用net.Dial-Funktion im oben bereitgestellten Code enthält keine Logik, um TLS-Handshake-Fehler gezielt zu ignorieren oder den TLS-Handshake auf eine Nicht-TLS-Verbindung umzustellen. Es bietet nur benutzerdefinierte Wählfunktionen in der bereitgestellten Form und ruft direkt an

ohne besondere Verarbeitung.

http.Transport结构体的TLSClientConfig字段提供的,具体是将InsecureSkipVerify字段设置为trueDer Mechanismus zum Ignorieren von TLS-Zertifikatsüberprüfungsfehlern wird tatsächlich durch das Feld TLSClientConfig der

Struktur bereitgestellt, insbesondere durch Setzen des Felds InsecureSkipVerify auf true :🎜
tr := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}

该配置告诉 Go 跳过验证服务器的证书链和主机名,这是 TLS 握手过程的一部分。但是,它不会忽略其他类型的 TLS 握手错误或切换到非 TLS 连接。通常不建议在生产环境中使用 InsecureSkipVerify: true,因为它会禁用重要的安全检查。

如果您想强制使用非 TLS(纯 HTTP)连接,通常只需使用 http:// URL,而不是 https:// URL。但是,如果服务器或代理服务器将 HTTP 重定向到 HTTPS(例如 http://catfact.ninja/fact 的情况),则客户端将遵循重定向并切换到 TLS 连接。

Das obige ist der detaillierte Inhalt vonSo beheben Sie Proxyconnect TCP: TLS: Der erste Datensatz sieht nicht nach TLS-Handshake aus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen