diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index ddac0cbea..f3eb4211f 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -2376,7 +2376,7 @@ func getKubernetesInfo(dctx context.Context) madmin.KubernetesInfo { } client := &http.Client{ - Transport: globalHealthChkTransport, + Transport: globalRemoteTargetTransport, Timeout: 10 * time.Second, } diff --git a/cmd/config-current.go b/cmd/config-current.go index 062361887..0847a90a3 100644 --- a/cmd/config-current.go +++ b/cmd/config-current.go @@ -678,7 +678,7 @@ func applyDynamicConfigForSubSys(ctx context.Context, objAPI ObjectLayer, s conf } } case config.SubnetSubSys: - subnetConfig, err := subnet.LookupConfig(s[config.SubnetSubSys][config.Default], globalProxyTransport) + subnetConfig, err := subnet.LookupConfig(s[config.SubnetSubSys][config.Default], globalRemoteTargetTransport) if err != nil { configLogIf(ctx, fmt.Errorf("Unable to parse subnet configuration: %w", err)) } else { diff --git a/cmd/endpoint.go b/cmd/endpoint.go index fa56ffc81..1709883dd 100644 --- a/cmd/endpoint.go +++ b/cmd/endpoint.go @@ -1205,7 +1205,7 @@ func GetProxyEndpoints(endpointServerPools EndpointServerPools) []ProxyEndpoint proxyEps = append(proxyEps, ProxyEndpoint{ Endpoint: endpoint, - Transport: globalProxyTransport, + Transport: globalRemoteTargetTransport, }) } } diff --git a/cmd/globals.go b/cmd/globals.go index 58eea1125..3dfa37ee0 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -398,12 +398,8 @@ var ( globalInternodeTransport http.RoundTripper - globalProxyTransport http.RoundTripper - globalRemoteTargetTransport http.RoundTripper - globalHealthChkTransport http.RoundTripper - globalDNSCache = &dnscache.Resolver{ Timeout: 5 * time.Second, } diff --git a/cmd/server-main.go b/cmd/server-main.go index 1a068eaff..c4f83c77b 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -362,22 +362,6 @@ func serverHandleCmdArgs(ctxt serverCtxt) { // Initialize, see which NIC the service is running on, and save it as global value setGlobalInternodeInterface(ctxt.Interface) - // allow transport to be HTTP/1.1 for proxying. - globalProxyTransport = NewCustomHTTPProxyTransport()() - globalProxyEndpoints = GetProxyEndpoints(globalEndpoints) - globalInternodeTransport = NewInternodeHTTPTransport(ctxt.MaxIdleConnsPerHost)() - globalRemoteTargetTransport = NewRemoteTargetHTTPTransport(false)() - globalHealthChkTransport = NewHTTPTransport() - globalForwarder = handlers.NewForwarder(&handlers.Forwarder{ - PassHost: true, - RoundTripper: NewHTTPTransportWithTimeout(1 * time.Hour), - Logger: func(err error) { - if err != nil && !errors.Is(err, context.Canceled) { - replLogIf(GlobalContext, err) - } - }, - }) - globalTCPOptions = xhttp.TCPOptions{ UserTimeout: int(ctxt.UserTimeout.Milliseconds()), ClientReadTimeout: ctxt.ConnClientReadDeadline, @@ -385,6 +369,20 @@ func serverHandleCmdArgs(ctxt serverCtxt) { Interface: ctxt.Interface, } + // allow transport to be HTTP/1.1 for proxying. + globalProxyEndpoints = GetProxyEndpoints(globalEndpoints) + globalInternodeTransport = NewInternodeHTTPTransport(ctxt.MaxIdleConnsPerHost)() + globalRemoteTargetTransport = NewRemoteTargetHTTPTransport(false)() + globalForwarder = handlers.NewForwarder(&handlers.Forwarder{ + PassHost: true, + RoundTripper: globalRemoteTargetTransport, + Logger: func(err error) { + if err != nil && !errors.Is(err, context.Canceled) { + replLogIf(GlobalContext, err) + } + }, + }) + // On macOS, if a process already listens on LOCALIPADDR:PORT, net.Listen() falls back // to IPv6 address ie minio will start listening on IPv6 address whereas another // (non-)minio process is listening on IPv4 of given port. @@ -1024,7 +1022,7 @@ func serverMain(ctx *cli.Context) { globalMinioClient, err = minio.New(globalLocalNodeName, &minio.Options{ Creds: credentials.NewStaticV4(globalActiveCred.AccessKey, globalActiveCred.SecretKey, ""), Secure: globalIsTLS, - Transport: globalProxyTransport, + Transport: globalRemoteTargetTransport, Region: region, }) logger.FatalIf(err, "Unable to initialize MinIO client") diff --git a/cmd/utils.go b/cmd/utils.go index e5e3454cc..aa1ad58e3 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -594,29 +594,17 @@ func NewInternodeHTTPTransport(maxIdleConnsPerHost int) func() http.RoundTripper }.NewInternodeHTTPTransport(maxIdleConnsPerHost) } -// NewCustomHTTPProxyTransport is used only for proxied requests, specifically -// only supports HTTP/1.1 -func NewCustomHTTPProxyTransport() func() *http.Transport { - return xhttp.ConnSettings{ - LookupHost: globalDNSCache.LookupHost, - DialTimeout: rest.DefaultTimeout, - RootCAs: globalRootCAs, - CipherSuites: fips.TLSCiphers(), - CurvePreferences: fips.TLSCurveIDs(), - EnableHTTP2: false, - TCPOptions: globalTCPOptions, - }.NewCustomHTTPProxyTransport() -} - // NewHTTPTransportWithClientCerts returns a new http configuration // used while communicating with the cloud backends. -func NewHTTPTransportWithClientCerts(clientCert, clientKey string) *http.Transport { +func NewHTTPTransportWithClientCerts(clientCert, clientKey string) http.RoundTripper { s := xhttp.ConnSettings{ - LookupHost: globalDNSCache.LookupHost, - DialTimeout: defaultDialTimeout, - RootCAs: globalRootCAs, - TCPOptions: globalTCPOptions, - EnableHTTP2: false, + LookupHost: globalDNSCache.LookupHost, + DialTimeout: defaultDialTimeout, + RootCAs: globalRootCAs, + CipherSuites: fips.TLSCiphersBackwardCompatible(), + CurvePreferences: fips.TLSCurveIDs(), + TCPOptions: globalTCPOptions, + EnableHTTP2: false, } if clientCert != "" && clientKey != "" { @@ -633,7 +621,7 @@ func NewHTTPTransportWithClientCerts(clientCert, clientKey string) *http.Transpo return transport } - return s.NewHTTPTransportWithTimeout(1 * time.Minute) + return globalRemoteTargetTransport } // NewHTTPTransport returns a new http configuration @@ -648,12 +636,14 @@ const defaultDialTimeout = 5 * time.Second // NewHTTPTransportWithTimeout allows setting a timeout. func NewHTTPTransportWithTimeout(timeout time.Duration) *http.Transport { return xhttp.ConnSettings{ - DialContext: newCustomDialContext(), - LookupHost: globalDNSCache.LookupHost, - DialTimeout: defaultDialTimeout, - RootCAs: globalRootCAs, - TCPOptions: globalTCPOptions, - EnableHTTP2: false, + DialContext: newCustomDialContext(), + LookupHost: globalDNSCache.LookupHost, + DialTimeout: defaultDialTimeout, + RootCAs: globalRootCAs, + TCPOptions: globalTCPOptions, + CipherSuites: fips.TLSCiphersBackwardCompatible(), + CurvePreferences: fips.TLSCurveIDs(), + EnableHTTP2: false, }.NewHTTPTransportWithTimeout(timeout) } @@ -682,11 +672,13 @@ func newCustomDialContext() xhttp.DialContext { // used while communicating with the remote replication targets. func NewRemoteTargetHTTPTransport(insecure bool) func() *http.Transport { return xhttp.ConnSettings{ - DialContext: newCustomDialContext(), - LookupHost: globalDNSCache.LookupHost, - RootCAs: globalRootCAs, - TCPOptions: globalTCPOptions, - EnableHTTP2: false, + DialContext: newCustomDialContext(), + LookupHost: globalDNSCache.LookupHost, + RootCAs: globalRootCAs, + CipherSuites: fips.TLSCiphersBackwardCompatible(), + CurvePreferences: fips.TLSCurveIDs(), + TCPOptions: globalTCPOptions, + EnableHTTP2: false, }.NewRemoteTargetHTTPTransport(insecure) } diff --git a/cmd/warm-backend-gcs.go b/cmd/warm-backend-gcs.go index c2fbde344..029c2550b 100644 --- a/cmd/warm-backend-gcs.go +++ b/cmd/warm-backend-gcs.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "io" + "net/http" "cloud.google.com/go/storage" "github.com/minio/madmin-go/v3" @@ -102,7 +103,7 @@ func (gcs *warmBackendGCS) InUse(ctx context.Context) (bool, error) { return false, nil } -func newWarmBackendGCS(conf madmin.TierGCS, _ string) (*warmBackendGCS, error) { +func newWarmBackendGCS(conf madmin.TierGCS, tier string) (*warmBackendGCS, error) { // Validation code if conf.Creds == "" { return nil, errors.New("empty credentials unsupported") @@ -117,7 +118,16 @@ func newWarmBackendGCS(conf madmin.TierGCS, _ string) (*warmBackendGCS, error) { return nil, err } - client, err := storage.NewClient(context.Background(), option.WithCredentialsJSON(credsJSON), option.WithScopes(storage.ScopeReadWrite)) + clnt := &http.Client{ + Transport: globalRemoteTargetTransport, + } + + client, err := storage.NewClient(context.Background(), + option.WithCredentialsJSON(credsJSON), + option.WithScopes(storage.ScopeReadWrite), + option.WithHTTPClient(clnt), + option.WithUserAgent(fmt.Sprintf("gcs-tier-%s", tier)+SlashSeparator+ReleaseTag), + ) if err != nil { return nil, err } diff --git a/cmd/warm-backend-minio.go b/cmd/warm-backend-minio.go index c184b3d77..94c09f226 100644 --- a/cmd/warm-backend-minio.go +++ b/cmd/warm-backend-minio.go @@ -25,7 +25,6 @@ import ( "math" "net/url" "strings" - "time" "github.com/minio/madmin-go/v3" minio "github.com/minio/minio-go/v7" @@ -108,14 +107,11 @@ func newWarmBackendMinIO(conf madmin.TierMinIO, tier string) (*warmBackendMinIO, } creds := credentials.NewStaticV4(conf.AccessKey, conf.SecretKey, "") - - getRemoteTierTargetInstanceTransportOnce.Do(func() { - getRemoteTierTargetInstanceTransport = NewHTTPTransportWithTimeout(10 * time.Minute) - }) opts := &minio.Options{ - Creds: creds, - Secure: u.Scheme == "https", - Transport: getRemoteTierTargetInstanceTransport, + Creds: creds, + Secure: u.Scheme == "https", + Transport: globalRemoteTargetTransport, + TrailingHeaders: true, } client, err := minio.New(u.Host, opts) if err != nil { diff --git a/cmd/warm-backend-s3.go b/cmd/warm-backend-s3.go index 28b314c36..de7e7d96d 100644 --- a/cmd/warm-backend-s3.go +++ b/cmd/warm-backend-s3.go @@ -25,20 +25,12 @@ import ( "net/http" "net/url" "strings" - "sync" - "time" "github.com/minio/madmin-go/v3" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" ) -// getRemoteTierTargetInstanceTransport contains a singleton roundtripper. -var ( - getRemoteTierTargetInstanceTransport http.RoundTripper - getRemoteTierTargetInstanceTransportOnce sync.Once -) - type warmBackendS3 struct { client *minio.Client core *minio.Core @@ -162,13 +154,10 @@ func newWarmBackendS3(conf madmin.TierS3, tier string) (*warmBackendS3, error) { default: return nil, errors.New("insufficient parameters for S3 backend authentication") } - getRemoteTierTargetInstanceTransportOnce.Do(func() { - getRemoteTierTargetInstanceTransport = NewHTTPTransportWithTimeout(10 * time.Minute) - }) opts := &minio.Options{ Creds: creds, Secure: u.Scheme == "https", - Transport: getRemoteTierTargetInstanceTransport, + Transport: globalRemoteTargetTransport, } client, err := minio.New(u.Host, opts) if err != nil { diff --git a/cmd/warm-backend.go b/cmd/warm-backend.go index 1fb90258c..bc17f83b2 100644 --- a/cmd/warm-backend.go +++ b/cmd/warm-backend.go @@ -18,11 +18,11 @@ package cmd import ( - "bytes" "context" "errors" "fmt" "io" + "strings" "github.com/minio/madmin-go/v3" xhttp "github.com/minio/minio/internal/http" @@ -48,8 +48,7 @@ const probeObject = "probeobject" // checkWarmBackend checks if tier config credentials have sufficient privileges // to perform all operations defined in the WarmBackend interface. func checkWarmBackend(ctx context.Context, w WarmBackend) error { - var empty bytes.Reader - remoteVersionID, err := w.Put(ctx, probeObject, &empty, 0) + remoteVersionID, err := w.Put(ctx, probeObject, strings.NewReader("MinIO"), 5) if err != nil { if _, ok := err.(BackendDown); ok { return err