diff --git a/make/harbor.yml.tmpl b/make/harbor.yml.tmpl index a131068e0..203cd7e21 100644 --- a/make/harbor.yml.tmpl +++ b/make/harbor.yml.tmpl @@ -17,9 +17,13 @@ https: certificate: /your/certificate/path private_key: /your/private/key/path +# # Uncomment following will enable tls communication between all harbor components # internal_tls: +# # set enabled to true means internal tls is enabled # enabled: true +# # verify_client_cert used to decide whether verify client certificate # verify_client_cert: false +# # put your cert and key files on dir # dir: /etc/harbor/tls/internal # Uncomment external_url if you want to enable external proxy diff --git a/make/photon/prepare/templates/jobservice/env.jinja b/make/photon/prepare/templates/jobservice/env.jinja index ace3eb6ea..7fcbb47ff 100644 --- a/make/photon/prepare/templates/jobservice/env.jinja +++ b/make/photon/prepare/templates/jobservice/env.jinja @@ -11,6 +11,9 @@ INTERNAL_TLS_TRUST_CA_PATH=/harbor_cust_cert/harbor_internal_ca.crt INTERNAL_TLS_KEY_PATH=/etc/harbor/ssl/job_service.key INTERNAL_TLS_CERT_PATH=/etc/harbor/ssl/job_service.crt {% endif %} +{% if internal_tls.verify_client_cert %} +INTERNAL_VERIFY_CLIENT_CERT=true +{% endif %} HTTP_PROXY={{jobservice_http_proxy}} HTTPS_PROXY={{jobservice_https_proxy}} diff --git a/make/photon/prepare/templates/registryctl/env.jinja b/make/photon/prepare/templates/registryctl/env.jinja index fbe31db66..2bae9a2b1 100644 --- a/make/photon/prepare/templates/registryctl/env.jinja +++ b/make/photon/prepare/templates/registryctl/env.jinja @@ -6,3 +6,6 @@ INTERNAL_TLS_TRUST_CA_PATH=/harbor_cust_cert/harbor_internal_ca.crt INTERNAL_TLS_KEY_PATH=/etc/harbor/ssl/registryctl.key INTERNAL_TLS_CERT_PATH=/etc/harbor/ssl/registryctl.crt {% endif %} +{% if internal_tls.verify_client_cert %} +INTERNAL_VERIFY_CLIENT_CERT=true +{% endif %} diff --git a/src/chartserver/client.go b/src/chartserver/client.go index 0d6668c49..06558566d 100644 --- a/src/chartserver/client.go +++ b/src/chartserver/client.go @@ -7,6 +7,7 @@ import ( "net/http" "net/url" "strings" + "sync" "time" commonhttp "github.com/goharbor/harbor/src/common/http" @@ -19,6 +20,11 @@ const ( idleConnectionTimeout = 30 * time.Second ) +var ( + once sync.Once + chartTransport *http.Transport +) + // ChartClient is a http client to get the content from the external http server type ChartClient struct { // HTTP client @@ -31,12 +37,15 @@ type ChartClient struct { // NewChartClient is constructor of ChartClient // credential can be nil func NewChartClient(credential *Credential) *ChartClient { // Create http client with customized timeouts - tr := commonhttp.GetHTTPTransport(commonhttp.SecureTransport) - tr.MaxIdleConns = maxIdleConnections - tr.IdleConnTimeout = idleConnectionTimeout + once.Do(func() { + chartTransport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport).Clone() + chartTransport.MaxIdleConns = maxIdleConnections + chartTransport.IdleConnTimeout = idleConnectionTimeout + }) + client := &http.Client{ Timeout: clientTimeout, - Transport: tr, + Transport: chartTransport, } return &ChartClient{ diff --git a/src/common/http/client.go b/src/common/http/client.go index 397415797..a81a000a4 100644 --- a/src/common/http/client.go +++ b/src/common/http/client.go @@ -79,12 +79,12 @@ type Client struct { func GetHTTPTransport(clientType uint) *http.Transport { switch clientType { case SecureTransport: - return secureHTTPTransport.Clone() + return secureHTTPTransport case InsecureTransport: - return insecureHTTPTransport.Clone() + return insecureHTTPTransport default: // default Transport is secure one - return secureHTTPTransport.Clone() + return secureHTTPTransport } } diff --git a/src/common/http/tls.go b/src/common/http/tls.go index 83e3245e8..e2dc578f1 100644 --- a/src/common/http/tls.go +++ b/src/common/http/tls.go @@ -27,10 +27,11 @@ import ( const ( // Internal TLS ENV - internalTLSEnable = "INTERNAL_TLS_ENABLED" - internalTLSKeyPath = "INTERNAL_TLS_KEY_PATH" - internalTLSCertPath = "INTERNAL_TLS_CERT_PATH" - internalTrustCAPath = "INTERNAL_TLS_TRUST_CA_PATH" + internalTLSEnable = "INTERNAL_TLS_ENABLED" + internalVerifyClientCert = "INTERNAL_VERIFY_CLIENT_CERT" + internalTLSKeyPath = "INTERNAL_TLS_KEY_PATH" + internalTLSCertPath = "INTERNAL_TLS_CERT_PATH" + internalTrustCAPath = "INTERNAL_TLS_TRUST_CA_PATH" ) // InternalTLSEnabled returns if internal TLS enabled @@ -42,6 +43,15 @@ func InternalTLSEnabled() bool { return false } +// InternalEnableVerifyClientCert returns if mTLS enabled +func InternalEnableVerifyClientCert() bool { + enabled := os.Getenv(internalVerifyClientCert) + if strings.ToLower(enabled) == "true" { + return true + } + return false +} + // GetInternalCA used to get internal cert file from Env func GetInternalCA(caPool *x509.CertPool) *x509.CertPool { if caPool == nil { diff --git a/src/jobservice/api/server.go b/src/jobservice/api/server.go index eed70370b..2898b9f9c 100644 --- a/src/jobservice/api/server.go +++ b/src/jobservice/api/server.go @@ -73,11 +73,10 @@ func NewServer(ctx context.Context, router Router, cfg ServerConfig) *Server { } // Initialize TLS/SSL config if protocol is https - if cfg.Protocol == config.JobServiceProtocolHTTPS { - logger.Infof("https enabled, load trustCAs") + if cfg.Protocol == config.JobServiceProtocolHTTPS && commonhttp.InternalEnableVerifyClientCert() { + logger.Infof("mTLS enabled ...") srv.TLSConfig = &tls.Config{ ClientAuth: tls.RequireAndVerifyClientCert, - ClientCAs: commonhttp.GetInternalCA(nil), } } diff --git a/src/registryctl/main.go b/src/registryctl/main.go index 2846d1c0e..4f6a3709e 100644 --- a/src/registryctl/main.go +++ b/src/registryctl/main.go @@ -19,6 +19,7 @@ import ( "flag" "net/http" + common_http "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/utils/log" "github.com/goharbor/harbor/src/registryctl/config" "github.com/goharbor/harbor/src/registryctl/handlers" @@ -37,14 +38,13 @@ func (s *RegistryCtl) Start() { Handler: s.Handler, } - if s.ServerConf.Protocol == "https" { - regCtl.TLSConfig = &tls.Config{ - ClientAuth: tls.RequireAndVerifyClientCert, - } - } - var err error if s.ServerConf.Protocol == "https" { + if common_http.InternalEnableVerifyClientCert() { + regCtl.TLSConfig = &tls.Config{ + ClientAuth: tls.RequireAndVerifyClientCert, + } + } err = regCtl.ListenAndServeTLS(s.ServerConf.HTTPSConfig.Cert, s.ServerConf.HTTPSConfig.Key) } else { err = regCtl.ListenAndServe()