Use user CAs in checkEndpoint() call (#8911)

The server info handler makes a http connection to other
nodes to check if they are up but does not load the custom
CAs in ~/.minio/certs/CAs.

This commit fix it.

Co-authored-by: Harshavardhana <harsha@minio.io>
This commit is contained in:
Anis Elleuch 2020-02-02 02:45:29 +01:00 committed by GitHub
parent d76160c245
commit 7432b5c9b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 55 deletions

View file

@ -19,6 +19,7 @@ package cmd
import (
"context"
"crypto/subtle"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
@ -1519,7 +1520,7 @@ func fetchVaultStatus(cfg config.Config) madmin.Vault {
return vault
}
if err := checkConnection(kmsInfo.Endpoint); err != nil {
if err := checkConnection(kmsInfo.Endpoint, 15*time.Second); err != nil {
vault.Status = "offline"
} else {
@ -1563,7 +1564,7 @@ func fetchLoggerInfo(cfg config.Config) ([]madmin.Logger, []madmin.Audit) {
var auditlogger []madmin.Audit
for log, l := range loggerCfg.HTTP {
if l.Enabled {
err := checkConnection(l.Endpoint)
err := checkConnection(l.Endpoint, 15*time.Second)
if err == nil {
mapLog := make(map[string]madmin.Status)
mapLog[log] = madmin.Status{Status: "Online"}
@ -1578,7 +1579,7 @@ func fetchLoggerInfo(cfg config.Config) ([]madmin.Logger, []madmin.Audit) {
for audit, l := range loggerCfg.Audit {
if l.Enabled {
err := checkConnection(l.Endpoint)
err := checkConnection(l.Endpoint, 15*time.Second)
if err == nil {
mapAudit := make(map[string]madmin.Status)
mapAudit[audit] = madmin.Status{Status: "Online"}
@ -1594,12 +1595,19 @@ func fetchLoggerInfo(cfg config.Config) ([]madmin.Logger, []madmin.Audit) {
}
// checkConnection - ping an endpoint , return err in case of no connection
func checkConnection(endpointStr string) error {
func checkConnection(endpointStr string, timeout time.Duration) error {
u, pErr := xnet.ParseURL(endpointStr)
if pErr != nil {
return pErr
}
if dErr := u.DialHTTP(); dErr != nil {
tr := newCustomHTTPTransport(
&tls.Config{RootCAs: globalRootCAs},
timeout,
0, /* Default value */
)()
if dErr := u.DialHTTP(tr); dErr != nil {
if urlErr, ok := dErr.(*url.Error); ok {
// To treat "connection refused" errors as un reachable endpoint.
if target.IsConnRefusedErr(urlErr.Err) {

View file

@ -20,7 +20,6 @@ import (
"net"
"net/http"
"os"
"strings"
"github.com/minio/minio-go/v6/pkg/set"
"github.com/minio/minio/pkg/cpu"
@ -190,51 +189,49 @@ func getLocalNetworkInfo(endpointZones EndpointZones, r *http.Request) madmin.Se
// getLocalServerProperty - returns ServerDrivesPerfInfo for only the
// local endpoints from given list of endpoints
func getLocalServerProperty(endpointZones EndpointZones, r *http.Request) madmin.ServerProperties {
var di madmin.Disk
var disks []madmin.Disk
addr := r.Host
if globalIsDistXL {
addr = GetLocalPeer(endpointZones)
}
network := make(map[string]string)
hosts := set.NewStringSet()
for _, ep := range endpointZones {
for _, endpoint := range ep.Endpoints {
url := strings.Replace(endpoint.URL.String(), endpoint.Path, "", -1)
if url == "" {
url = r.Host
nodeName := endpoint.Host
if nodeName == "" {
nodeName = r.Host
}
hosts.Add(url)
// Only proceed for local endpoints
if endpoint.IsLocal {
url = fetchAddress(url)
network[url] = "online"
if _, err := os.Stat(endpoint.Path); err != nil {
continue
// Only proceed for local endpoints
network[nodeName] = "online"
var di = madmin.Disk{
DrivePath: endpoint.Path,
}
diInfo, err := disk.GetInfo(endpoint.Path)
if err != nil {
if os.IsNotExist(err) || isSysErrPathNotFound(err) {
di.State = madmin.DriveStateMissing
} else {
di.State = madmin.DriveStateCorrupt
}
} else {
di.State = madmin.DriveStateOk
di.DrivePath = endpoint.Path
di.TotalSpace = diInfo.Total
di.UsedSpace = diInfo.Total - diInfo.Free
di.Utilization = float64((diInfo.Total - diInfo.Free) / diInfo.Total * 100)
}
diInfo, _ := disk.GetInfo(endpoint.Path)
di.State = "ok"
di.DrivePath = endpoint.Path
di.TotalSpace = diInfo.Total
di.UsedSpace = diInfo.Total - diInfo.Free
di.Utilization = float64((diInfo.Total - diInfo.Free) / diInfo.Total * 100)
disks = append(disks, di)
}
}
}
for host := range hosts {
_, present := network[host]
if !present {
err := checkConnection(host)
host = fetchAddress(host)
if err != nil {
network[host] = "offline"
} else {
network[host] = "online"
_, present := network[nodeName]
if !present {
err := IsServerResolvable(endpoint)
if err == nil {
network[nodeName] = "online"
} else {
network[nodeName] = "offline"
}
}
}
}
}
@ -249,13 +246,3 @@ func getLocalServerProperty(endpointZones EndpointZones, r *http.Request) madmin
Disks: disks,
}
}
// Replaces http and https from address
func fetchAddress(address string) string {
if strings.Contains(address, "http://") {
address = strings.Replace(address, "http://", "", -1)
} else if strings.Contains(address, "https://") {
address = strings.Replace(address, "https://", "", -1)
}
return address
}

View file

@ -95,7 +95,7 @@ func (target *ElasticsearchTarget) ID() event.TargetID {
// IsActive - Return true if target is up and active
func (target *ElasticsearchTarget) IsActive() (bool, error) {
if dErr := target.args.URL.DialHTTP(); dErr != nil {
if dErr := target.args.URL.DialHTTP(nil); dErr != nil {
if xnet.IsNetworkOrHostDown(dErr) {
return false, errNotConnected
}
@ -260,7 +260,7 @@ func NewElasticsearchTarget(id string, args ElasticsearchArgs, doneCh <-chan str
}
}
dErr := args.URL.DialHTTP()
dErr := args.URL.DialHTTP(nil)
if dErr != nil {
if store == nil {
return nil, dErr

View file

@ -95,7 +95,7 @@ func (target *WebhookTarget) IsActive() (bool, error) {
if pErr != nil {
return false, pErr
}
if dErr := u.DialHTTP(); dErr != nil {
if dErr := u.DialHTTP(nil); dErr != nil {
if xnet.IsNetworkOrHostDown(dErr) {
return false, errNotConnected
}

View file

@ -86,14 +86,20 @@ func (u *URL) UnmarshalJSON(data []byte) (err error) {
}
// DialHTTP - dials the url to check the connection.
func (u URL) DialHTTP() error {
var client = &http.Client{
Transport: &http.Transport{
func (u URL) DialHTTP(transport *http.Transport) error {
if transport == nil {
transport = &http.Transport{
DialContext: (&net.Dialer{
Timeout: 2 * time.Second,
}).DialContext,
},
}
}
var client = &http.Client{
Transport: transport,
}
req, err := http.NewRequest("POST", u.String(), nil)
if err != nil {
return err