Skip to content

Commit

Permalink
pkg/server, cmd/linksharing: support specifying uplink client identities
Browse files Browse the repository at this point in the history
this change allows the gateway and linksharing processes to specify
stable uplink client identities. this is important so that different
gateway regions can get different choice-of-two load balancing profiles,
and other benefits of satellite-trusted uplinks.

we intend that all gateways and linksharing services within a single
region use the same identity.

note that the linksharing process already has an identity called the
TierServiceIdentity, where it asks the Satellite for tier services using
that identity. If that identity is also different between regions and
the same within a region, it is fine to reuse that identity for this
as part of the configuration.

a future patch set could simplify the configuration so only one is
necessary to configure

Change-Id: If2942af0907126d1c91578d61af6cad43c13c69b
  • Loading branch information
jtolio committed May 31, 2024
1 parent 5758fd9 commit 5a3ea0f
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 9 deletions.
6 changes: 6 additions & 0 deletions cmd/gateway-mt/config.yaml.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ cert-magic.staging: false
# timeout for dials
# client.dial-timeout: 10s

# path to the certificate chain for this identity
client.identity.cert-path: ""

# path to the private key for this identity
client.identity.key-path: ""

# maximum buffer size for DRPC streams
# client.maximum-buffer-size: 304.00 KB

Expand Down
6 changes: 6 additions & 0 deletions cmd/linksharing/config.yaml.lock
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ cert-magic.tier-service-identity.key-path: /identity.key
# list of clients IPs (comma separated) which are trusted; usually used when the service run behinds gateways, load balancers, etc.
client-trusted-ips-list: []

# path to the certificate chain for this identity
client.identity.cert-path: ""

# path to the private key for this identity
client.identity.key-path: ""

# RPC connection pool capacity
connection-pool.capacity: 100

Expand Down
12 changes: 12 additions & 0 deletions cmd/linksharing/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"storj.io/edge/pkg/linksharing"
"storj.io/edge/pkg/linksharing/sharing"
"storj.io/edge/pkg/linksharing/sharing/assets"
"storj.io/edge/pkg/uplinkutil"
"storj.io/uplink"
)

Expand Down Expand Up @@ -53,6 +54,10 @@ type LinkSharing struct {
ListPageLimit int `help:"maximum number of paths to list on a single page" default:"100"`
DynamicAssetsDir string `help:"use a assets dir that is reparsed for every request" default:""`

Client struct {
Identity uplinkutil.IdentityConfig
}

SatelliteConnectionPool satelliteConnectionPoolConfig
ConnectionPool connectionPoolConfig

Expand Down Expand Up @@ -148,6 +153,11 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
dynamicAssets = true
}

clientCertPEM, clientKeyPEM, err := runCfg.Client.Identity.LoadPEMs()
if err != nil {
return err
}

