2021-04-19 03:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright (c) 2015-2021 MinIO, Inc.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This file is part of MinIO Object Storage stack
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software: you can redistribute it and/or modify
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Affero General Public License as published by
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Affero General Public License for more details.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Affero General Public License
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"bufio" 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-26 14:02:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-24 10:27:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 23:45:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/tls" 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 13:47:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/x509" 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-07 16:18:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/gob" 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 00:53:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/pem" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-19 16:34:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"math/rand" 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-23 23:03:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 01:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-26 04:05:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-23 23:03:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"runtime" 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sort" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 16:38:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"syscall" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 09:09:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/dustin/go-humanize" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fcolor  "github.com/fatih/color" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/go-openapi/loads" 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 05:22:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/inconshreveable/mousetrap" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 05:56:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dns2  "github.com/miekg/dns" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/minio/cli" 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 06:28:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									consoleoauth2  "github.com/minio/console/pkg/auth/idp/oauth2" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									consoleCerts  "github.com/minio/console/pkg/certs" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/console/restapi" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/console/restapi/operations" 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/kes-go" 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-20 08:53:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/madmin-go/v3" 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 13:11:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-15 00:38:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/set" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 05:59:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/auth" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/color" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 05:59:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/config" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/kms" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/logger" 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-05 03:57:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/pkg/v2/certs" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/pkg/v2/console" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/pkg/v2/ellipses" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/pkg/v2/env" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xnet  "github.com/minio/pkg/v2/net" 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 08:52:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// serverDebugLog will enable debug printing
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  serverDebugLog  =  env . Get ( "_MINIO_SERVER_DEBUG" ,  config . EnableOff )  ==  config . EnableOn  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-15 06:28:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  shardDiskTimeDelta  time . Duration  
						 
					
						
							
								
									
										
										
										
											2020-12-18 08:52:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-07 16:18:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  init ( )  {  
						 
					
						
							
								
									
										
										
										
											2021-11-04 05:22:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  runtime . GOOS  ==  "windows"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  mousetrap . StartedByExplorer ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fmt . Printf ( "Don't double-click %s\n" ,  os . Args [ 0 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fmt . Println ( "You need to open cmd.exe/PowerShell and run it from the command line" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fmt . Println ( "Refer to the docs here on how to run it as a Windows Service https://github.com/minio/minio-service/tree/master/windows" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fmt . Println ( "Press the Enter Key to Exit" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fmt . Scanln ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Exit ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-18 04:04:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rand . Seed ( time . Now ( ) . UTC ( ) . UnixNano ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-07 16:18:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									logger . Init ( GOPATH ,  GOROOT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									logger . RegisterError ( config . FmtError ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-14 03:57:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initGlobalContext ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 03:22:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalBatchJobsMetrics  =  batchJobMetrics { metrics :  make ( map [ string ] * batchJobInfo ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  globalBatchJobsMetrics . purgeJobMetrics ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-27 18:59:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t ,  _  :=  minioVersionToReleaseTime ( Version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! t . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalVersionUnix  =  uint64 ( t . Unix ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-19 09:21:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIsCICD  =  env . Get ( "MINIO_CI_CD" ,  "" )  !=  ""  ||  env . Get ( "CI" ,  "" )  !=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									console . SetColor ( "Debug" ,  fcolor . New ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 08:52:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-07 16:18:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									gob . Register ( StorageErr ( "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-06 17:51:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									gob . Register ( madmin . TimeInfo { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-11 06:20:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									gob . Register ( madmin . XFSErrorConfigs { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-06 17:51:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									gob . Register ( map [ string ] interface { } { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 03:47:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-23 03:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									shardDiskTimeDelta ,  err  =  time . ParseDuration ( env . Get ( "_MINIO_SHARD_DISKTIME_DELTA" ,  "1m" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										shardDiskTimeDelta  =  1  *  time . Minute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-16 09:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// All minio-go and madmin-go API operations shall be performed only once,
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-29 13:11:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// another way to look at this is we are turning off retries.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									minio . MaxRetry  =  1 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-16 09:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									madmin . MaxRetry  =  1 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-07 16:18:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  consolePrefix  =  "CONSOLE_"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  minioConfigToConsoleFeatures ( )  {  
						 
					
						
							
								
									
										
										
										
											2023-10-18 23:06:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									os . Setenv ( "CONSOLE_PBKDF_SALT" ,  globalDeploymentID ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									os . Setenv ( "CONSOLE_PBKDF_PASSPHRASE" ,  globalDeploymentID ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 06:01:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalMinioEndpoint  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Setenv ( "CONSOLE_MINIO_SERVER" ,  globalMinioEndpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-22 05:42:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Explicitly set 127.0.0.1 so Console will automatically bypass TLS verification to the local S3 API.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This will save users from providing a certificate with IP or FQDN SAN that points to the local host.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Setenv ( "CONSOLE_MINIO_SERVER" ,  fmt . Sprintf ( "%s://127.0.0.1:%s" ,  getURLScheme ( globalIsTLS ) ,  globalMinioPort ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 05:51:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-15 08:28:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  value  :=  env . Get ( config . EnvMinIOLogQueryURL ,  "" ) ;  value  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										os . Setenv ( "CONSOLE_LOG_QUERY_URL" ,  value ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-15 08:28:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  value  :=  env . Get ( config . EnvMinIOLogQueryAuthToken ,  "" ) ;  value  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 03:04:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											os . Setenv ( "CONSOLE_LOG_QUERY_AUTH_TOKEN" ,  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-18 07:01:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// pass the console subpath configuration
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-14 09:43:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalBrowserRedirectURL  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-26 04:05:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										subPath  :=  path . Clean ( pathJoin ( strings . TrimSpace ( globalBrowserRedirectURL . Path ) ,  SlashSeparator ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  subPath  !=  SlashSeparator  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Setenv ( "CONSOLE_SUBPATH" ,  subPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-18 07:01:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Enable if prometheus URL is set.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-15 08:28:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  value  :=  env . Get ( config . EnvMinIOPrometheusURL ,  "" ) ;  value  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										os . Setenv ( "CONSOLE_PROMETHEUS_URL" ,  value ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-15 08:28:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  value  :=  env . Get ( config . EnvMinIOPrometheusJobID ,  "minio-job" ) ;  value  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 03:04:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											os . Setenv ( "CONSOLE_PROMETHEUS_JOB_ID" ,  value ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-12 04:04:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Support additional labels for more granular filtering.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-15 08:28:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  value  :=  env . Get ( config . EnvMinIOPrometheusExtraLabels ,  "" ) ;  value  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-12 04:04:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												os . Setenv ( "CONSOLE_PROMETHEUS_EXTRA_LABELS" ,  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 03:04:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-15 08:28:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Support Prometheus Auth Token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  value  :=  env . Get ( config . EnvMinIOPrometheusAuthToken ,  "" ) ;  value  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Setenv ( "CONSOLE_PROMETHEUS_AUTH_TOKEN" ,  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Enable if LDAP is enabled.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-25 10:37:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalIAMSys . LDAPConfig . Enabled ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										os . Setenv ( "CONSOLE_LDAP_ENABLED" ,  config . EnableOn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-04 06:32:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Handle animation in welcome page
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  value  :=  env . Get ( config . EnvBrowserLoginAnimation ,  "on" ) ;  value  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Setenv ( "CONSOLE_ANIMATED_LOGIN" ,  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 01:21:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 02:55:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Pass on the session duration environment variable, else we will default to 12 hours
 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-31 01:21:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  valueSts  :=  env . Get ( config . EnvMinioStsDuration ,  "" ) ;  valueSts  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Setenv ( "CONSOLE_STS_DURATION" ,  valueSts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  valueSession  :=  env . Get ( config . EnvBrowserSessionDuration ,  "" ) ;  valueSession  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Setenv ( "CONSOLE_STS_DURATION" ,  valueSession ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-22 02:55:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-04 06:32:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 05:06:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									os . Setenv ( "CONSOLE_MINIO_REGION" ,  globalSite . Region ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 07:08:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									os . Setenv ( "CONSOLE_CERT_PASSWD" ,  env . Get ( "MINIO_CERT_PASSWD" ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-27 15:20:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalSubnetConfig . ApplyEnv ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 06:28:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  buildOpenIDConsoleConfig ( )  consoleoauth2 . OpenIDPCfg  {  
						 
					
						
							
								
									
										
										
										
											2023-02-26 13:01:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pcfgs  :=  globalIAMSys . OpenIDConfig . ProviderCfgs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m  :=  make ( map [ string ] consoleoauth2 . ProviderConfig ,  len ( pcfgs ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  name ,  cfg  :=  range  pcfgs  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 06:28:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										callback  :=  getConsoleEndpoints ( ) [ 0 ]  +  "/oauth_callback" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  cfg . RedirectURI  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											callback  =  cfg . RedirectURI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m [ name ]  =  consoleoauth2 . ProviderConfig { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											URL :                      cfg . URL . String ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DisplayName :              cfg . DisplayName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ClientID :                 cfg . ClientID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ClientSecret :             cfg . ClientSecret , 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-18 23:06:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											HMACSalt :                 globalDeploymentID ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 06:28:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											HMACPassphrase :           cfg . ClientID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Scopes :                   strings . Join ( cfg . DiscoveryDoc . ScopesSupported ,  "," ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Userinfo :                 cfg . ClaimUserinfo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											RedirectCallbackDynamic :  cfg . RedirectURIDynamic , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											RedirectCallback :         callback , 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 08:56:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											EndSessionEndpoint :       cfg . DiscoveryDoc . EndSessionEndpoint , 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-16 03:57:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											RoleArn :                  cfg . GetRoleArn ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-23 06:28:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  m 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  initConsoleServer ( )  ( * restapi . Server ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unset all console_ environment variables.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  cenv  :=  range  env . List ( consolePrefix )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Unsetenv ( cenv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// enable all console environment variables
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									minioConfigToConsoleFeatures ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set certs dir to minio directory
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									consoleCerts . GlobalCertsDir  =  & consoleCerts . ConfigDir { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Path :  globalCertsDir . Get ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									consoleCerts . GlobalCertsCADir  =  & consoleCerts . ConfigDir { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Path :  globalCertsCADir . Get ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-26 00:58:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// set certs before other console initialization
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									restapi . GlobalRootCAs ,  restapi . GlobalPublicCerts ,  restapi . GlobalTLSCertsManager  =  globalRootCAs ,  globalPublicCerts ,  globalTLSCerts 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									swaggerSpec ,  err  :=  loads . Embedded ( restapi . SwaggerJSON ,  restapi . FlatSwaggerJSON ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-29 09:30:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									api  :=  operations . NewConsoleAPI ( swaggerSpec ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-30 14:05:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 00:01:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! serverDebugLog  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Disable console logging if server debug log is not enabled
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										noLog  :=  func ( string ,  ... interface { } )  { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 00:01:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										restapi . LogInfo  =  noLog 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										restapi . LogError  =  noLog 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										api . Logger  =  noLog 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-29 09:30:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Pass in console application config. This needs to happen before the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ConfigureAPI() call.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									restapi . GlobalMinIOConfig  =  restapi . MinIOConfig { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										OpenIDProviders :  buildOpenIDConsoleConfig ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									server  :=  restapi . NewServer ( api ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// register all APIs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									server . ConfigureAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									consolePort ,  _  :=  strconv . Atoi ( globalMinioConsolePort ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									server . Host  =  globalMinioConsoleHost 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									server . Port  =  consolePort 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									restapi . Port  =  globalMinioConsolePort 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									restapi . Hostname  =  globalMinioConsoleHost 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalIsTLS  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If TLS certificates are provided enforce the HTTPS.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										server . EnabledListeners  =  [ ] string { "https" } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										server . TLSPort  =  consolePort 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Need to store tls-port, tls-host un config variables so secure.middleware can read from there
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										restapi . TLSPort  =  globalMinioConsolePort 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										restapi . Hostname  =  globalMinioConsoleHost 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  server ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Check for updates and print a notification message
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  checkUpdate ( mode  string )  {  
						 
					
						
							
								
									
										
										
										
											2020-07-23 23:03:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									updateURL  :=  minioReleaseInfoURL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  runtime . GOOS  ==  globalWindowsOSName  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										updateURL  =  minioReleaseWindowsInfoURL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u ,  err  :=  url . Parse ( updateURL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-16 04:33:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Its OK to ignore any errors during doUpdate() here.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-23 23:03:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									crTime ,  err  :=  GetCurrentReleaseTime ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_ ,  lrTime ,  err  :=  getLatestReleaseTime ( u ,  2 * time . Second ,  mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  older  time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  downloadURL  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  lrTime . After ( crTime )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										older  =  lrTime . Sub ( crTime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										downloadURL  =  getDownloadURL ( releaseTimeToReleaseTag ( lrTime ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									updateMsg  :=  prepareUpdateMessage ( downloadURL ,  older ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  updateMsg  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 05:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									logger . Info ( prepareUpdateMessage ( "Run `mc admin update`" ,  lrTime . Sub ( crTime ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-17 04:04:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newConfigDirFromCtx ( ctx  * cli . Context ,  option  string ,  getDefaultDir  func ( )  string )  ( * ConfigDir ,  bool )  {  
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  dir  string 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-17 04:04:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  dirSet  bool 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ctx . IsSet ( option ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dir  =  ctx . String ( option ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-17 04:04:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dirSet  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ctx . GlobalIsSet ( option ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dir  =  ctx . GlobalString ( option ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-17 04:04:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dirSet  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// cli package does not expose parent's option option.  Below code is workaround.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dir  ==  ""  ||  dir  ==  getDefaultDir ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-17 04:04:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dirSet  =  false  // Unset to false since GlobalIsSet() true is a false positive.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ctx . Parent ( ) . GlobalIsSet ( option )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dir  =  ctx . Parent ( ) . GlobalString ( option ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-17 04:04:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dirSet  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Neither local nor global option is provided.  In this case, try to use
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// default directory.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dir  =  getDefaultDir ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dir  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . FatalIf ( errInvalidArgument ,  "%s option must be provided" ,  option ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  dir  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . FatalIf ( errors . New ( "empty directory" ) ,  "%s directory cannot be empty" ,  option ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Disallow relative paths, figure out absolute paths.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dirAbs ,  err  :=  filepath . Abs ( dir ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									logger . FatalIf ( err ,  "Unable to fetch absolute path for %s=%s" ,  option ,  dir ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									logger . FatalIf ( mkdirAllIgnorePerm ( dirAbs ) ,  "Unable to create directory specified %s=%s" ,  option ,  dir ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-17 04:04:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  & ConfigDir { path :  dirAbs } ,  dirSet 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  handleCommonCmdArgs ( ctx  * cli . Context )  {  
						 
					
						
							
								
									
										
										
										
											2018-12-19 08:08:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Get "json" flag from command line argument and
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-10 21:49:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// enable json and quite modes if json flag is turned on.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 08:08:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalCLIContext . JSON  =  ctx . IsSet ( "json" )  ||  ctx . GlobalIsSet ( "json" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalCLIContext . JSON  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . EnableJSON ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get quiet flag from command line argument.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalCLIContext . Quiet  =  ctx . IsSet ( "quiet" )  ||  ctx . GlobalIsSet ( "quiet" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalCLIContext . Quiet  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . EnableQuiet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get anonymous flag from command line argument.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalCLIContext . Anonymous  =  ctx . IsSet ( "anonymous" )  ||  ctx . GlobalIsSet ( "anonymous" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalCLIContext . Anonymous  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . EnableAnonymous ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Fetch address option
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									addr  :=  ctx . GlobalString ( "address" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  addr  ==  ""  ||  addr  ==  ":" + GlobalMinioDefaultPort  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addr  =  ctx . String ( "address" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 08:08:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Fetch console address option
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									consoleAddr  :=  ctx . GlobalString ( "console-address" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  consoleAddr  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										consoleAddr  =  ctx . String ( "console-address" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  consoleAddr  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p ,  err  :=  xnet . GetFreePort ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 10:10:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . FatalIf ( err ,  "Unable to get free port for Console UI on the host" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										consoleAddr  =  net . JoinHostPort ( "" ,  p . String ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  _ ,  err  :=  net . SplitHostPort ( consoleAddr ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . FatalIf ( err ,  "Unable to start listening on console port" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  consoleAddr  ==  addr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . FatalIf ( errors . New ( "--console-address cannot be same as --address" ) ,  "Unable to start the server" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalMinioHost ,  globalMinioPort  =  mustSplitHostPort ( addr ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-13 10:10:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalMinioPort  ==  "0"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p ,  err  :=  xnet . GetFreePort ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . FatalIf ( err ,  "Unable to get free port for S3 API on the host" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalMinioPort  =  p . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalDynamicAPIPort  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalMinioConsoleHost ,  globalMinioConsolePort  =  mustSplitHostPort ( consoleAddr ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalMinioPort  ==  globalMinioConsolePort  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . FatalIf ( errors . New ( "--console-address port cannot be same as --address port" ) ,  "Unable to start the server" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-21 14:04:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalMinioAddr  =  addr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-13 09:08:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check "no-compat" flag from command line argument.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalCLIContext . StrictS3Compat  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ctx . IsSet ( "no-compat" )  ||  ctx . GlobalIsSet ( "no-compat" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalCLIContext . StrictS3Compat  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set all config, certs and CAs directories.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-17 04:04:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  configSet ,  certsSet  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalConfigDir ,  configSet  =  newConfigDirFromCtx ( ctx ,  "config-dir" ,  defaultConfigDir . Get ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalCertsDir ,  certsSet  =  newConfigDirFromCtx ( ctx ,  "certs-dir" ,  defaultCertsDir . Get ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Remove this code when we deprecate and remove config-dir.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This code is to make sure we inherit from the config-dir
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// option if certs-dir is not provided.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! certsSet  &&  configSet  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalCertsDir  =  & ConfigDir { path :  filepath . Join ( globalConfigDir . Get ( ) ,  certsDir ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalCertsCADir  =  & ConfigDir { path :  filepath . Join ( globalCertsDir . Get ( ) ,  certsCADir ) } 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-01 12:13:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									logger . FatalIf ( mkdirAllIgnorePerm ( globalCertsCADir . Get ( ) ) ,  "Unable to create certs CA directory at %s" ,  globalCertsCADir . Get ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-25 06:13:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check if we have configured a custom DNS cache TTL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dnsTTL  :=  ctx . Duration ( "dns-cache-ttl" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  dnsTTL  <=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dnsTTL  =  10  *  time . Minute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Call to refresh will refresh names in cache.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Baremetal setups set DNS refresh window up to dnsTTL duration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t  :=  time . NewTicker ( dnsTTL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  t . Stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  <- t . C : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												globalDNSCache . Refresh ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  <- GlobalContext . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  envKV  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Key    string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Value  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Skip   bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( e  envKV )  String ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  e . Skip  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  fmt . Sprintf ( "%s=%s" ,  e . Key ,  e . Value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  parsEnvEntry ( envEntry  string )  ( envKV ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-12-26 14:02:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									envEntry  =  strings . TrimSpace ( envEntry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  envEntry  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Skip all empty lines
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  envKV { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Skip :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-22 01:37:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  strings . HasPrefix ( envEntry ,  "#" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Skip commented lines
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  envKV { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Skip :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-05 13:21:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									envTokens  :=  strings . SplitN ( strings . TrimSpace ( strings . TrimPrefix ( envEntry ,  "export" ) ) ,  config . EnvSeparator ,  2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( envTokens )  !=  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  envKV { } ,  fmt . Errorf ( "envEntry malformed; %s, expected to be of form 'KEY=value'" ,  envEntry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 05:13:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									key  :=  envTokens [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									val  :=  envTokens [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Remove quotes from the value if found
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( val )  >=  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										quote  :=  val [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( quote  ==  '"'  ||  quote  ==  '\'' )  &&  val [ len ( val ) - 1 ]  ==  quote  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											val  =  val [ 1  :  len ( val ) - 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  envKV { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-21 05:13:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Key :    key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Value :  val , 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Similar to os.Environ returns a copy of strings representing
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the environment values from a file, in the form "key, value".
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// in a structured form.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  minioEnvironFromFile ( envConfigFile  string )  ( [ ] envKV ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-08-02 04:22:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									f ,  err  :=  Open ( envConfigFile ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  f . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ekvs  [ ] envKV 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									scanner  :=  bufio . NewScanner ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  scanner . Scan ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ekv ,  err  :=  parsEnvEntry ( scanner . Text ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ekv . Skip  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Skips empty lines
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ekvs  =  append ( ekvs ,  ekv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  scanner . Err ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ekvs ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  readFromSecret ( sp  string )  ( string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Supports reading path from docker secrets, filename is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// relative to /run/secrets/ position.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isFile ( pathJoin ( "/run/secrets/" ,  sp ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sp  =  pathJoin ( "/run/secrets/" ,  sp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credBuf ,  err  :=  os . ReadFile ( sp ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  os . IsNotExist ( err )  {  // ignore if file doesn't exist.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  "" ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-26 14:02:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  string ( bytes . TrimSpace ( credBuf ) ) ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  loadEnvVarsFromFiles ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  env . IsSet ( config . EnvAccessKeyFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accessKey ,  err  :=  readFromSecret ( env . Get ( config . EnvAccessKeyFile ,  "" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( config . ErrInvalidCredentials ( err ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Unable to validate credentials inherited from the secret file(s)" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  accessKey  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Setenv ( config . EnvRootUser ,  accessKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  env . IsSet ( config . EnvSecretKeyFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey ,  err  :=  readFromSecret ( env . Get ( config . EnvSecretKeyFile ,  "" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( config . ErrInvalidCredentials ( err ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Unable to validate credentials inherited from the secret file(s)" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  secretKey  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Setenv ( config . EnvRootPassword ,  secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  env . IsSet ( config . EnvRootUserFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rootUser ,  err  :=  readFromSecret ( env . Get ( config . EnvRootUserFile ,  "" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( config . ErrInvalidCredentials ( err ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Unable to validate credentials inherited from the secret file(s)" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rootUser  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Setenv ( config . EnvRootUser ,  rootUser ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  env . IsSet ( config . EnvRootPasswordFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rootPassword ,  err  :=  readFromSecret ( env . Get ( config . EnvRootPasswordFile ,  "" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( config . ErrInvalidCredentials ( err ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Unable to validate credentials inherited from the secret file(s)" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rootPassword  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Setenv ( config . EnvRootPassword ,  rootPassword ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  env . IsSet ( kms . EnvKMSSecretKeyFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kmsSecret ,  err  :=  readFromSecret ( env . Get ( kms . EnvKMSSecretKeyFile ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( err ,  "Unable to read the KMS secret key inherited from secret file" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  kmsSecret  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											os . Setenv ( kms . EnvKMSSecretKey ,  kmsSecret ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  env . IsSet ( config . EnvConfigEnvFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ekvs ,  err  :=  minioEnvironFromFile ( env . Get ( config . EnvConfigEnvFile ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 00:59:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  &&  ! os . IsNotExist ( err )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . Fatal ( err ,  "Unable to read the config environment file" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  ekv  :=  range  ekvs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . Setenv ( ekv . Key ,  ekv . Value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  handleCommonEnvVars ( )  {  
						 
					
						
							
								
									
										
										
										
											2021-05-17 23:45:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-30 10:01:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalBrowserEnabled ,  err  =  config . ParseBool ( env . Get ( config . EnvBrowser ,  config . EnableOn ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . Fatal ( config . ErrInvalidBrowserValue ( err ) ,  "Invalid MINIO_BROWSER value in environment variable" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-10 05:27:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalBrowserEnabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-04 06:32:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  redirectURL  :=  env . Get ( config . EnvBrowserRedirectURL ,  "" ) ;  redirectURL  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-10 05:27:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											u ,  err  :=  xnet . ParseHTTPURL ( redirectURL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 03:38:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . Fatal ( err ,  "Invalid MINIO_BROWSER_REDIRECT_URL value in environment variable" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-10 05:27:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Look for if URL has invalid values and return error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ( ( u . Scheme  ==  "http"  ||  u . Scheme  ==  "https" )  && 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-18 07:01:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												u . Opaque  ==  ""  && 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-10 05:27:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												! u . ForceQuery  &&  u . RawQuery  ==  ""  &&  u . Fragment  ==  "" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 22:24:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												err  :=  fmt . Errorf ( "URL contains unexpected resources, expected URL to be one of http(s)://console.example.com or as a subpath via API endpoint http(s)://minio.example.com/minio format: %v" ,  u ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 03:38:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . Fatal ( err ,  "Invalid MINIO_BROWSER_REDIRECT_URL value is environment variable" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-10 05:27:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											globalBrowserRedirectURL  =  u 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-14 09:43:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalBrowserRedirect  =  env . Get ( config . EnvBrowserRedirect ,  config . EnableOn )  ==  config . EnableOn 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-10 05:27:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-30 10:01:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 06:01:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  serverURL  :=  env . Get ( config . EnvMinIOServerURL ,  "" ) ;  serverURL  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 05:51:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										u ,  err  :=  xnet . ParseHTTPURL ( serverURL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( err ,  "Invalid MINIO_SERVER_URL value in environment variable" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Look for if URL has invalid values and return error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ( ( u . Scheme  ==  "http"  ||  u . Scheme  ==  "https" )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											( u . Path  ==  "/"  ||  u . Path  ==  "" )  &&  u . Opaque  ==  ""  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											! u . ForceQuery  &&  u . RawQuery  ==  ""  &&  u . Fragment  ==  "" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  :=  fmt . Errorf ( "URL contains unexpected resources, expected URL to be of http(s)://minio.example.com format: %v" ,  u ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( err ,  "Invalid MINIO_SERVER_URL value is environment variable" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u . Path  =  ""  // remove any path component such as `/`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalMinioEndpoint  =  u . String ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-08 00:12:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalMinioEndpointURL  =  u 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 05:51:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-13 10:24:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalFSOSync ,  err  =  config . ParseBool ( env . Get ( config . EnvFSOSync ,  config . EnableOff ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . Fatal ( config . ErrInvalidFSOSyncValue ( err ) ,  "Invalid MINIO_FS_OSYNC value in environment variable" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-09-12 03:19:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rootDiskSize  :=  env . Get ( config . EnvRootDriveThresholdSize ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rootDiskSize  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rootDiskSize  =  env . Get ( config . EnvRootDiskThresholdSize ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rootDiskSize  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 09:09:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										size ,  err  :=  humanize . ParseBytes ( rootDiskSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-12 03:19:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . Fatal ( err ,  fmt . Sprintf ( "Invalid %s value in root drive threshold environment variable" ,  rootDiskSize ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 09:09:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalRootDiskThreshold  =  size 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-31 14:39:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									domains  :=  env . Get ( config . EnvDomain ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( domains )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  domainName  :=  range  strings . Split ( domains ,  config . ValueSeparator )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 13:47:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  ok  :=  dns2 . IsDomainName ( domainName ) ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-05 01:35:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . Fatal ( config . ErrInvalidDomainValue ( nil ) . Msg ( "Unknown value `%s`" ,  domainName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-23 11:18:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													"Invalid MINIO_DOMAIN value in environment variable" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											globalDomainNames  =  append ( globalDomainNames ,  domainName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 05:56:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sort . Strings ( globalDomainNames ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lcpSuf  :=  lcpSuffix ( globalDomainNames ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  domainName  :=  range  globalDomainNames  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 05:08:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  domainName  ==  lcpSuf  &&  len ( globalDomainNames )  >  1  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . Fatal ( config . ErrOverlappingDomainValue ( nil ) . Msg ( "Overlapping domains `%s` not allowed" ,  globalDomainNames ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													"Invalid MINIO_DOMAIN value in environment variable" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 05:56:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-16 09:20:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-31 14:39:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									publicIPs  :=  env . Get ( config . EnvPublicIPs ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( publicIPs )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										minioEndpoints  :=  strings . Split ( publicIPs ,  config . ValueSeparator ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										domainIPs  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-23 19:08:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  endpoint  :=  range  minioEndpoints  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  net . ParseIP ( endpoint )  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Checking if the IP is a DNS entry.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-21 05:03:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												addrs ,  err  :=  globalDNSCache . LookupHost ( GlobalContext ,  endpoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-23 19:08:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													logger . FatalIf ( err ,  "Unable to initialize MinIO server with [%s] invalid entry found in MINIO_PUBLIC_IPS" ,  endpoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-23 19:08:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for  _ ,  addr  :=  range  addrs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													domainIPs . Add ( addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-12 03:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-23 19:08:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											domainIPs . Add ( endpoint ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-12 03:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-23 19:08:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										updateDomainIPs ( domainIPs ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-05 09:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Add found interfaces IP address to global domain IPS,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// loopback addresses will be naturally dropped.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:28:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										domainIPs  :=  mustGetLocalIP4 ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  host  :=  range  globalEndpoints . Hostnames ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											domainIPs . Add ( host ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										updateDomainIPs ( domainIPs ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-12 03:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-05 09:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-16 04:33:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// In place update is true by default if the MINIO_UPDATE is not set
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// or is not set to 'off', if MINIO_UPDATE is set to 'off' then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// in-place update is off.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-05 07:32:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalInplaceUpdateDisabled  =  strings . EqualFold ( env . Get ( config . EnvUpdate ,  config . EnableOn ) ,  config . EnableOff ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-02 06:53:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if the supported credential env vars,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// "MINIO_ROOT_USER" and "MINIO_ROOT_PASSWORD" are provided
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Warn user if deprecated environment variables,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// "MINIO_ACCESS_KEY" and "MINIO_SECRET_KEY", are defined
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check all error conditions first
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									//nolint:gocritic
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! env . IsSet ( config . EnvRootUser )  &&  env . IsSet ( config . EnvRootPassword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . Fatal ( config . ErrMissingEnvCredentialRootUser ( nil ) ,  "Unable to start MinIO" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  env . IsSet ( config . EnvRootUser )  &&  ! env . IsSet ( config . EnvRootPassword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . Fatal ( config . ErrMissingEnvCredentialRootPassword ( nil ) ,  "Unable to start MinIO" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ! env . IsSet ( config . EnvRootUser )  &&  ! env . IsSet ( config . EnvRootPassword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! env . IsSet ( config . EnvAccessKey )  &&  env . IsSet ( config . EnvSecretKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( config . ErrMissingEnvCredentialAccessKey ( nil ) ,  "Unable to start MinIO" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  env . IsSet ( config . EnvAccessKey )  &&  ! env . IsSet ( config . EnvSecretKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( config . ErrMissingEnvCredentialSecretKey ( nil ) ,  "Unable to start MinIO" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-30 01:55:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// At this point, either both environment variables
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// are defined or both are not defined.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check both cases and authenticate them if correctly defined
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  user ,  password  string 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  hasCredentials  bool 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									//nolint:gocritic
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  env . IsSet ( config . EnvRootUser )  &&  env . IsSet ( config . EnvRootPassword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										user  =  env . Get ( config . EnvRootUser ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										password  =  env . Get ( config . EnvRootPassword ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hasCredentials  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  env . IsSet ( config . EnvAccessKey )  &&  env . IsSet ( config . EnvSecretKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										user  =  env . Get ( config . EnvAccessKey ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										password  =  env . Get ( config . EnvSecretKey ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hasCredentials  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  hasCredentials  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cred ,  err  :=  auth . CreateCredentials ( user ,  password ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 02:22:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( config . ErrInvalidCredentials ( err ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Unable to validate credentials inherited from the shell environment" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 10:23:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  env . IsSet ( config . EnvAccessKey )  &&  env . IsSet ( config . EnvSecretKey )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											msg  :=  fmt . Sprintf ( "WARNING: %s and %s are deprecated.\n" + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"         Please use %s and %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												config . EnvAccessKey ,  config . EnvSecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												config . EnvRootUser ,  config . EnvRootPassword ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-04 05:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . Info ( color . RedBold ( msg ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-11 13:28:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 02:22:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalActiveCred  =  cred 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 17:05:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalCredViaEnv  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 04:27:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalActiveCred  =  auth . DefaultCredentials 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 02:22:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-19 23:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalDisableFreezeOnBoot  =  env . Get ( "_MINIO_DISABLE_API_FREEZE_ON_BOOT" ,  "" )  ==  "true"  ||  serverDebugLog 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 04:06:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-01-06 02:22:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 04:06:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Initialize KMS global variable after valiadating and loading the configuration.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It depends on KMS env variables and global cli flags.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  handleKMSConfig ( )  {  
						 
					
						
							
								
									
										
										
										
											2023-03-07 00:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  env . IsSet ( kms . EnvKMSSecretKey )  &&  env . IsSet ( kms . EnvKESEndpoint )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . Fatal ( errors . New ( "ambigious KMS configuration" ) ,  fmt . Sprintf ( "The environment contains %q as well as %q" ,  kms . EnvKMSSecretKey ,  kms . EnvKESEndpoint ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 23:45:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-25 10:05:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  env . IsSet ( kms . EnvKMSSecretKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										KMS ,  err  :=  kms . Parse ( env . Get ( kms . EnvKMSSecretKey ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 01:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-26 02:04:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . Fatal ( err ,  "Unable to parse the KMS secret key inherited from the shell environment" ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-18 01:36:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-14 04:06:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										GlobalKMS  =  KMS 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 23:45:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  env . IsSet ( kms . EnvKESEndpoint )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  env . IsSet ( kms . EnvKESAPIKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  env . IsSet ( kms . EnvKESClientKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . Fatal ( errors . New ( "ambigious KMS configuration" ) ,  fmt . Sprintf ( "The environment contains %q as well as %q" ,  kms . EnvKESAPIKey ,  kms . EnvKESClientKey ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  env . IsSet ( kms . EnvKESClientCert )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . Fatal ( errors . New ( "ambigious KMS configuration" ) ,  fmt . Sprintf ( "The environment contains %q as well as %q" ,  kms . EnvKESAPIKey ,  kms . EnvKESClientCert ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-22 01:37:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! env . IsSet ( kms . EnvKESKeyName )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( errors . New ( "Invalid KES configuration" ) ,  fmt . Sprintf ( "The mandatory environment variable %q not set" ,  kms . EnvKESKeyName ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-11 09:15:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  endpoints  [ ] string 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  endpoint  :=  range  strings . Split ( env . Get ( kms . EnvKESEndpoint ,  "" ) ,  "," )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-11 09:15:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  strings . TrimSpace ( endpoint )  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ellipses . HasEllipses ( endpoint )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												endpoints  =  append ( endpoints ,  endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											patterns ,  err  :=  ellipses . FindEllipsesPatterns ( endpoint ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . Fatal ( err ,  fmt . Sprintf ( "Invalid KES endpoint %q" ,  endpoint ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  lbls  :=  range  patterns . Expand ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												endpoints  =  append ( endpoints ,  strings . Join ( lbls ,  "" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rootCAs ,  err  :=  certs . GetRootCAs ( env . Get ( kms . EnvKESServerCA ,  globalCertsCADir . Get ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 00:53:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . Fatal ( err ,  fmt . Sprintf ( "Unable to load X.509 root CAs for KES from %q" ,  env . Get ( kms . EnvKESServerCA ,  globalCertsCADir . Get ( ) ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 00:53:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 07:58:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  kmsConf  kms . Config 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  env . IsSet ( kms . EnvKESAPIKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											key ,  err  :=  kes . ParseAPIKey ( env . Get ( kms . EnvKESAPIKey ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 00:53:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . Fatal ( err ,  fmt . Sprintf ( "Failed to parse KES API key from %q" ,  env . Get ( kms . EnvKESAPIKey ,  "" ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 00:53:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											kmsConf  =  kms . Config { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Endpoints :     endpoints , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Enclave :       env . Get ( kms . EnvKESEnclave ,  "" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DefaultKeyID :  env . Get ( kms . EnvKESKeyName ,  "" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												APIKey :        key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												RootCAs :       rootCAs , 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 07:58:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											loadX509KeyPair  :=  func ( certFile ,  keyFile  string )  ( tls . Certificate ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Manually load the certificate and private key into memory.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We need to check whether the private key is encrypted, and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// if so, decrypt it using the user-provided password.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												certBytes ,  err  :=  os . ReadFile ( certFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  tls . Certificate { } ,  fmt . Errorf ( "Unable to load KES client certificate as specified by the shell environment: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												keyBytes ,  err  :=  os . ReadFile ( keyFile ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 07:58:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  tls . Certificate { } ,  fmt . Errorf ( "Unable to load KES client private key as specified by the shell environment: %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 07:58:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												privateKeyPEM ,  rest  :=  pem . Decode ( bytes . TrimSpace ( keyBytes ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  len ( rest )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  tls . Certificate { } ,  errors . New ( "Unable to load KES client private key as specified by the shell environment: private key contains additional data" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  x509 . IsEncryptedPEMBlock ( privateKeyPEM )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													keyBytes ,  err  =  x509 . DecryptPEMBlock ( privateKeyPEM ,  [ ] byte ( env . Get ( kms . EnvKESClientPassword ,  "" ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														return  tls . Certificate { } ,  fmt . Errorf ( "Unable to decrypt KES client private key as specified by the shell environment: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													keyBytes  =  pem . EncodeToMemory ( & pem . Block { Type :  privateKeyPEM . Type ,  Bytes :  keyBytes } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												certificate ,  err  :=  tls . X509KeyPair ( certBytes ,  keyBytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  tls . Certificate { } ,  fmt . Errorf ( "Unable to load KES client certificate as specified by the shell environment: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  certificate ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 07:58:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reloadCertEvents  :=  make ( chan  tls . Certificate ,  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											certificate ,  err  :=  certs . NewCertificate ( env . Get ( kms . EnvKESClientCert ,  "" ) ,  env . Get ( kms . EnvKESClientKey ,  "" ) ,  loadX509KeyPair ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 07:58:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . Fatal ( err ,  "Failed to load KES client certificate" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											certificate . Watch ( context . Background ( ) ,  15 * time . Minute ,  syscall . SIGHUP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											certificate . Notify ( reloadCertEvents ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											kmsConf  =  kms . Config { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Endpoints :         endpoints , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Enclave :           env . Get ( kms . EnvKESEnclave ,  "" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DefaultKeyID :      env . Get ( kms . EnvKESKeyName ,  "" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Certificate :       certificate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ReloadCertEvents :  reloadCertEvents , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												RootCAs :           rootCAs , 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 07:58:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-11 09:15:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-03 07:58:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 23:19:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										KMS ,  err  :=  kms . NewWithConfig ( kmsConf ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 23:45:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Fatal ( err ,  "Unable to initialize a connection to KES as specified by the shell environment" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 02:22:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-14 02:13:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// We check that the default key ID exists or try to create it otherwise.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This implicitly checks that we can communicate to KES. We don't treat
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// a policy error as failure condition since MinIO may not have the permission
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// to create keys - just to generate/decrypt data encryption keys.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-22 09:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  =  KMS . CreateKey ( context . Background ( ) ,  env . Get ( kms . EnvKESKeyName ,  "" ) ) ;  err  !=  nil  &&  ! errors . Is ( err ,  kes . ErrKeyExists )  &&  ! errors . Is ( err ,  kes . ErrNotAllowed )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-14 02:13:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . Fatal ( err ,  "Unable to initialize a connection to KES as specified by the shell environment" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 23:45:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										GlobalKMS  =  KMS 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 02:22:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:50:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-09-22 16:24:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getTLSConfig ( )  ( x509Certs  [ ] * x509 . Certificate ,  manager  * certs . Manager ,  secureConn  bool ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2019-10-08 13:47:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! ( isFile ( getPublicCertFile ( ) )  &&  isFile ( getPrivateKeyFile ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  x509Certs ,  err  =  config . ParsePublicCertFile ( getPublicCertFile ( ) ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									manager ,  err  =  certs . NewManager ( GlobalContext ,  getPublicCertFile ( ) ,  getPrivateKeyFile ( ) ,  config . LoadX509KeyPair ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 13:47:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// MinIO has support for multiple certificates. It expects the following structure:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  certs/
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   │
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   ├─ public.crt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   ├─ private.key
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   │
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   ├─ example.com/
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   │   │
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   │   ├─ public.crt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   │   └─ private.key
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   └─ foobar.org/
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//      │
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//      ├─ public.crt
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//      └─ private.key
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//   ...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Therefore, we read all filenames in the cert directory and check
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// for each directory whether it contains a public.crt and private.key.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If so, we try to add it to certificate manager.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-02 04:22:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									root ,  err  :=  Open ( globalCertsDir . Get ( ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  root . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									files ,  err  :=  root . Readdir ( - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  file  :=  range  files  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-30 23:21:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Ignore all
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// - regular files
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// - "CAs" directory
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// - any directory which starts with ".."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  file . Mode ( ) . IsRegular ( )  ||  file . Name ( )  ==  "CAs"  ||  strings . HasPrefix ( file . Name ( ) ,  ".." )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-30 23:21:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  file . Mode ( ) & os . ModeSymlink  ==  os . ModeSymlink  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-02 04:22:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											file ,  err  =  Stat ( filepath . Join ( root . Name ( ) ,  file . Name ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-30 23:21:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// not accessible ignore
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! file . IsDir ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											certFile  =  filepath . Join ( root . Name ( ) ,  file . Name ( ) ,  publicCertFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											keyFile   =  filepath . Join ( root . Name ( ) ,  file . Name ( ) ,  privateKeyFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! isFile ( certFile )  ||  ! isFile ( keyFile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-30 23:21:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  =  manager . AddCertificate ( certFile ,  keyFile ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "Unable to load TLS certificate '%s,%s': %w" ,  certFile ,  keyFile ,  err ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											logger . LogIf ( GlobalContext ,  err ,  logger . Minio ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 13:47:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									secureConn  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 16:38:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-05 12:34:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Certs might be symlinks, reload them every 10 seconds.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									manager . UpdateReloadDuration ( 10  *  time . Second ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-01 16:38:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// syscall.SIGHUP to reload the certs.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									manager . ReloadOnSignal ( syscall . SIGHUP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												certs: refactor cert manager to support multiple certificates (#10207)
This commit refactors the certificate management implementation
in the `certs` package such that multiple certificates can be
specified at the same time. Therefore, the following layout of
the `certs/` directory is expected:
```
certs/
 │
 ├─ public.crt
 ├─ private.key
 ├─ CAs/          // CAs directory is ignored
 │   │
 │    ...
 │
 ├─ example.com/
 │   │
 │   ├─ public.crt
 │   └─ private.key
 └─ foobar.org/
     │
     ├─ public.crt
     └─ private.key
   ...
```
However, directory names like `example.com` are just for human
readability/organization and don't have any meaning w.r.t whether
a particular certificate is served or not. This decision is made based
on the SNI sent by the client and the SAN of the certificate.
***
The `Manager` will pick a certificate based on the client trying
to establish a TLS connection. In particular, it looks at the client
hello (i.e. SNI) to determine which host the client tries to access.
If the manager can find a certificate that matches the SNI it
returns this certificate to the client.
However, the client may choose to not send an SNI or tries to access
a server directly via IP (`https://<ip>:<port>`). In this case, we
cannot use the SNI to determine which certificate to serve. However,
we also should not pick "the first" certificate that would be accepted
by the client (based on crypto. parameters - like a signature algorithm)
because it may be an internal certificate that contains internal hostnames. 
We would disclose internal infrastructure details doing so.
Therefore, the `Manager` returns the "default" certificate when the
client does not specify an SNI. The default certificate the top-level
`public.crt` - i.e. `certs/public.crt`.
This approach has some consequences:
 - It's the operator's responsibility to ensure that the top-level
   `public.crt` does not disclose any information (i.e. hostnames)
   that are not publicly visible. However, this was the case in the
   past already.
 - Any other `public.crt` - except for the top-level one - must not
   contain any IP SAN. The reason for this restriction is that the
   Manager cannot match a SNI to an IP b/c the SNI is the server host
   name. The entire purpose of SNI is to indicate which host the client
   tries to connect to when multiple hosts run on the same IP. So, a
   client will not set the SNI to an IP.
   If we would allow IP SANs in a lower-level `public.crt` a user would
   expect that it is possible to connect to MinIO directly via IP address
   and that the MinIO server would pick "the right" certificate. However,
   the MinIO server cannot determine which certificate to serve, and
   therefore always picks the "default" one. This may lead to all sorts
   of confusing errors like:
   "It works if I use `https:instance.minio.local` but not when I use
   `https://10.0.2.1`.
These consequences/limitations should be pointed out / explained in our
docs in an appropriate way. However, the support for multiple
certificates should not have any impact on how deployment with a single
certificate function today.
Co-authored-by: Harshavardhana <harsha@minio.io>
											 
										 
										
											2020-09-04 14:33:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  x509Certs ,  manager ,  secureConn ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-08 13:47:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-03-27 02:18:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// contextCanceled returns whether a context is canceled.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  contextCanceled ( ctx  context . Context )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-01-07 02:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// bgContext returns a context that can be used for async operations.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Cancellation/timeouts are removed, so parent cancellations/timeout will
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// not propagate from parent.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Context values are preserved.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This can be used for goroutines that live beyond the parent context.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  bgContext ( parent  context . Context )  context . Context  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  bgCtx { parent :  parent } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  bgCtx  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parent  context . Context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( a  bgCtx )  Done ( )  <- chan  struct { }  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( a  bgCtx )  Err ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( a  bgCtx )  Deadline ( )  ( deadline  time . Time ,  ok  bool )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  time . Time { } ,  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( a  bgCtx )  Value ( key  interface { } )  interface { }  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  a . parent . Value ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}