diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f0b65fb9c..99dacb7f6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -125,27 +125,3 @@ jobs: - name: test run: go test -v ./integration/... - - storage-backend-test-redis: - runs-on: ubuntu-latest - services: - redis: - image: redis - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 6379:6379 - steps: - - name: install go - uses: actions/setup-go@v1 - with: - go-version: 1.14.x - - - name: checkout code - uses: actions/checkout@v2 - - - name: test - run: go test -v -tags redis ./pkg/storage/redis/... ./internal/databroker/... diff --git a/cache/databroker.go b/cache/databroker.go index 0574bf8aa..19961ea0d 100644 --- a/cache/databroker.go +++ b/cache/databroker.go @@ -1,13 +1,17 @@ package cache import ( + "crypto/tls" + "crypto/x509" "encoding/base64" "fmt" + "io/ioutil" "google.golang.org/grpc" "github.com/pomerium/pomerium/config" internal_databroker "github.com/pomerium/pomerium/internal/databroker" + "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/pkg/cryptutil" "github.com/pomerium/pomerium/pkg/grpc/databroker" ) @@ -23,10 +27,27 @@ func NewDataBrokerServer(grpcServer *grpc.Server, opts config.Options) (*DataBro if err != nil || len(key) != cryptutil.DefaultKeySize { return nil, fmt.Errorf("shared key is required and must be %d bytes long", cryptutil.DefaultKeySize) } + + caCertPool := x509.NewCertPool() + if caCert, err := ioutil.ReadFile(opts.DataBrokerStorageCAFile); err == nil { + caCertPool.AppendCertsFromPEM(caCert) + } else { + log.Warn().Err(err).Msg("failed to read databroker CA file") + } + tlsConfig := &tls.Config{ + RootCAs: caCertPool, + // nolint: gosec + InsecureSkipVerify: opts.DataBrokerStorageCertSkipVerify, + } + if opts.DataBrokerCertificate != nil { + tlsConfig.Certificates = []tls.Certificate{*opts.DataBrokerCertificate} + } + internalSrv := internal_databroker.New( internal_databroker.WithSecret(key), internal_databroker.WithStorageType(opts.DataBrokerStorageType), internal_databroker.WithStorageConnectionString(opts.DataBrokerStorageConnectionString), + internal_databroker.WithStorageTLSConfig(tlsConfig), ) srv := &DataBrokerServer{DataBrokerServiceServer: internalSrv} databroker.RegisterDataBrokerServiceServer(grpcServer, srv) diff --git a/config/options.go b/config/options.go index 9dfa2ffab..9100fe5a6 100644 --- a/config/options.go +++ b/config/options.go @@ -230,6 +230,12 @@ type Options struct { DataBrokerStorageType string `mapstructure:"databroker_storage_type" yaml:"databroker_storage_type,omitempty"` // DataBrokerStorageConnectionString is the data source name for storage backend. DataBrokerStorageConnectionString string `mapstructure:"databroker_storage_connection_string" yaml:"databroker_storage_connection_string,omitempty"` + DataBrokerStorageCertFile string `mapstructure:"databroker_storage_cert_file" yaml:"databroker_storage_cert_file,omitempty"` + DataBrokerStorageCertKeyFile string `mapstructure:"databroker_storage_key_file" yaml:"databroker_storage_key_file,omitempty"` + DataBrokerStorageCAFile string `mapstructure:"databroker_storage_ca_file" yaml:"databroker_storage_ca_file,omitempty"` + DataBrokerStorageCertSkipVerify bool `mapstructure:"databroker_storage_tls_skip_verify" yaml:"databroker_storage_tls_skip_verify,omitempty"` + + DataBrokerCertificate *tls.Certificate `mapstructure:"-" yaml:"-"` // ClientCA is the base64-encoded certificate authority to validate client mTLS certificates against. ClientCA string `mapstructure:"client_ca" yaml:"client_ca,omitempty"` @@ -590,6 +596,20 @@ func (o *Options) Validate() error { o.Certificates = append(o.Certificates, *cert) } + if o.DataBrokerStorageCertFile != "" || o.DataBrokerStorageCertKeyFile != "" { + cert, err := cryptutil.CertificateFromFile(o.CertFile, o.KeyFile) + if err != nil { + return fmt.Errorf("config: bad databroker cert file %w", err) + } + o.DataBrokerCertificate = cert + } + + if o.DataBrokerStorageCAFile != "" { + if _, err := os.Stat(o.DataBrokerStorageCAFile); err != nil { + return fmt.Errorf("config: bad databroker ca file: %w", err) + } + } + if o.ClientCA != "" { if _, err := base64.StdEncoding.DecodeString(o.ClientCA); err != nil { return fmt.Errorf("config: bad client ca base64: %w", err) diff --git a/docs/reference/readme.md b/docs/reference/readme.md index e31a8fd6f..ed7f0abb6 100644 --- a/docs/reference/readme.md +++ b/docs/reference/readme.md @@ -836,10 +836,46 @@ The backend storage that databroker server will use, available types: `memory`, - Config File Key: `databroker_storage_connection_string` - Type: `string` - **Required** when storage type is `redis` -- Example: `"redis://localhost:6379/0"` +- Example: `"redis://localhost:6379/0"`, `"rediss://localhost:6379/0"` The connection string that server will use to connect to storage backend. +### Data Broker Storage Certificate File + +- Environment Variable: `DATABROKER_STORAGE_CERT_FILE` +- Config File Key: `databroker_storage_cert_file` +- Type: relative file location +- Optional + +The certificate uses to connect to storage backend. + +### Data Broker Storage Certificate Key File + +- Environment Variable: `DATABROKER_STORAGE_KEY_FILE` +- Config File Key: `databroker_storage_key_file` +- Type: relative file location +- Optional + +The certificate key uses to connect to storage backend. + +### Data Broker Storage Certificate Authority + +- Environment Variable: `DATABROKER_STORAGE_CA_FILE` +- Config File Key: `databroker_storage_ca_file` +- Type: relative file location +- Optional + +The Broker Storage Certificate Authority defines the set of root certificate authorities that are use when verifying storage server certificates. + +### Data Broker Storage TLS Skip Verify + +- Environment Variable: `DATABROKER_STORAGE_TLS_SKIP_VERIFY` +- Config File Key: `databroker_storage_tls_skip_verify` +- Type: relative file location +- Optional + +If set, TLS connection to storage backend will not be verified. + ## Policy - Environmental Variable: `POLICY` diff --git a/go.mod b/go.mod index 59d26681e..1e5a98940 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/onsi/gomega v1.8.1 // indirect github.com/open-policy-agent/opa v0.22.0 github.com/openzipkin/zipkin-go v0.2.2 + github.com/ory/dockertest/v3 v3.6.0 github.com/pelletier/go-toml v1.6.0 // indirect github.com/pomerium/csrf v1.6.2-0.20190918035251-f3318380bad3 github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect diff --git a/go.sum b/go.sum index 0e2016176..b7dae9945 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,8 @@ contrib.go.opencensus.io/exporter/zipkin v0.1.1 h1:PR+1zWqY8ceXs1qDQQIlgXe+sdiwC contrib.go.opencensus.io/exporter/zipkin v0.1.1/go.mod h1:GMvdSl3eJ2gapOaLKzTKE3qDgUkJ86k9k3yY2eqwkzc= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg= github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw= github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= @@ -47,6 +49,10 @@ github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvd github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.7 h1:fzrmmkskv067ZQbd9wERNGuxckWw67dyzoMG62p7LMo= github.com/OneOfOne/xxhash v1.2.7/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= @@ -87,6 +93,8 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/caddyserver/certmagic v0.11.2 h1:nPBqyuFNHJEf2FwC1ixJjArtTKWyPqpaH6k4jl7gxYI= github.com/caddyserver/certmagic v0.11.2/go.mod h1:fqY1IZk5iqhsj5FU3Vw20Sjq66tEKaanTFYNZ74soMY= +github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cenkalti/backoff/v4 v4.0.0 h1:6VeaLF9aI+MAUQ95106HwWzYZgJJpZ4stumjj6RFYAU= github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= github.com/cenkalti/backoff/v4 v4.0.2 h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4eamEDs= @@ -109,6 +117,8 @@ github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533 h1:8wZizuKuZVu5COB7Es github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 h1:9kRtNpqLHbZVO/NNxhHp2ymxFxsHOe3x2efJGn//Tas= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 h1:NmTXa/uVnDyp0TY5MKi197+3HWcnYWfnHGyaFthlnGw= +github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -131,6 +141,10 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnsimple/dnsimple-go v0.60.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= @@ -328,6 +342,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA= github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA= github.com/liquidweb/liquidweb-go v1.6.0/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVLEIG/i5J9cyixzQ= github.com/lithammer/shortuuid/v3 v3.0.4 h1:uj4xhotfY92Y1Oa6n6HUiFn87CdoEHYUlTy0+IgbLrs= @@ -391,10 +407,18 @@ github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/open-policy-agent/opa v0.22.0 h1:KZvn0uMQIorBIwYk8Vc89dp8No9FIEF8eFl0sc1r/1U= github.com/open-policy-agent/opa v0.22.0/go.mod h1:rrwxoT/b011T0cyj+gg2VvxqTtn6N3gp/jzmr3fjW44= +github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/ory/dockertest/v3 v3.6.0 h1:I6KNJ6izxGduLACQii2SP/g7GN0JM9Xfaik6aAVaw6Y= +github.com/ory/dockertest/v3 v3.6.0/go.mod h1:4ZOpj8qBUmh8fcBSVzkH2bws2s91JdGvHUqan4GHEuQ= github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -627,6 +651,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -685,6 +710,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -718,6 +744,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -847,11 +874,14 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/databroker/config.go b/internal/databroker/config.go index 3979e2138..9e911b4ee 100644 --- a/internal/databroker/config.go +++ b/internal/databroker/config.go @@ -1,6 +1,9 @@ package databroker -import "time" +import ( + "crypto/tls" + "time" +) var ( // DefaultDeletePermanentlyAfter is the default amount of time to wait before deleting @@ -18,6 +21,7 @@ type serverConfig struct { secret []byte storageType string storageConnectionString string + storageTLSConfig *tls.Config } func newServerConfig(options ...ServerOption) *serverConfig { @@ -70,3 +74,10 @@ func WithStorageConnectionString(connStr string) ServerOption { cfg.storageConnectionString = connStr } } + +// WithStorageTLSConfig sets the tls config for connection to storage. +func WithStorageTLSConfig(tlsConfig *tls.Config) ServerOption { + return func(cfg *serverConfig) { + cfg.storageTLSConfig = tlsConfig + } +} diff --git a/internal/databroker/config_source_test.go b/internal/databroker/config_source_test.go index c1861041d..9d6e61fe2 100644 --- a/internal/databroker/config_source_test.go +++ b/internal/databroker/config_source_test.go @@ -26,7 +26,7 @@ func TestConfigSource(t *testing.T) { } defer li.Close() - dataBrokerServer := newTestServer() + dataBrokerServer := New() srv := grpc.NewServer() databroker.RegisterDataBrokerServiceServer(srv, dataBrokerServer) go func() { _ = srv.Serve(li) }() diff --git a/internal/databroker/helper_no_redis.go b/internal/databroker/helper_no_redis.go deleted file mode 100644 index 04d422b83..000000000 --- a/internal/databroker/helper_no_redis.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !redis - -package databroker - -func newTestServer() *Server { - return New() -} diff --git a/internal/databroker/helper_redis.go b/internal/databroker/helper_redis.go deleted file mode 100644 index 71903f7f5..000000000 --- a/internal/databroker/helper_redis.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build redis - -package databroker - -import ( - "os" - - "github.com/pomerium/pomerium/pkg/storage/redis" -) - -func newTestServer() *Server { - address := "redis://localhost:6379/0" - if redisURL := os.Getenv("REDIS_URL"); redisURL != "" { - address = redisURL - } - return New(WithStorageType(redis.Name), WithStorageConnectionString(address)) -} diff --git a/internal/databroker/server.go b/internal/databroker/server.go index 7acab1c3f..8fee509f5 100644 --- a/internal/databroker/server.go +++ b/internal/databroker/server.go @@ -350,9 +350,14 @@ func (srv *Server) getDB(recordType string) (storage.Backend, error) { func (srv *Server) newDB(recordType string) (db storage.Backend, err error) { switch srv.cfg.storageType { case config.StorageInMemoryName: - db = inmemory.NewDB(recordType, srv.cfg.btreeDegree) + return inmemory.NewDB(recordType, srv.cfg.btreeDegree), nil case config.StorageRedisName: - db, err = redis.New(srv.cfg.storageConnectionString, recordType, int64(srv.cfg.deletePermanentlyAfter.Seconds())) + db, err = redis.New( + srv.cfg.storageConnectionString, + recordType, + int64(srv.cfg.deletePermanentlyAfter.Seconds()), + redis.WithTLSConfig(srv.cfg.storageTLSConfig), + ) if err != nil { return nil, fmt.Errorf("failed to create new redis storage: %w", err) } diff --git a/pkg/storage/redis/option.go b/pkg/storage/redis/option.go new file mode 100644 index 000000000..aec80df07 --- /dev/null +++ b/pkg/storage/redis/option.go @@ -0,0 +1,13 @@ +package redis + +import "crypto/tls" + +// Option customizes a DB. +type Option func(*DB) + +// WithTLSConfig sets the tls.Config which DB uses. +func WithTLSConfig(tlsConfig *tls.Config) Option { + return func(db *DB) { + db.tlsConfig = tlsConfig + } +} diff --git a/pkg/storage/redis/redis.go b/pkg/storage/redis/redis.go index 979ea0a40..b728f9607 100644 --- a/pkg/storage/redis/redis.go +++ b/pkg/storage/redis/redis.go @@ -3,9 +3,11 @@ package redis import ( "context" + "crypto/tls" "fmt" "net" "strconv" + "strings" "time" "github.com/golang/protobuf/proto" @@ -35,38 +37,44 @@ type DB struct { lastVersionKey string versionSet string deletedSet string + tlsConfig *tls.Config } // New returns new DB instance. -func New(rawURL, recordType string, deletePermanentAfter int64) (*DB, error) { +func New(rawURL, recordType string, deletePermanentAfter int64, opts ...Option) (*DB, error) { db := &DB{ - pool: &redis.Pool{ - Wait: true, - Dial: func() (redis.Conn, error) { - c, err := redis.DialURL(rawURL) - if err != nil { - return nil, fmt.Errorf(`redis.DialURL(): %w`, err) - } - return c, nil - }, - TestOnBorrow: func(c redis.Conn, t time.Time) error { - if time.Since(t) < time.Minute { - return nil - } - _, err := c.Do("PING") - if err != nil { - return fmt.Errorf(`c.Do("PING"): %w`, err) - } - return nil - }, - }, deletePermanentlyAfter: deletePermanentAfter, recordType: recordType, versionSet: recordType + "_version_set", deletedSet: recordType + "_deleted_set", lastVersionKey: recordType + "_last_version", } + metrics.AddRedisMetrics(db.pool.Stats) + for _, o := range opts { + o(db) + } + db.pool = &redis.Pool{ + Wait: true, + Dial: func() (redis.Conn, error) { + c, err := redis.DialURL(rawURL, redis.DialTLSConfig(db.tlsConfig)) + if err != nil { + return nil, fmt.Errorf(`redis.DialURL(): %w`, err) + } + return c, nil + }, + TestOnBorrow: func(c redis.Conn, t time.Time) error { + if time.Since(t) < time.Minute { + return nil + } + _, err := c.Do("PING") + if err != nil { + return fmt.Errorf(`c.Do("PING"): %w`, err) + } + return nil + }, + } + return db, nil } @@ -255,6 +263,9 @@ func (db *DB) doNotifyLoop(ctx context.Context, ch chan struct{}, psc *redis.Pub if _, ok := v.(net.Error); ok { return } + if strings.HasPrefix(v.Error(), "redigo: connection closed") { + return + } } } } diff --git a/pkg/storage/redis/redis_test.go b/pkg/storage/redis/redis_test.go index 4078c8289..ec291379f 100644 --- a/pkg/storage/redis/redis_test.go +++ b/pkg/storage/redis/redis_test.go @@ -1,20 +1,27 @@ -// +build redis - package redis import ( "context" + "crypto/tls" + "crypto/x509" "fmt" + "io/ioutil" "os" + "runtime" + "strings" "testing" "time" "github.com/gomodule/redigo/redis" + "github.com/ory/dockertest/v3" + "github.com/pomerium/pomerium/pkg/cryptutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/anypb" ) +var db *DB + func cleanup(c redis.Conn, db *DB, t *testing.T) { require.NoError(t, c.Send("MULTI")) require.NoError(t, c.Send("DEL", db.recordType)) @@ -24,24 +31,97 @@ func cleanup(c redis.Conn, db *DB, t *testing.T) { require.NoError(t, err) } +func tlsConfig(rawURL string, t *testing.T) *tls.Config { + if !strings.HasPrefix(rawURL, "rediss") { + return nil + } + cert, err := cryptutil.CertificateFromFile("./testdata/tls/redis.crt", "./testdata/tls/redis.key") + require.NoError(t, err) + caCertPool := x509.NewCertPool() + caCert, err := ioutil.ReadFile("./testdata/tls/ca.crt") + require.NoError(t, err) + caCertPool.AppendCertsFromPEM(caCert) + tlsConfig := &tls.Config{ + RootCAs: caCertPool, + Certificates: []tls.Certificate{*cert}, + } + return tlsConfig +} + +func runWithRedisDockerImage(repo, tag string, env []string, withTLS bool, testFunc func(t *testing.T), t *testing.T) { + pool, err := dockertest.NewPool("") + if err != nil { + t.Fatalf("Could not connect to docker: %s", err) + } + resource, err := pool.Run(repo, tag, env) + if err != nil { + t.Fatalf("Could not start resource: %s", err) + } + + defer func() { + if err := pool.Purge(resource); err != nil { + t.Fatalf("Could not purge resource: %s", err) + } + }() + + scheme := "redis" + if withTLS { + scheme = "rediss" + } + address := fmt.Sprintf(scheme+"://localhost:%s/0", resource.GetPort("6379/tcp")) + if err := pool.Retry(func() error { + var err error + db, err = New(address, "record_type", int64(time.Hour.Seconds()), WithTLSConfig(tlsConfig(address, t))) + if err != nil { + return err + } + _, err = db.pool.Get().Do("PING") + return err + }); err != nil { + t.Fatalf("Could not connect to docker: %s", err) + } + + testFunc(t) +} + func TestDB(t *testing.T) { + if os.Getenv("GITHUB_ACTION") != "" && runtime.GOOS == "darwin" { + t.Skip("Github action can not run docker on MacOS") + } + redisTLSEnv := []string{ + "ALLOW_EMPTY_PASSWORD=yes", + "REDIS_TLS_ENABLED=yes", + "REDIS_TLS_CERT_FILE=/tls/redis.crt", + "REDIS_TLS_KEY_FILE=/tls/redis.key", + "REDIS_TLS_CA_FILE=/tls/ca.crt", + } + tests := []struct { + name string + repo string + tag string + env []string + withTLS bool + }{ + {"redis", "redis", "latest", nil, false}, + {"redis TLS", "gnouc/pomerium-redis-tls", "latest", redisTLSEnv, true}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + runWithRedisDockerImage(tc.repo, tc.tag, tc.env, tc.withTLS, testDB, t) + }) + } +} + +func testDB(t *testing.T) { ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() - address := "redis://localhost:6379/0" - if redisURL := os.Getenv("REDIS_URL"); redisURL != "" { - address = redisURL - } - db, err := New(address, "record_type", int64(time.Hour.Seconds())) - require.NoError(t, err) + ids := []string{"a", "b", "c"} id := ids[0] c := db.pool.Get() defer c.Close() - cleanup(c, db, t) - _, err = c.Do("DEL", db.lastVersionKey) - require.NoError(t, err) - ch := db.Watch(ctx) t.Run("get missing record", func(t *testing.T) { @@ -94,10 +174,9 @@ func TestDB(t *testing.T) { }) t.Run("list", func(t *testing.T) { cleanup(c, db, t) - ids := make([]string, 0, 10) + for i := 0; i < 10; i++ { id := fmt.Sprintf("%02d", i) - ids = append(ids, id) data := new(anypb.Any) assert.NoError(t, db.Put(ctx, id, data)) } diff --git a/pkg/storage/redis/testdata/Dockerfile b/pkg/storage/redis/testdata/Dockerfile new file mode 100644 index 000000000..519c1454b --- /dev/null +++ b/pkg/storage/redis/testdata/Dockerfile @@ -0,0 +1,3 @@ +FROM bitnami/redis:latest + +Add tls /tls diff --git a/pkg/storage/redis/testdata/tls/ca.crt b/pkg/storage/redis/testdata/tls/ca.crt new file mode 100644 index 000000000..5cf4af4da --- /dev/null +++ b/pkg/storage/redis/testdata/tls/ca.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE5jCCAs4CCQCcWg5kDLmBZTANBgkqhkiG9w0BAQsFADA1MRMwEQYDVQQKDApS +ZWRpcyBUZXN0MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjAw +NzMwMDQyMzAxWhcNMzAwNzI4MDQyMzAxWjA1MRMwEQYDVQQKDApSZWRpcyBUZXN0 +MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQClzNGrTLlQKurX1CDnCTX2mRD6G0QAlXZ8nU3Lphhu +8SgJd868DWQp+f/c6VoXuhz+rRZoPrSvgtSCqSrtWy5vj5eC8egvYQNZOcH8aj3R +1vCq7h10nRUqJGG/PhvQoYKFIx0s4kXiiNsdH+cvnfiIkwt6Hw9eY8GjBgB5lQQ+ +P+RKDjV4busREDfYWV3N+YWoNz7KjRrjJO3XTeDFfywfSGWPKUtJAC3bggjOv76F +td7iK1bFfcxLVkey3ZOCVp74n3p6tnkF6rXoS4Ji4bfmMjIZubtd/jNZiV1vjsWz +EiUVo229mROzCug9GbXf8SW9en5qwM8nigL5NQQAObrSwbKTtVLgFLjTcELwiz0H +/3MSFVWBrWZQZHwXabC/YF2LogZ9ZClGhRn6+kG0wpovBCPltmS9MK8g3dx9U5cP +VTkm4aer8OlP4wggsGz4Yk410YkBkj/4V3Ge22jRxr93k/OWFDkX+pG44UVlCiFQ +3hy2X80VQrJn59QM7BrRfnC9JYJvlF5ON+iSuTGDv3r3ELwlPPxHZArPp6KLw4Qm +yt+b2eMzFx/mS9cAEAw1rwwoGtJdnWXn0UX8qFPc9uJhV9f3xv9tvOAJElKXwMq+ +PKDrY4ThwJGVnkV87WUq8vPal4XNXLKApPdHwnR3bSPVKTSUNsHYARmd0thYshBa +7QIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQAu6anZk8Ac5B0mvI3HD2MG885z4l3t +fo9z1VJHthIyFCUcf/zwkdjFED6Gxn4G5QX399cFg+NrNxEC0x3K3Au4yD/uKCxp +yhuWzYGamkGzQJ6kX1edJ+l8CgstdVUWBVmWOyPKSQKJKUqaK4flhW6vPZNPTErQ +nUzjEXDzYGy1OVZlPWh2e5ng9EeTYBkaXMRIL6JbPbNxroE+aQsQ8e737tN+Ih8+ +ZHR4B8/lnipnqUaFpnuK4PJZStQW3rLxv+7Xny3nUM6HKB8iz3JgmDDTlCoOtQ1K +Dl8J3w4/v12zat5VRwyIkpkbmqsczRnryK+U7iQX7rSTCBBsjC6yXyo/yqR7f7qh +T2MbXotZDZOopJDkJ70a83bQgR2zlU46oPSXmX7Zum+9zSOSzu5YUeqTC4cvPM8V +vYimiJnAmwhe9HUXfypezh2LLISqTLt9z+6ZImXf+KSu6xdocdON7cMfyxWhVEUw +twHnNYH88OlacSHLSG5ArnoNGnkELfBB8gVXjaVH4n/q0XJCEFu85WPKfgS0aA6c +rMKh3Fo3dpkTXg69aCXBKTwnp0+1uV6F7gB0YyOjd1bBhEQjRF6rNmbqX7f0vYNO +JSLoJWZsLidmBFsAEhLMnyE9tX7nzgLT38gzOhEhjMdZaGHw8lEx+WZnT0F/Sl+o +izm4jRW7jSLxfw== +-----END CERTIFICATE----- diff --git a/pkg/storage/redis/testdata/tls/ca.key b/pkg/storage/redis/testdata/tls/ca.key new file mode 100644 index 000000000..7ee388468 --- /dev/null +++ b/pkg/storage/redis/testdata/tls/ca.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEApczRq0y5UCrq19Qg5wk19pkQ+htEAJV2fJ1Ny6YYbvEoCXfO +vA1kKfn/3OlaF7oc/q0WaD60r4LUgqkq7Vsub4+XgvHoL2EDWTnB/Go90dbwqu4d +dJ0VKiRhvz4b0KGChSMdLOJF4ojbHR/nL534iJMLeh8PXmPBowYAeZUEPj/kSg41 +eG7rERA32FldzfmFqDc+yo0a4yTt103gxX8sH0hljylLSQAt24IIzr++hbXe4itW +xX3MS1ZHst2Tglae+J96erZ5Beq16EuCYuG35jIyGbm7Xf4zWYldb47FsxIlFaNt +vZkTswroPRm13/ElvXp+asDPJ4oC+TUEADm60sGyk7VS4BS403BC8Is9B/9zEhVV +ga1mUGR8F2mwv2Bdi6IGfWQpRoUZ+vpBtMKaLwQj5bZkvTCvIN3cfVOXD1U5JuGn +q/DpT+MIILBs+GJONdGJAZI/+Fdxntto0ca/d5PzlhQ5F/qRuOFFZQohUN4ctl/N +FUKyZ+fUDOwa0X5wvSWCb5ReTjfokrkxg7969xC8JTz8R2QKz6eii8OEJsrfm9nj +Mxcf5kvXABAMNa8MKBrSXZ1l59FF/KhT3PbiYVfX98b/bbzgCRJSl8DKvjyg62OE +4cCRlZ5FfO1lKvLz2peFzVyygKT3R8J0d20j1Sk0lDbB2AEZndLYWLIQWu0CAwEA +AQKCAgEAlh60fSCT7bVeO5tTSz04whXnnD1RviGWTdB0Hv89wj3SHXiAFB8f4S39 +8DzNGQynsiRwVGTqXrvbxI59UrorelGOQr7blwKE8KXuMajUXon6ERpWSz7raePV +KT6IGsgSEJAxm3EpC6sUkfNP9PpYjPhu/Nzgons6WWxWw78cP2zEPBVPbsMnTaTc +m6SW3aee0CdtUCKhBKdsPnTCHrA99/kqE4y1INzrqIO9i81rKU/6Bdht0ZVMg64U +byxWoj3h5IUpdbCANc5FdJXh8bwkMWajnE1iDAHc5qYMlrSz5qZ4M3ZtJ61Re9xV +WPVNiv2iSUR+8BOxvUAl3xSUkcuzjilDxza3S1Ryglw9/6x8UYYOMA71BGK4FuBc +ebQNElJTTPRUaGVo0+Wx/+lBW7PL2HCWXTuF61qskIzLi43+eDaVPSbSqw3Kd+GW +KZQ2dFCMWOjSPFFtm2PtJEy4SQOLFx6lvWslKXYXC9tcMHLM3VMd1+I2WZC3TnnG +uSeeTXibbRcQadZbIDQ6HdfdHwnDd20bC140CIm3qdFtUtHR/mvC+2JvR48+edT4 +Vpn0VHPDbLB5N4wHDlvwWIjTToJUA5OS1478bycV1S8oDxL9fDrjTdH8DFvd3IN5 +S4YMWSB+5y933gUTquJjA6e1LfOYQ/tvUcL0cRwTWtNCPMEG0ZUCggEBAM8LCvxh +ZFwB8tDBtR4g4qF8IQKTf5y225P92u2TL2jRm+W7hCgc8x0a7VI7yA+Q8CBT+WuW +NhKlI/OKgNQhotRTPFyhuhz9NKkT7ZRdv9baOeB+VeXh0gzj2+s81x3xH3ermb86 +UoPgeOZH87GbNRW472a5+U3ks/K+kIcX2kpDzKPBwYp+ZZ7AKprVSvyK8+0Y+o/v +mFQKdZBR36jIlG2mabx/iSlZxSYOsi89K8R1tqsDcIlAyFIHBZKTuEGkY4fAEfDc +NZejwpcOmeXsh2P7+T71o6efcYIoeVS0YkeWCBV/vX667F/uEbq0/Wtp/ClRNg21 +0D0RhHj/MMsUKVsCggEBAM0BNPS1v64Kr5FDGXZ4xqfqXGse8EvQTVDnUjaRO6K9 +ZKf2ezNRzxQ5RVJAYLhnqSn1ISDuuaSDR9NP74FptKHemswfNqIH206Z+MweBmEX +6+wXuYlI+e4tCUgeUlDh3gu4OBsNlWtwU2oD/zE3RB3DO60Nn1yuZxP7OK1wzOLi +NLvVHdm9x+h5EaQBaaRM3sOGEdndGXFoCXZzfbezf7O2cMW58Gc6HKnIeodgM3UU +ApaY/odPUYmUaPqdbhBViNBNjYjGhQWsQN5ot6VB5sGFsfJD5eKuVDLeAnKINUaO +e8T4m7QLCU8pbeVebQoMD47jtBbbgztAnYs7ioCHd1cCggEAIdNJCTCUJ9/9npN3 +FqQCwqU382bLm3vYZdY8dUHtpe9Qy/iVv8PzCBdFHIE9zyU7xdxSTHxu+x7Vv80p +/P49zviGTQ/zCxdnChSCZRHn7J8cg4vAVt1M5uQ3Irh+4JprLK7xYGeT4Y3D0sOA +kcysoI7lNeA+VbZ+m7L8g8Wm2Sk4fqyCBTFfQs9cZo1gQeAlt9+z194qAdjvmhN2 +OeoDLeLZNX2UmBfdeLk/7S3OP7uHi2r1cMcPsy8Ifwj5Omg0BpKfm70uWEbd3LX6 ++LBq8i/RabLR+Om4rq4UHH2X7OAbFAAZomHBim6noNw+5tSa6Nkmvpism72H6giv +HQ5/LwKCAQBYZw3T/NAUmC0PghTn3rsjy89gri3HM6MzoRz1xPkne259c6+6+KtI +uE2pY3OR8bmkCz3m+qr5Q1dky1KnxtKK/vhXz5n6k1LB+Wmtc8Eie3NUEwMCLYMB +b1BSVij/EfdzrFQdbmUhuIVv8RtJuOBZyUfhnz86c0al+i59tGfV6t/8o7FEpS8g +k5zE0Yshu7hQLm9iOJLxMYDrIHB1GCWYdLL6wOznRsr3eClGWXi3IxLeqEkSRmUN +4/7FG8BLsObXlKnU8m6IfLhYcGXJELsWdrW+mAL5Fl3etZfulcgLjgPXc7GJGT1B +csceIvL4Yy0OXCjbtntHwNxvHxThygjvAoIBAQCoRITYoX6Lql8ozAbG4qnYhutL +uzTt2WAuaEsCPn5+8qANn9DSLbUvPg4nrwCY44pKB5CW1Pfh3VXvJVKSprpj9AFV +N896EXnm/Zl+3l88bvAtqVc0zPXeLG3HvVldWVwzTSDVJBEoNYMlqwKu0lIGPArV +YxM+7Oygg559vRi67CYMK+CLjh4kVJ8Rttf4pOO1EedbChbOAlMQy9hcO29xbFK7 +Xhd1TeubGvUqsqD/HNRt010W0HvLeDtUZ1bxOIE7ZdxsmeF4HUGhWmxbofsAio6C +HGrF+7zN0Dha4DFF4zVyqjZlNlLBYxbJkThyHNbC1Jr9Mior+K8IN2NrROjJ +-----END RSA PRIVATE KEY----- diff --git a/pkg/storage/redis/testdata/tls/ca.txt b/pkg/storage/redis/testdata/tls/ca.txt new file mode 100644 index 000000000..700e99d0d --- /dev/null +++ b/pkg/storage/redis/testdata/tls/ca.txt @@ -0,0 +1 @@ +D2B95B278BB44405 diff --git a/pkg/storage/redis/testdata/tls/redis.crt b/pkg/storage/redis/testdata/tls/redis.crt new file mode 100644 index 000000000..e1b28cb40 --- /dev/null +++ b/pkg/storage/redis/testdata/tls/redis.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID2jCCAcICCQDSuVsni7REBTANBgkqhkiG9w0BAQsFADA1MRMwEQYDVQQKDApS +ZWRpcyBUZXN0MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjAw +NzMwMDQyMzQ0WhcNMjEwNzMwMDQyMzQ0WjApMRMwEQYDVQQKDApSZWRpcyBUZXN0 +MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDlqpPoUThTy+bbhKynsb1q/jSkh6UlvaitCgLANlmpQzGMLkK7lRcOF3GA +VthohYcHEitUzqtgkqYtdruQ38/fWRJZUnfjV8wCp9pVZ8iVnPr6oAXN/u0REeye +jrwnEzEao1Bn9QpLtHB7o0GsHgEcu1DpZGWxjZY6TNcO1OT61slYvmXM7D0oEPD8 +P05uGgImpmD9gE0pZTMnZKCjdErBE+9AldbHpQEQukQ60DBw4Px8fSWYdXOUbi4H +12AcNq//LFtpEtsFZ2FtUoRxhwVxeXmoPkYmnz1ZUssWtND/AMYcke3+OJ+hh4tU +qU28IOj2muCFs9Ibh+ecFwXZFzgrAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAD+J +/MKK7e8PDSNqZl5vKj4CWZCAiHDFTIuyjGN0SBGlhIAVYEmUU28QHIpB7P/BTbih +ToUW9Z1AEcbNbo3jRnLftZ5dHT0m7VxmFhTw3S2+D8oFuFOSVGQ49UFFb/Mc6VXT +AIhgSSfMo0Sl83oyA35U4bKBkyW+3zPm/Tlagqsotxp4IMfDNc1dAMoeVSS8Pb5k +KZxxGBU7dkxeLVywzTloVXduMuE6eVOZgEOCPCG419RHUFSvZKSxIjatgK+bkw9H +WYtGduRZinU2QDlnTZVhq78rqhrsloW4uCfpBo/DF5V043iQ5RmGuLzFkilRvpZQ +QAAbc2qWxUJKl61TprY9RD1vp35TXuTsJIiiGYYOXJjc1lEE7VjRi1JDPPtT2DpW +GDJE/ma7VwzHUf3+AOrq4TH1Cjw0v0sz2rwkS4KAKTqz/CYoIg1wwUnOOr5FfSSP +6rzaAhtWK3+jJW6jf1+Loe7FtEeL8uzILbxmHrjoBLvRU8zlLYvXl9TnPDXRE2TF +4mSySab4OVILxf0ykRdrsO9of10xl3x5MKAbEsHiwsMrA47lN8WxF/BD2OhZMMA7 +HOWoB+O5qrwHSQJiVCRWWw3OpCeguMgrC8u4gWM6i589yH6fpRwH5dxCtIcrJBmB +YuhPo+21yI3+v6ylQcY2Rrh7k5TlCpCQYFHfcmOV +-----END CERTIFICATE----- diff --git a/pkg/storage/redis/testdata/tls/redis.dh b/pkg/storage/redis/testdata/tls/redis.dh new file mode 100644 index 000000000..31ef5cf23 --- /dev/null +++ b/pkg/storage/redis/testdata/tls/redis.dh @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA0z6Tn69LEeG4+pooHvW9ENMBqdd23JD0UvB69TknOLogvSFUpQwI +JNlhisC0a4LjuBD07X9drWW1uL2yb8vgexGRpWxLmPMEUTMTCRzkHVQEHSkV6MJn +todbgVQ4c2DRGAsSA8VY5XVGIf6w7IUJ/OagyQ/Gr/9+DzliOC7svQlR2iKogX/s +P4+qk0is8lpMMBzhz1bzo4zsJ8NMFqzYGQzuYzlEQlI6UCiiR2+rd6Fh83RbPb12 +4o9XKr0Wh+hAwl6EOERMmHR2UBYFn1+It6vmcg8uJnoEWzSiZTWOXqID3YeRyCPi +Myz43Ir5tHMz3V6gVSBZnhex09w58FjRkwIBAg== +-----END DH PARAMETERS----- diff --git a/pkg/storage/redis/testdata/tls/redis.key b/pkg/storage/redis/testdata/tls/redis.key new file mode 100644 index 000000000..fdf9dbe5c --- /dev/null +++ b/pkg/storage/redis/testdata/tls/redis.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA5aqT6FE4U8vm24Ssp7G9av40pIelJb2orQoCwDZZqUMxjC5C +u5UXDhdxgFbYaIWHBxIrVM6rYJKmLXa7kN/P31kSWVJ341fMAqfaVWfIlZz6+qAF +zf7tERHsno68JxMxGqNQZ/UKS7Rwe6NBrB4BHLtQ6WRlsY2WOkzXDtTk+tbJWL5l +zOw9KBDw/D9ObhoCJqZg/YBNKWUzJ2Sgo3RKwRPvQJXWx6UBELpEOtAwcOD8fH0l +mHVzlG4uB9dgHDav/yxbaRLbBWdhbVKEcYcFcXl5qD5GJp89WVLLFrTQ/wDGHJHt +/jifoYeLVKlNvCDo9prghbPSG4fnnBcF2Rc4KwIDAQABAoIBAHWBV9mmLJabHYu1 +Dw1hoBNs6ow/ppxvtCyMkam8ZRV3/pLFXHlTJ4+bKQRL6r9XiiVxA2CJuR9ZCNL8 +C61tBZM1pHC1BAf6dLPrI4dM6VC7F6JBW5bw1mREcncRemzXoekKI+p8cf8X2/E2 +LzSbyV/k6tnu9yTn1zQO+n1pKZq4b/uWu65iMlwRZbOx6vhRRCe+vJSsidAN4O1E +k6yfJxmVagUNqu4jPmfrcGGbTV27CJgwRZymnnp9pOQ39aJNNmU1EvLdMdFK88hF +8FRZwE1uYW7sTSXQtoyiaQ/XjaLb2Mu4SqyjkpA7sWqMvQ0tSJOfoRb3kJsUrX4T +5n4gyXECgYEA9O8MaZ1QynjPJIkm0SC4FkeVbOLwE45+9cGOHsAdigH5Ac/257gx +tke92Gq06RE3h9NvZ46cTcNB0wavS3BTdgi1Aw6u2JSWsBbndnriUyhoaORosKA/ +j19T+DRjqn7wV8b2coQiW8hUaa1MYazHkO9kyDccacQHhhkRJXnQk+kCgYEA8Arx +XdVN+vpLAA9EUq71y3Y8EHilK8Yo+5XZT0yAPAi5EZBaZ5dcx+LwCQrIJvDswNpt +sICwSSJtwGrp9zrdQiTb3NyjU6XFe//pRl3ZVTd6ik64Ol99vBcrAhxMTHbv3xw5 +XY6ToiGTMbsLS28Afigdizpcrz2WScb97pZ7AvMCgYBa7uDx2PjkoqNs0gp6O6Z8 +hwj/yuUMrauO+9QSsIqG8SKMPLRS5Px3yvy9eyg9Gyo9oA7NKJH5ANPQT7wGyuYB +fUwOnYXmXIvxRh+ayhZ6fxb8UkhXwra2ONMI5BJYexYp0HEwpMPIxYApV7By1t2k +fmwxNNy0m5WbgHTwL+By+QKBgCJ+0BTV9HDeyyxlBUKElhn5EcSkMchKn9UXwbTd +n4gBEOdvQS6l19V5zVjfTcga00sbmKvGso6v/emq85htwyIgPeBNbMM2jVy2eAV+ +sx7F7Dw3982br2v6QFn7SxOp++qqGaxSMvEXthltccATYZS/mw9JAczFIvXTPOau +hVr1AoGAQ/QV3VKabio66A6pzS4JmHU8tAlDuLGbFG1uUYZZoQDz5mwij7WTMy3a +DQ2TnanrHeyQY9SKK+FLOoezE8IeOyZC/Er3TOoCH5p+OM47mblANtSj3BL7oWif +KPxtI0OZlmUbQvGTrRdy5093FtRXiLB/rAnJ2cox12mYqwStDbA= +-----END RSA PRIVATE KEY-----