var tlsConfig *httpserver.TLSConfig
if !runCfg.InsecureDisableTLS {
tlsConfig = &httpserver.TLSConfig{
Expand Down Expand Up @@ -197,6 +207,8 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
Uplink: &uplink.Config{
UserAgent: "linksharing",
DialTimeout: runCfg.DialTimeout,
ChainPEM: clientCertPEM,
KeyPEM: clientKeyPEM,
},
ListPageLimit: runCfg.ListPageLimit,
},
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ require (
storj.io/eventkit v0.0.0-20240415002644-1d9596fee086
storj.io/gateway v1.9.1-0.20240517132048-2aaa6fd6d33e
storj.io/minio v0.0.0-20240517005305-6bf61e2db47a
storj.io/uplink v1.13.0
storj.io/uplink v1.13.1-0.20240522144333-931e862e9315
storj.io/zipper v0.0.0-20220124122551-2ac2d53a46f6
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1815,7 +1815,7 @@ storj.io/monkit-jaeger v0.0.0-20240221095020-52b0792fa6cd/go.mod h1:nwyyJiAFAPRu
storj.io/picobuf v0.0.3 h1:xAUPB5ZUGfxkqd3bnw3zp01kkWb9wlhg4vtZWUs2S9A=
storj.io/picobuf v0.0.3/go.mod h1:4V4xelV1RSCck5GgmkL/Txw9l6IfX3XcBzegmL5Kudo=
storj.io/uplink v1.7.1/go.mod h1:pKqsMpNMIAz//2TXzUGOR6tpu3iyabvXV4VWINj4jaY=
storj.io/uplink v1.13.0 h1:MAwzMaO4F86n2sMdNm7/m7LVyf8KD0FP+72h1H+HuRE=
storj.io/uplink v1.13.0/go.mod h1:MT8+V7qddgn1ra09piq3Idy4IUva2S90S7me7U8n6cE=
storj.io/uplink v1.13.1-0.20240522144333-931e862e9315 h1:e/slFmWr7UVY5XqtdnqlZZFtdIKOYi3riGzHWl9jL+w=
storj.io/uplink v1.13.1-0.20240522144333-931e862e9315/go.mod h1:MT8+V7qddgn1ra09piq3Idy4IUva2S90S7me7U8n6cE=
storj.io/zipper v0.0.0-20220124122551-2ac2d53a46f6 h1:vJQmb+uAiYn8hVfkhMl6OqjnUyMWSCPnkzW8IsjF8vE=
storj.io/zipper v0.0.0-20220124122551-2ac2d53a46f6/go.mod h1:MRnaO2kEXqZ+dd+InduHGg5RQy8gbrnPLaPp38CWDxg=
2 changes: 2 additions & 0 deletions pkg/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"storj.io/common/memory"
"storj.io/edge/pkg/authclient"
"storj.io/edge/pkg/uplinkutil"
"storj.io/gateway/miniogw"
)

Expand Down Expand Up @@ -86,6 +87,7 @@ type SatelliteConnectionPoolConfig struct {
type ClientConfig struct {
DialTimeout time.Duration `help:"timeout for dials" default:"10s"`
MaximumBufferSize memory.Size `help:"maximum buffer size for DRPC streams" default:"304kB"`
Identity uplinkutil.IdentityConfig

Upload uploadConfig
}
Expand Down
15 changes: 12 additions & 3 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ func New(config Config, log *zap.Logger, trustedIPs trustedip.List, corsAllowedO
MaxLifetime: config.ConnectionPool.MaxLifetime,
})

uplinkConfig := configureUplinkConfig(config.Client)
uplinkConfig, err := configureUplinkConfig(config.Client)
if err != nil {
return nil, err
}

layer, err := gw.NewMultiTenantLayer(miniogw.NewStorjGateway(config.S3Compatibility), satelliteConnectionPool, connectionPool, uplinkConfig, config.InsecureLogAll)
if err != nil {
Expand Down Expand Up @@ -194,10 +197,16 @@ func deduplicateDomains(domains string) (result []string) {
}

// configureUplinkConfig configures new uplink.Config using clientConfig.
func configureUplinkConfig(clientConfig ClientConfig) gw.UplinkConfig {
func configureUplinkConfig(clientConfig ClientConfig) (gw.UplinkConfig, error) {
clientCertPEM, clientKeyPEM, err := clientConfig.Identity.LoadPEMs()
if err != nil {
return gw.UplinkConfig{}, err
}
ret := gw.UplinkConfig{
Base: uplink.Config{
DialTimeout: clientConfig.DialTimeout,
ChainPEM: clientCertPEM,
KeyPEM: clientKeyPEM,
},
Uploads: gw.UploadConfig{
PieceHashAlgorithmBlake3: clientConfig.Upload.PieceHashAlgorithmBlake3,
Expand All @@ -207,7 +216,7 @@ func configureUplinkConfig(clientConfig ClientConfig) gw.UplinkConfig {

transport.SetMaximumBufferSize(&ret.Base, clientConfig.MaximumBufferSize.Int())

return ret
return ret, nil
}

func (s *Peer) healthCheck(w http.ResponseWriter, r *http.Request) {
Expand Down
37 changes: 37 additions & 0 deletions pkg/uplinkutil/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (C) 2024 Storj Labs, Inc.
// See LICENSE for copying information.

package uplinkutil

import (
"os"

"github.com/zeebo/errs"
)

// IdentityConfig is an intentional copy of identity.Config that has
// empty defaults.
type IdentityConfig struct {
CertPath string `help:"path to the certificate chain for this identity" default:"" user:"true" path:"true"`
KeyPath string `help:"path to the private key for this identity" default:"" user:"true" path:"true"`
}

// LoadPEMs loads files and returns their byte strings if set. A possible
// return value of this function is nil, nil, nil.
func (c *IdentityConfig) LoadPEMs() (certPEM, keyPEM []byte, err error) {
if c.CertPath == "" && c.KeyPath == "" {
return nil, nil, nil
}
if c.CertPath == "" || c.KeyPath == "" {
return nil, nil, errs.New("only one of key path and cert path are set (%q, %q)", c.KeyPath, c.CertPath)
}
certPEM, err = os.ReadFile(c.CertPath)
if err != nil {
return nil, nil, errs.New("failed reading cert path %q: %+v", c.CertPath, err)
}
keyPEM, err = os.ReadFile(c.KeyPath)
if err != nil {
return nil, nil, errs.New("failed reading key path %q: %+v", c.KeyPath, err)
}
return certPEM, keyPEM, nil
}
2 changes: 1 addition & 1 deletion testsuite/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
storj.io/edge v0.0.0-00010101000000-000000000000
storj.io/minio v0.0.0-20240517005305-6bf61e2db47a
storj.io/storj v1.91.0-alpha.0.20240529222445-8d5ead827f2a
storj.io/uplink v1.13.0
storj.io/uplink v1.13.1-0.20240522144333-931e862e9315
)

require (
Expand Down
4 changes: 2 additions & 2 deletions testsuite/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2721,7 +2721,7 @@ storj.io/picobuf v0.0.3/go.mod h1:4V4xelV1RSCck5GgmkL/Txw9l6IfX3XcBzegmL5Kudo=
storj.io/storj v1.91.0-alpha.0.20240529222445-8d5ead827f2a h1:ZvqgwTjT2jDxvK8DPoiF5tVQxKi+2IQnlBDoMfBzuy4=
storj.io/storj v1.91.0-alpha.0.20240529222445-8d5ead827f2a/go.mod h1:jl7/3zyG1hZ9nrY13nT/lCwgKo5R3CTBvJYfgZ/HPag=
storj.io/uplink v1.7.1/go.mod h1:pKqsMpNMIAz//2TXzUGOR6tpu3iyabvXV4VWINj4jaY=
storj.io/uplink v1.13.0 h1:MAwzMaO4F86n2sMdNm7/m7LVyf8KD0FP+72h1H+HuRE=
storj.io/uplink v1.13.0/go.mod h1:MT8+V7qddgn1ra09piq3Idy4IUva2S90S7me7U8n6cE=
storj.io/uplink v1.13.1-0.20240522144333-931e862e9315 h1:e/slFmWr7UVY5XqtdnqlZZFtdIKOYi3riGzHWl9jL+w=
storj.io/uplink v1.13.1-0.20240522144333-931e862e9315/go.mod h1:MT8+V7qddgn1ra09piq3Idy4IUva2S90S7me7U8n6cE=
storj.io/zipper v0.0.0-20220124122551-2ac2d53a46f6 h1:vJQmb+uAiYn8hVfkhMl6OqjnUyMWSCPnkzW8IsjF8vE=
storj.io/zipper v0.0.0-20220124122551-2ac2d53a46f6/go.mod h1:MRnaO2kEXqZ+dd+InduHGg5RQy8gbrnPLaPp38CWDxg=

0 comments on commit 5a3ea0f

Please sign in to comment.