Skip to content

Commit 5181e1b

Browse files
committed
Connect MCS with Minio insecure TLS/Custom CAs
This PR adds support to connecting MCS to minio instances running TLS with self-signed certificates or certificates signed by custom Certificate Authorities ``` export MCS_MINIO_SERVER_TLS_SKIP_VERIFICATION=on export MCS_MINIO_SERVER_TLS_ROOT_CAS=file1,file2,file3 ```
1 parent 63f4150 commit 5181e1b

File tree

10 files changed

+237
-34
lines changed

10 files changed

+237
-34
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ export MCS_MINIO_SERVER=http://localhost:9000
6868
./mcs server
6969
```
7070

71+
## Connect MCS to a Minio using TLS and a self-signed certificate
72+
73+
```
74+
...
75+
export MCS_MINIO_SERVER_TLS_SKIP_VERIFICATION=on
76+
export MCS_MINIO_SERVER=https://localhost:9000
77+
./mcs server
78+
```
79+
7180
You can verify that the apis work by doing the request on `localhost:9090/api/v1/...`
7281

7382
# Contribute to mcs Project

go.sum

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ github.com/Azure/azure-storage-blob-go v0.8.0 h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFE
1212
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
1313
github.com/Azure/go-autorest v11.7.1+incompatible h1:M2YZIajBBVekV86x0rr1443Lc1F/Ylxb9w+5EtSyX3Q=
1414
github.com/Azure/go-autorest v11.7.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
15+
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
1516
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
1617
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
1718
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@@ -239,6 +240,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
239240
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
240241
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
241242
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
243+
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
242244
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
243245
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
244246
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -404,10 +406,17 @@ github.com/minio/mc v0.0.0-20200415193718-68b638f2f96c/go.mod h1:l9PuOY62zT7AQJq
404406
github.com/minio/minio v0.0.0-20200415191640-bde0f444dbab/go.mod h1:v8oQPMMaTkjDwp5cOz1WCElA4Ik+X+0y4On+VMk0fis=
405407
github.com/minio/minio v0.0.0-20200501193630-d1c8e9f31ba0 h1:QxIz36O01LbKqJiz6HKeKCOC2afgydspkpahQ807msY=
406408
github.com/minio/minio v0.0.0-20200501193630-d1c8e9f31ba0/go.mod h1:Vhlqz7Se0EgpgFiVxpvzF4Zz/h2LMx+EPKH96Aera5U=
409+
github.com/minio/minio v0.0.0-20200506212505-4c9de098b0fb h1:okO1FO5iR5G9ZX8vElpeAgdqYue98UzQ3HQ5X5/pB2g=
410+
github.com/minio/minio v0.0.0-20200506212505-4c9de098b0fb/go.mod h1:+HURmfnikX5JaBIms97fh5J5eMrAUOOoy6jjz33twdI=
411+
github.com/minio/minio v0.0.0-20200508020030-9dda1fd62419 h1:dXluK/W8elgtD2uxQPcxj18DG5oPJcwyAXv+kf680JQ=
412+
github.com/minio/minio v0.0.0-20200508020030-9dda1fd62419/go.mod h1:2JUAKRSQZ/2jZhDCyj0N7i0HeJOLLGRyxUvE4v0jlrs=
413+
github.com/minio/minio v0.0.0-20200508024915-5bf3eeaa7722 h1:8hFsVyynRF2huocXqHlnElnVgMXmW5LwQBnn0YcLrpM=
407414
github.com/minio/minio-go/v6 v6.0.53 h1:8jzpwiOzZ5Iz7/goFWqNZRICbyWYShbb5rARjrnSCNI=
408415
github.com/minio/minio-go/v6 v6.0.53/go.mod h1:DIvC/IApeHX8q1BAMVCXSXwpmrmM+I+iBvhvztQorfI=
409416
github.com/minio/minio-go/v6 v6.0.55-0.20200424204115-7506d2996b22 h1:nZEve4vdUhwHBoV18zRvPDgjL6NYyDJE5QJvz3l9bRs=
410417
github.com/minio/minio-go/v6 v6.0.55-0.20200424204115-7506d2996b22/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI=
418+
github.com/minio/minio-go/v6 v6.0.55-0.20200425081427-89eebdef2af0 h1:PdHKpM9h2vqCDr1AjJdK8e/6tRdOSjUNzIqeNmxu7ak=
419+
github.com/minio/minio-go/v6 v6.0.55-0.20200425081427-89eebdef2af0/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI=
411420
github.com/minio/parquet-go v0.0.0-20200414234858-838cfa8aae61 h1:pUSI/WKPdd77gcuoJkSzhJ4wdS8OMDOsOu99MtpXEQA=
412421
github.com/minio/parquet-go v0.0.0-20200414234858-838cfa8aae61/go.mod h1:4trzEJ7N1nBTd5Tt7OCZT5SEin+WiAXpdJ/WgPkESA8=
413422
github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
@@ -607,11 +616,19 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
607616
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
608617
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
609618
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
619+
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
620+
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
610621
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
611622
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
623+
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
624+
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
625+
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
626+
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
612627
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
613628
go.uber.org/zap v1.11.0 h1:gSmpCfs+R47a4yQPAI4xJ0IPDLTRGXskm6UelqNXpqE=
614629
go.uber.org/zap v1.11.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
630+
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
631+
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
615632
golang.org/x/arch v0.0.0-20190909030613-46d78d1859ac/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
616633
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
617634
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -620,6 +637,7 @@ golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACk
620637
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
621638
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
622639
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
640+
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
623641
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
624642
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
625643
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -635,6 +653,9 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk
635653
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
636654
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
637655
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
656+
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
657+
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
658+
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
638659
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
639660
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
640661
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -715,8 +736,11 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
715736
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
716737
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
717738
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
739+
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
718740
golang.org/x/tools v0.0.0-20190914235951-31e00f45c22e h1:nOOVVcLC+/3MeovP40q5lCiWmP1Z1DaN8yn8ngU63hw=
719741
golang.org/x/tools v0.0.0-20190914235951-31e00f45c22e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
742+
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
743+
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
720744
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
721745
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32 h1:Xvf3ZQTm5bjXPxhI7g+dwqsCqadK1rcNtwtszuatetk=
722746
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -786,4 +810,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
786810
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
787811
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
788812
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
813+
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
814+
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
789815
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

restapi/client-admin.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func NewAdminClient(url, accessKey, secretKey string) (*madmin.AdminClient, *pro
4444
AppName: appName,
4545
AppVersion: McsVersion,
4646
AppComments: []string{appName, runtime.GOOS, runtime.GOARCH},
47+
Insecure: getMinIOServerTLSSkipVerification(),
4748
})
4849
if err != nil {
4950
return nil, err.Trace(url)
@@ -240,13 +241,15 @@ func newMAdminClient(jwt string) (*madmin.AdminClient, error) {
240241

241242
// newAdminFromClaims creates a minio admin from Decrypted claims using Assume role credentials
242243
func newAdminFromClaims(claims *auth.DecryptedClaims) (*madmin.AdminClient, error) {
244+
tlsEnabled := getMinIOEndpointIsSecure()
243245
adminClient, err := madmin.NewWithOptions(getMinIOEndpoint(), &madmin.Options{
244246
Creds: credentials.NewStaticV4(claims.AccessKeyID, claims.SecretAccessKey, claims.SessionToken),
245-
Secure: getMinIOEndpointIsSecure(),
247+
Secure: tlsEnabled,
246248
})
247249
if err != nil {
248250
return nil, err
249251
}
252+
adminClient.SetCustomTransport(STSClient.Transport)
250253
return adminClient, nil
251254
}
252255

restapi/client.go

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package restapi
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223

2324
mc "github.com/minio/mc/cmd"
@@ -133,13 +134,46 @@ func (c mcsCredentials) Expire() {
133134
c.minioCredentials.Expire()
134135
}
135136

137+
// mcsSTSAssumeRole it's a STSAssumeRole wrapper, in general
138+
// there's no need to use this struct anywhere else in the project, it's only required
139+
// for passing a custom *http.Client to *credentials.STSAssumeRole
140+
type mcsSTSAssumeRole struct {
141+
stsAssumeRole *credentials.STSAssumeRole
142+
}
143+
144+
func (s mcsSTSAssumeRole) Retrieve() (credentials.Value, error) {
145+
return s.stsAssumeRole.Retrieve()
146+
}
147+
148+
func (s mcsSTSAssumeRole) IsExpired() bool {
149+
return s.stsAssumeRole.IsExpired()
150+
}
151+
152+
// HTTP Client contains configured need it by STSAssumeRole
153+
// PrepareSTSClient will be executed only once
154+
var STSClient = PrepareSTSClient()
155+
136156
func newMcsCredentials(accessKey, secretKey, location string) (*credentials.Credentials, error) {
137-
return credentials.NewSTSAssumeRole(getMinIOServer(), credentials.STSAssumeRoleOptions{
157+
stsEndpoint := getMinIOServer()
158+
if stsEndpoint == "" {
159+
return nil, errors.New("STS endpoint cannot be empty")
160+
}
161+
if accessKey == "" || secretKey == "" {
162+
return nil, errors.New("AssumeRole credentials access/secretkey is mandatory")
163+
}
164+
opts := credentials.STSAssumeRoleOptions{
138165
AccessKey: accessKey,
139166
SecretKey: secretKey,
140167
Location: location,
141168
DurationSeconds: xjwt.GetMcsSTSAndJWTDurationInSeconds(),
142-
})
169+
}
170+
stsAssumeRole := &credentials.STSAssumeRole{
171+
Client: STSClient,
172+
STSEndpoint: stsEndpoint,
173+
Options: opts,
174+
}
175+
mcsSTSWrapper := mcsSTSAssumeRole{stsAssumeRole: stsAssumeRole}
176+
return credentials.New(mcsSTSWrapper), nil
143177
}
144178

145179
// getMcsCredentialsFromJWT returns the *minioCredentials.Credentials associated to the
@@ -160,14 +194,15 @@ func newMinioClient(jwt string) (*minio.Client, error) {
160194
if err != nil {
161195
return nil, err
162196
}
163-
adminClient, err := minio.NewWithOptions(getMinIOEndpoint(), &minio.Options{
197+
minioClient, err := minio.NewWithOptions(getMinIOEndpoint(), &minio.Options{
164198
Creds: creds,
165199
Secure: getMinIOEndpointIsSecure(),
166200
})
167201
if err != nil {
168202
return nil, err
169203
}
170-
return adminClient, nil
204+
minioClient.SetCustomTransport(STSClient.Transport)
205+
return minioClient, nil
171206
}
172207

173208
// newS3BucketClient creates a new mc S3Client to talk to the server based on a bucket

restapi/config.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ func getMinIOServer() string {
5151
return env.Get(McsMinIOServer, "http://localhost:9000")
5252
}
5353

54+
// If MCS_MINIO_SERVER_TLS_SKIP_VERIFICATION is true mcs will skip the verification on the
55+
// TLS connection, this is useful for testing or when working with self-signed certificates
56+
func getMinIOServerTLSSkipVerification() bool {
57+
return strings.ToLower(env.Get(McsMinIOServerTLSSkipVerification, "off")) == "on"
58+
}
59+
60+
func getMinioServerTLSRootCAs() []string {
61+
caCertFileNames := env.Get(McsMinIOServerTLSRootCAs, "")
62+
if caCertFileNames == "" {
63+
return []string{}
64+
}
65+
return strings.Split(caCertFileNames, ",")
66+
}
67+
5468
func getMinIOEndpoint() string {
5569
server := getMinIOServer()
5670
if strings.Contains(server, "://") {
@@ -67,7 +81,7 @@ func getMinIOEndpointIsSecure() bool {
6781
if strings.Contains(server, "://") {
6882
parts := strings.Split(server, "://")
6983
if len(parts) > 1 {
70-
if parts[1] == "https" {
84+
if parts[0] == "https" {
7185
return true
7286
}
7387
}

restapi/consts.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ package restapi
1818

1919
const (
2020
// consts for common configuration
21-
McsVersion = `0.1.0`
22-
McsAccessKey = "MCS_ACCESS_KEY"
23-
McsSecretKey = "MCS_SECRET_KEY"
24-
McsMinIOServer = "MCS_MINIO_SERVER"
25-
McsProductionMode = "MCS_PRODUCTION_MODE"
26-
McsHostname = "MCS_HOSTNAME"
27-
McsPort = "MCS_PORT"
28-
McsTLSHostname = "MCS_TLS_HOSTNAME"
29-
McsTLSPort = "MCS_TLS_PORT"
21+
McsVersion = `0.1.0`
22+
McsAccessKey = "MCS_ACCESS_KEY"
23+
McsSecretKey = "MCS_SECRET_KEY"
24+
McsMinIOServer = "MCS_MINIO_SERVER"
25+
McsMinIOServerTLSSkipVerification = "MCS_MINIO_SERVER_TLS_SKIP_VERIFICATION"
26+
McsMinIOServerTLSRootCAs = "MCS_MINIO_SERVER_TLS_ROOT_CAS"
27+
McsProductionMode = "MCS_PRODUCTION_MODE"
28+
McsHostname = "MCS_HOSTNAME"
29+
McsPort = "MCS_PORT"
30+
McsTLSHostname = "MCS_TLS_HOSTNAME"
31+
McsTLSPort = "MCS_TLS_PORT"
3032

3133
// consts for Secure middleware
3234
McsSecureAllowedHosts = "MCS_SECURE_ALLOWED_HOSTS"

restapi/tls.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// This file is part of MinIO Orchestrator
2+
// Copyright (c) 2020 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package restapi
18+
19+
import (
20+
"crypto/tls"
21+
"crypto/x509"
22+
"errors"
23+
"fmt"
24+
"io/ioutil"
25+
"net"
26+
"net/http"
27+
"time"
28+
)
29+
30+
var (
31+
certDontExists = "File certificate doesn't exists: %s"
32+
)
33+
34+
func prepareSTSClientTransport() *http.Transport {
35+
// This takes github.com/minio/minio/pkg/madmin/transport.go as an example
36+
//
37+
// DefaultTransport - this default transport is similar to
38+
// http.DefaultTransport but with additional param DisableCompression
39+
// is set to true to avoid decompressing content with 'gzip' encoding.
40+
DefaultTransport := &http.Transport{
41+
Proxy: http.ProxyFromEnvironment,
42+
DialContext: (&net.Dialer{
43+
Timeout: 5 * time.Second,
44+
KeepAlive: 15 * time.Second,
45+
}).DialContext,
46+
MaxIdleConns: 1024,
47+
MaxIdleConnsPerHost: 1024,
48+
ResponseHeaderTimeout: 60 * time.Second,
49+
IdleConnTimeout: 60 * time.Second,
50+
TLSHandshakeTimeout: 10 * time.Second,
51+
ExpectContinueTimeout: 1 * time.Second,
52+
DisableCompression: true,
53+
}
54+
// If Minio instance is running with TLS enabled and it's using a self-signed certificate
55+
// or a certificate issued by a custom certificate authority we prepare a new custom *http.Transport
56+
if getMinIOEndpointIsSecure() {
57+
caCertFileNames := getMinioServerTLSRootCAs()
58+
tlsConfig := &tls.Config{
59+
InsecureSkipVerify: getMinIOServerTLSSkipVerification(),
60+
// Can't use SSLv3 because of POODLE and BEAST
61+
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
62+
// Can't use TLSv1.1 because of RC4 cipher usage
63+
MinVersion: tls.VersionTLS12,
64+
}
65+
// If root CAs are configured we save them to the http.Client RootCAs store
66+
if len(caCertFileNames) > 0 {
67+
certs := x509.NewCertPool()
68+
for _, caCert := range caCertFileNames {
69+
// Validate certificate exists
70+
if FileExists(caCert) {
71+
pemData, err := ioutil.ReadFile(caCert)
72+
if err != nil {
73+
// if there was an error reading pem file stop mcs
74+
panic(err)
75+
}
76+
certs.AppendCertsFromPEM(pemData)
77+
} else {
78+
// if provided cert filename doesn't exists stop mcs
79+
panic(errors.New(fmt.Sprintf(certDontExists, caCert)))
80+
}
81+
}
82+
tlsConfig.RootCAs = certs
83+
}
84+
DefaultTransport.TLSClientConfig = tlsConfig
85+
}
86+
return DefaultTransport
87+
}
88+
89+
// PrepareSTSClient returns an http.Client with custom configurations need it by *credentials.STSAssumeRole
90+
// custom configurations include skipVerification flag, and root CA certificates
91+
func PrepareSTSClient() *http.Client {
92+
transport := prepareSTSClientTransport()
93+
// Return http client with default configuration
94+
return &http.Client{
95+
Transport: transport,
96+
}
97+
}

0 commit comments

Comments
 (0)