Skip TLS verif for local address (#2323)
Since the console is talking locally to MinIO, skip the TLS verification if any. This will allow users to avoid defining the correct MINIO_SERVER_URL domain address, when TLS is enabled, is useful in a bare-metal setup.
This commit is contained in:
@@ -106,7 +106,7 @@ func getLoginDetailsResponse(params authApi.LoginDetailParams) (*models.LoginDet
|
||||
if oauth2.IsIDPEnabled() {
|
||||
loginStrategy = models.LoginDetailsLoginStrategyRedirectDashServiceDashAccount
|
||||
// initialize new oauth2 client
|
||||
oauth2Client, err := oauth2.NewOauth2ProviderClient(nil, r, restapi.GetConsoleHTTPClient())
|
||||
oauth2Client, err := oauth2.NewOauth2ProviderClient(nil, r, restapi.GetConsoleHTTPClient(""))
|
||||
if err != nil {
|
||||
return nil, restapi.ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -144,7 +144,7 @@ func getLoginOauth2AuthResponse(params authApi.LoginOauth2AuthParams) (*models.L
|
||||
|
||||
if oauth2.IsIDPEnabled() {
|
||||
// initialize new oauth2 client
|
||||
oauth2Client, err := oauth2.NewOauth2ProviderClient(nil, r, restapi.GetConsoleHTTPClient())
|
||||
oauth2Client, err := oauth2.NewOauth2ProviderClient(nil, r, restapi.GetConsoleHTTPClient(""))
|
||||
if err != nil {
|
||||
return nil, restapi.ErrorWithContext(ctx, err)
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ func getOperatorSubnetLoginResponse(session *models.Principal, params operator_a
|
||||
if username == "" || password == "" {
|
||||
return nil, restapi.ErrorWithContext(ctx, errors.New("empty credentials"))
|
||||
}
|
||||
subnetHTTPClient := &xhttp.Client{Client: restapi.GetConsoleHTTPClient()}
|
||||
subnetHTTPClient := &xhttp.Client{Client: restapi.GetConsoleHTTPClient("")}
|
||||
token, mfa, err := restapi.SubnetLogin(subnetHTTPClient, username, password)
|
||||
if err != nil {
|
||||
return nil, restapi.ErrorWithContext(ctx, err)
|
||||
@@ -102,7 +102,7 @@ func getOperatorSubnetLoginResponse(session *models.Principal, params operator_a
|
||||
func getOperatorSubnetLoginMFAResponse(session *models.Principal, params operator_api.OperatorSubnetLoginMFAParams) (*models.OperatorSubnetLoginResponse, *models.Error) {
|
||||
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
|
||||
defer cancel()
|
||||
subnetHTTPClient := &xhttp.Client{Client: restapi.GetConsoleHTTPClient()}
|
||||
subnetHTTPClient := &xhttp.Client{Client: restapi.GetConsoleHTTPClient("")}
|
||||
res, err := subnet.LoginWithMFA(subnetHTTPClient, *params.Body.Username, *params.Body.MfaToken, *params.Body.Otp)
|
||||
if err != nil {
|
||||
return nil, restapi.ErrorWithContext(ctx, err)
|
||||
@@ -115,7 +115,7 @@ func getOperatorSubnetLoginMFAResponse(session *models.Principal, params operato
|
||||
func getOperatorSubnetAPIKeyResponse(session *models.Principal, params operator_api.OperatorSubnetAPIKeyParams) (*models.OperatorSubnetAPIKey, *models.Error) {
|
||||
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
|
||||
defer cancel()
|
||||
subnetHTTPClient := &xhttp.Client{Client: restapi.GetConsoleHTTPClient()}
|
||||
subnetHTTPClient := &xhttp.Client{Client: restapi.GetConsoleHTTPClient("")}
|
||||
token := params.HTTPRequest.URL.Query().Get("token")
|
||||
apiKey, err := subnet.GetAPIKey(subnetHTTPClient, token)
|
||||
if err != nil {
|
||||
|
||||
@@ -948,7 +948,7 @@ func getUsageWidgetsForDeployment(ctx context.Context, prometheusURL string, mAd
|
||||
}
|
||||
|
||||
func unmarshalPrometheus(ctx context.Context, endpoint string, data interface{}) bool {
|
||||
httpClnt := GetConsoleHTTPClient()
|
||||
httpClnt := GetConsoleHTTPClient(endpoint)
|
||||
resp, err := httpClnt.Get(endpoint)
|
||||
if err != nil {
|
||||
ErrorWithContext(ctx, fmt.Errorf("Unable to fetch labels from prometheus (%s)", resp.Status))
|
||||
@@ -975,7 +975,7 @@ func testPrometheusURL(ctx context.Context, url string) bool {
|
||||
ErrorWithContext(ctx, fmt.Errorf("error Building Request: (%v)", err))
|
||||
return false
|
||||
}
|
||||
response, err := GetConsoleHTTPClient().Do(req)
|
||||
response, err := GetConsoleHTTPClient(url).Do(req)
|
||||
if err != nil {
|
||||
ErrorWithContext(ctx, fmt.Errorf("default Prometheus URL not reachable, trying root testing: (%v)", err))
|
||||
newTestURL := req.URL.Scheme + "://" + req.URL.Host + "/-/healthy"
|
||||
@@ -984,7 +984,7 @@ func testPrometheusURL(ctx context.Context, url string) bool {
|
||||
ErrorWithContext(ctx, fmt.Errorf("error Building Root Request: (%v)", err))
|
||||
return false
|
||||
}
|
||||
rootResponse, err := GetConsoleHTTPClient().Do(req2)
|
||||
rootResponse, err := GetConsoleHTTPClient(newTestURL).Do(req2)
|
||||
if err != nil {
|
||||
// URL & Root tests didn't work. Prometheus not reachable
|
||||
ErrorWithContext(ctx, fmt.Errorf("root Prometheus URL not reachable: (%v)", err))
|
||||
|
||||
@@ -91,7 +91,7 @@ func SubnetRegisterWithAPIKey(ctx context.Context, minioClient MinioAdmin, apiKe
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
registerResult, err := subnet.Register(GetConsoleHTTPClient(), serverInfo, apiKey, "", "")
|
||||
registerResult, err := subnet.Register(GetConsoleHTTPClient(""), serverInfo, apiKey, "", "")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -213,7 +213,7 @@ func GetSubnetHTTPClient(ctx context.Context, minioClient MinioAdmin) (*xhttp.Cl
|
||||
}
|
||||
subnetHTTPClient.Transport.(*http.Transport).Proxy = http.ProxyURL(subnetProxyURL)
|
||||
} else {
|
||||
subnetHTTPClient = GetConsoleHTTPClient()
|
||||
subnetHTTPClient = GetConsoleHTTPClient("")
|
||||
}
|
||||
clientI := &xhttp.Client{
|
||||
Client: subnetHTTPClient,
|
||||
@@ -309,7 +309,7 @@ func GetSubnetInfoResponse(session *models.Principal, params subnetApi.SubnetInf
|
||||
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
|
||||
defer cancel()
|
||||
client := &xhttp.Client{
|
||||
Client: GetConsoleHTTPClient(),
|
||||
Client: GetConsoleHTTPClient(""),
|
||||
}
|
||||
|
||||
licenseInfo, err := subnet.ParseLicense(client, os.Getenv("CONSOLE_SUBNET_LICENSE"))
|
||||
|
||||
@@ -21,7 +21,10 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
@@ -479,7 +482,7 @@ func newAdminFromClaims(claims *models.Principal) (*madmin.AdminClient, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
adminClient.SetCustomTransport(GetConsoleHTTPClient().Transport)
|
||||
adminClient.SetCustomTransport(GetConsoleHTTPClient(getMinIOServer()).Transport)
|
||||
return adminClient, nil
|
||||
}
|
||||
|
||||
@@ -498,17 +501,54 @@ func newAdminFromCreds(accessKey, secretKey, endpoint string, tlsEnabled bool) (
|
||||
|
||||
// httpClient is a custom http client, this client should not be called directly and instead be
|
||||
// called using GetConsoleHTTPClient() to ensure is initialized and the certificates are loaded correctly
|
||||
var httpClient *http.Client
|
||||
var httpClients = struct {
|
||||
sync.Mutex
|
||||
m map[string]*http.Client
|
||||
}{
|
||||
m: make(map[string]*http.Client),
|
||||
}
|
||||
|
||||
// GetConsoleHTTPClient will initialize the console HTTP Client with fully populated custom TLS
|
||||
// Transport that with loads certs at
|
||||
// - ${HOME}/.console/certs/CAs
|
||||
// - ${HOME}/.minio/certs/CAs
|
||||
func GetConsoleHTTPClient() *http.Client {
|
||||
if httpClient == nil {
|
||||
httpClient = PrepareConsoleHTTPClient(false)
|
||||
// isLocalAddress returns true if the url contains an IPv4/IPv6 hostname
|
||||
// that points to the local machine - FQDN are not supported
|
||||
func isLocalIPEndpoint(addr string) bool {
|
||||
u, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return httpClient
|
||||
return isLocalIPAddress(u.Hostname())
|
||||
}
|
||||
|
||||
// isLocalAddress returns true if the url contains an IPv4/IPv6 hostname
|
||||
// that points to the local machine - FQDN are not supported
|
||||
func isLocalIPAddress(ipAddr string) bool {
|
||||
if ipAddr == "" {
|
||||
return false
|
||||
}
|
||||
ip := net.ParseIP(ipAddr)
|
||||
return ip != nil && ip.IsLoopback()
|
||||
}
|
||||
|
||||
// GetConsoleHTTPClient caches different http clients depending on the target endpoint while taking
|
||||
// in consideration CA certs stored in ${HOME}/.console/certs/CAs and ${HOME}/.minio/certs/CAs
|
||||
// If the target endpoint points to a loopback device, skip the TLS verification.
|
||||
func GetConsoleHTTPClient(address string) *http.Client {
|
||||
u, err := url.Parse(address)
|
||||
if err == nil {
|
||||
address = u.Hostname()
|
||||
}
|
||||
|
||||
httpClients.Lock()
|
||||
client, ok := httpClients.m[address]
|
||||
httpClients.Unlock()
|
||||
if ok {
|
||||
return client
|
||||
}
|
||||
|
||||
client = PrepareConsoleHTTPClient(isLocalIPAddress(address))
|
||||
httpClients.Lock()
|
||||
httpClients.m[address] = client
|
||||
httpClients.Unlock()
|
||||
return client
|
||||
}
|
||||
|
||||
func (ac AdminClient) speedtest(ctx context.Context, opts madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error) {
|
||||
|
||||
@@ -330,12 +330,14 @@ func (s consoleSTSAssumeRole) IsExpired() bool {
|
||||
}
|
||||
|
||||
func NewConsoleCredentials(accessKey, secretKey, location string) (*credentials.Credentials, error) {
|
||||
minioURL := getMinIOServer()
|
||||
|
||||
// Future authentication methods can be added under this switch statement
|
||||
switch {
|
||||
// LDAP authentication for Console
|
||||
case ldap.GetLDAPEnabled():
|
||||
{
|
||||
creds, err := auth.GetCredentialsFromLDAP(GetConsoleHTTPClient(), getMinIOServer(), accessKey, secretKey)
|
||||
creds, err := auth.GetCredentialsFromLDAP(GetConsoleHTTPClient(minioURL), minioURL, accessKey, secretKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -354,8 +356,8 @@ func NewConsoleCredentials(accessKey, secretKey, location string) (*credentials.
|
||||
DurationSeconds: int(xjwt.GetConsoleSTSDuration().Seconds()),
|
||||
}
|
||||
stsAssumeRole := &credentials.STSAssumeRole{
|
||||
Client: GetConsoleHTTPClient(),
|
||||
STSEndpoint: getMinIOServer(),
|
||||
Client: GetConsoleHTTPClient(minioURL),
|
||||
STSEndpoint: minioURL,
|
||||
Options: opts,
|
||||
}
|
||||
consoleSTSWrapper := consoleSTSAssumeRole{stsAssumeRole: stsAssumeRole}
|
||||
@@ -374,10 +376,12 @@ func getConsoleCredentialsFromSession(claims *models.Principal) *credentials.Cre
|
||||
// from the provided session token
|
||||
func newMinioClient(claims *models.Principal) (*minio.Client, error) {
|
||||
creds := getConsoleCredentialsFromSession(claims)
|
||||
minioClient, err := minio.New(getMinIOEndpoint(), &minio.Options{
|
||||
endpoint := getMinIOEndpoint()
|
||||
secure := getMinIOEndpointIsSecure()
|
||||
minioClient, err := minio.New(endpoint, &minio.Options{
|
||||
Creds: creds,
|
||||
Secure: getMinIOEndpointIsSecure(),
|
||||
Transport: GetConsoleHTTPClient().Transport,
|
||||
Secure: secure,
|
||||
Transport: GetConsoleHTTPClient(getMinIOServer()).Transport,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -414,7 +418,7 @@ func newS3BucketClient(claims *models.Principal, bucketName string, prefix strin
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the provided endpoint is invalid")
|
||||
}
|
||||
s3Config := newS3Config(objectURL, claims.STSAccessKeyID, claims.STSSecretAccessKey, claims.STSSessionToken, false)
|
||||
s3Config := newS3Config(objectURL, claims.STSAccessKeyID, claims.STSSecretAccessKey, claims.STSSessionToken)
|
||||
client, pErr := mc.S3New(s3Config)
|
||||
if pErr != nil {
|
||||
return nil, pErr.Cause
|
||||
@@ -438,7 +442,7 @@ func pathJoinFinalSlash(elem ...string) string {
|
||||
|
||||
// newS3Config simply creates a new Config struct using the passed
|
||||
// parameters.
|
||||
func newS3Config(endpoint, accessKey, secretKey, sessionToken string, insecure bool) *mc.Config {
|
||||
func newS3Config(endpoint, accessKey, secretKey, sessionToken string) *mc.Config {
|
||||
// We have a valid alias and hostConfig. We populate the/
|
||||
// consoleCredentials from the match found in the config file.
|
||||
s3Config := new(mc.Config)
|
||||
@@ -446,13 +450,16 @@ func newS3Config(endpoint, accessKey, secretKey, sessionToken string, insecure b
|
||||
s3Config.AppName = globalAppName
|
||||
s3Config.AppVersion = pkg.Version
|
||||
s3Config.Debug = false
|
||||
s3Config.Insecure = insecure
|
||||
|
||||
s3Config.HostURL = endpoint
|
||||
s3Config.AccessKey = accessKey
|
||||
s3Config.SecretKey = secretKey
|
||||
s3Config.SessionToken = sessionToken
|
||||
s3Config.Signature = "S3v4"
|
||||
|
||||
insecure := isLocalIPEndpoint(endpoint)
|
||||
|
||||
s3Config.Insecure = insecure
|
||||
s3Config.Transport = PrepareSTSClientTransport(insecure)
|
||||
|
||||
return s3Config
|
||||
|
||||
@@ -91,7 +91,7 @@ func getLogSearchResponse(session *models.Principal, params logApi.LogSearchPara
|
||||
}
|
||||
|
||||
func logSearch(endpoint string) (*models.LogSearchResponse, error) {
|
||||
httpClnt := GetConsoleHTTPClient()
|
||||
httpClnt := GetConsoleHTTPClient(endpoint)
|
||||
resp, err := httpClnt.Get(endpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the Log Search API cannot be reached. Please review the URL and try again %v", err)
|
||||
|
||||
@@ -157,7 +157,7 @@ func getLoginDetailsResponse(params authApi.LoginDetailParams, openIDProviders o
|
||||
loginStrategy = models.LoginDetailsLoginStrategyRedirect
|
||||
for name, provider := range openIDProviders {
|
||||
// initialize new oauth2 client
|
||||
oauth2Client, err := openIDProviders.NewOauth2ProviderClient(name, nil, r, GetConsoleHTTPClient())
|
||||
oauth2Client, err := openIDProviders.NewOauth2ProviderClient(name, nil, r, GetConsoleHTTPClient(""))
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err, ErrOauth2Provider)
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func getLoginOauth2AuthResponse(params authApi.LoginOauth2AuthParams, openIDProv
|
||||
lr := params.Body
|
||||
if openIDProviders != nil {
|
||||
// initialize new oauth2 client
|
||||
oauth2Client, err := openIDProviders.NewOauth2ProviderClient(idpName, nil, r, GetConsoleHTTPClient())
|
||||
oauth2Client, err := openIDProviders.NewOauth2ProviderClient(idpName, nil, r, GetConsoleHTTPClient(""))
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user