v5.0.68: TLSNextProto fix — disable HTTP/2 ALPN (DDoS-Guard EOF)

This commit is contained in:
“Naeel”
2026-07-01 15:40:09 +04:00
parent e06e8de134
commit 7862ea7e45
5 changed files with 165 additions and 73 deletions
@@ -1,13 +1,9 @@
package provider
import (
"bufio"
"context"
"crypto/tls"
"fmt"
"net"
"net/http"
"net/url"
"os"
"strings"
"time"
@@ -21,7 +17,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
utls "github.com/refraction-networking/utls"
)
var _ provider.Provider = &NubesProvider{}
@@ -128,59 +123,12 @@ func (p *NubesProvider) Configure(ctx context.Context, req provider.ConfigureReq
// HTTP transport: клонируем DefaultTransport чтобы сохранить системные настройки (proxy, timeouts).
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.TLSHandshakeTimeout = 60 * time.Second
transport.ForceAttemptHTTP2 = false
// utls: маскируем Go TLS под Firefox, чтобы пройти DDoS-Guard (JA3 fingerprint).
// Стандартный crypto/tls и Chrome блокируются на deck-api-*.ngcloud.ru.
transport.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
// Используем прокси если задан (HTTPS_PROXY) — без него API не доступен
dialer := &net.Dialer{Timeout: 30 * time.Second}
proxyFunc := transport.Proxy
target := addr
if proxyFunc != nil {
proxy, err := proxyFunc(&http.Request{URL: &url.URL{Scheme: "https", Host: target}})
if err == nil && proxy != nil {
conn, err := dialer.DialContext(ctx, "tcp", proxy.Host)
if err != nil {
return nil, err
}
// CONNECT tunnel
fmt.Fprintf(conn, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n\r\n", target, target)
br := bufio.NewReader(conn)
resp, err := http.ReadResponse(br, nil)
if err != nil || resp.StatusCode != 200 {
conn.Close()
return nil, fmt.Errorf("proxy CONNECT failed: %v", err)
}
host, _, _ := net.SplitHostPort(target)
uconn := utls.UClient(conn, &utls.Config{
ServerName: host,
InsecureSkipVerify: insecureSkipVerify,
MinVersion: tls.VersionTLS12,
}, utls.HelloFirefox_120)
if err := uconn.HandshakeContext(ctx); err != nil {
conn.Close()
return nil, err
}
return uconn, nil
}
}
// Прямое соединение (без прокси)
conn, err := dialer.DialContext(ctx, network, addr)
if err != nil {
return nil, err
}
host, _, _ := net.SplitHostPort(addr)
uconn := utls.UClient(conn, &utls.Config{
ServerName: host,
InsecureSkipVerify: insecureSkipVerify,
MinVersion: tls.VersionTLS12,
}, utls.HelloFirefox_120)
if err := uconn.HandshakeContext(ctx); err != nil {
conn.Close()
return nil, err
}
return uconn, nil
// Отключаем HTTP/2: ColdFusion + DDoS-Guard не поддерживают h2 → EOF.
// Пустой TLSNextProto убирает h2 из ALPN → только HTTP/1.1.
transport.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) http.RoundTripper)
transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: insecureSkipVerify,
MinVersion: tls.VersionTLS12,
}
// Определяем уровень логирования операций: none (тихий) / info / debug.