mirror of
https://github.com/minio/minio.git
synced 2025-04-22 03:24:38 -04:00
fix: allow S3 gateway passthrough for SSE-S3 header (#12020)
only in case of S3 gateway we have a case where we need to allow for SSE-S3 headers as passthrough, If SSE-C headers are passed then they are rejected if KMS is not configured.
This commit is contained in:
parent
16ce7fb70c
commit
0e4794ea50
@ -381,6 +381,13 @@ func (e errorCodeMap) ToAPIErrWithErr(errCode APIErrorCode, err error) APIError
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
apiErr.Description = fmt.Sprintf("%s (%s)", apiErr.Description, err)
|
apiErr.Description = fmt.Sprintf("%s (%s)", apiErr.Description, err)
|
||||||
}
|
}
|
||||||
|
if globalServerRegion != "" {
|
||||||
|
switch errCode {
|
||||||
|
case ErrAuthorizationHeaderMalformed:
|
||||||
|
apiErr.Description = fmt.Sprintf("The authorization header is malformed; the region is wrong; expecting '%s'.", globalServerRegion)
|
||||||
|
return apiErr
|
||||||
|
}
|
||||||
|
}
|
||||||
return apiErr
|
return apiErr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2116,6 +2123,13 @@ func toAPIError(ctx context.Context, err error) APIError {
|
|||||||
Description: e.Message,
|
Description: e.Message,
|
||||||
HTTPStatusCode: e.StatusCode,
|
HTTPStatusCode: e.StatusCode,
|
||||||
}
|
}
|
||||||
|
if globalIsGateway && strings.Contains(e.Message, "KMS is not configured") {
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "NotImplemented",
|
||||||
|
Description: e.Message,
|
||||||
|
HTTPStatusCode: http.StatusNotImplemented,
|
||||||
|
}
|
||||||
|
}
|
||||||
case *googleapi.Error:
|
case *googleapi.Error:
|
||||||
apiErr = APIError{
|
apiErr = APIError{
|
||||||
Code: "XGCSInternalError",
|
Code: "XGCSInternalError",
|
||||||
|
@ -876,6 +876,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
|
|||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
dstBucket := vars["bucket"]
|
dstBucket := vars["bucket"]
|
||||||
dstObject, err := unescapePath(vars["object"])
|
dstObject, err := unescapePath(vars["object"])
|
||||||
@ -1395,9 +1396,18 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := crypto.IsRequested(r.Header); !objectAPI.IsEncryptionSupported() && ok {
|
if _, ok := crypto.IsRequested(r.Header); ok {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
if globalIsGateway {
|
||||||
return
|
if crypto.SSEC.IsRequested(r.Header) && !objectAPI.IsEncryptionSupported() {
|
||||||
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !objectAPI.IsEncryptionSupported() {
|
||||||
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
@ -1698,9 +1708,18 @@ func (api objectAPIHandlers) PutObjectExtractHandler(w http.ResponseWriter, r *h
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := crypto.IsRequested(r.Header); !objectAPI.IsEncryptionSupported() && ok {
|
if _, ok := crypto.IsRequested(r.Header); ok {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
if globalIsGateway {
|
||||||
return
|
if crypto.SSEC.IsRequested(r.Header) && !objectAPI.IsEncryptionSupported() {
|
||||||
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !objectAPI.IsEncryptionSupported() {
|
||||||
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
@ -1978,9 +1997,18 @@ func (api objectAPIHandlers) NewMultipartUploadHandler(w http.ResponseWriter, r
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := crypto.IsRequested(r.Header); !objectAPI.IsEncryptionSupported() && ok {
|
if _, ok := crypto.IsRequested(r.Header); ok {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
if globalIsGateway {
|
||||||
return
|
if crypto.SSEC.IsRequested(r.Header) && !objectAPI.IsEncryptionSupported() {
|
||||||
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !objectAPI.IsEncryptionSupported() {
|
||||||
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
@ -2429,10 +2457,20 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := crypto.IsRequested(r.Header); !objectAPI.IsEncryptionSupported() && ok {
|
if _, ok := crypto.IsRequested(r.Header); ok {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
if globalIsGateway {
|
||||||
return
|
if crypto.SSEC.IsRequested(r.Header) && !objectAPI.IsEncryptionSupported() {
|
||||||
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !objectAPI.IsEncryptionSupported() {
|
||||||
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
bucket := vars["bucket"]
|
bucket := vars["bucket"]
|
||||||
object, err := unescapePath(vars["object"])
|
object, err := unescapePath(vars["object"])
|
||||||
|
@ -67,22 +67,28 @@ As a prerequisite to run MinIO S3 gateway on an AWS S3 compatible service, you n
|
|||||||
## Run MinIO Gateway with double-encryption
|
## Run MinIO Gateway with double-encryption
|
||||||
MinIO gateway to S3 supports encryption of data at rest. Three types of encryption modes are supported
|
MinIO gateway to S3 supports encryption of data at rest. Three types of encryption modes are supported
|
||||||
|
|
||||||
- encryption can be set to ``pass-through`` to backend
|
- encryption can be set to ``pass-through`` to backend only for SSE-S3, SSE-C is not allowed passthrough.
|
||||||
- ``single encryption`` (at the gateway)
|
- ``single encryption`` (at the gateway)
|
||||||
- ``double encryption`` (single encryption at gateway and pass through to backend).
|
- ``double encryption`` (single encryption at gateway and pass through to backend)
|
||||||
|
|
||||||
This can be specified by setting MINIO_GATEWAY_SSE environment variable. If MINIO_GATEWAY_SSE and KMS are not setup, all encryption headers are passed through to the backend. If KMS environment variables are set up, ``single encryption`` is automatically performed at the gateway and encrypted object is saved at the backend.
|
This can be specified by setting MINIO_GATEWAY_SSE environment variable. If MINIO_GATEWAY_SSE and KMS are not setup, all encryption headers are passed through to the backend. If KMS environment variables are set up, ``single encryption`` is automatically performed at the gateway and encrypted object is saved at the backend.
|
||||||
|
|
||||||
To specify ``double encryption``, MINIO_GATEWAY_SSE environment variable needs to be set to "s3" for sse-s3
|
To specify ``double encryption``, MINIO_GATEWAY_SSE environment variable needs to be set to "s3" for sse-s3
|
||||||
and "c" for sse-c encryption. More than one encryption option can be set, delimited by ";". Objects are encrypted at the gateway and the gateway also does a pass-through to backend. Note that in the case of SSE-C encryption, gateway derives a unique SSE-C key for pass through from the SSE-C client key using a key derivation function (KDF).
|
and "c" for sse-c encryption. More than one encryption option can be set, delimited by ";". Objects are encrypted at the gateway and the gateway also does a pass-through to backend. Note that in the case of SSE-C encryption, gateway derives a unique SSE-C key for pass through from the SSE-C client key using a key derivation function (KDF).
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -sSL --tlsv1.2 \
|
||||||
|
-O 'https://raw.githubusercontent.com/minio/kes/master/root.key' \
|
||||||
|
-O 'https://raw.githubusercontent.com/minio/kes/master/root.cert'
|
||||||
|
```
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export MINIO_GATEWAY_SSE="s3;c"
|
export MINIO_GATEWAY_SSE="s3;c"
|
||||||
export MINIO_KMS_VAULT_APPROLE_ID=9b56cc08-8258-45d5-24a3-679876769126
|
export MINIO_KMS_KES_ENDPOINT=https://play.min.io:7373
|
||||||
export MINIO_KMS_VAULT_APPROLE_SECRET=4e30c52f-13e4-a6f5-0763-d50e8cb4321f
|
export MINIO_KMS_KES_KEY_FILE=root.key
|
||||||
export MINIO_KMS_VAULT_ENDPOINT=https://vault-endpoint-ip:8200
|
export MINIO_KMS_KES_CERT_FILE=root.cert
|
||||||
export MINIO_KMS_VAULT_KEY_NAME=my-minio-key
|
export MINIO_KMS_KES_KEY_NAME=my-minio-key
|
||||||
export MINIO_KMS_VAULT_AUTH_TYPE=approle
|
|
||||||
minio gateway s3
|
minio gateway s3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -186,6 +186,12 @@ func IsNetworkOrHostDown(err error, expectTimeouts bool) bool {
|
|||||||
case strings.Contains(err.Error(), "connection timed out"):
|
case strings.Contains(err.Error(), "connection timed out"):
|
||||||
// If err is a net.Dial timeout.
|
// If err is a net.Dial timeout.
|
||||||
return true
|
return true
|
||||||
|
case strings.Contains(err.Error(), "connection reset by peer"):
|
||||||
|
// IF err is a peer reset on a socket.
|
||||||
|
return true
|
||||||
|
case strings.Contains(err.Error(), "broken pipe"):
|
||||||
|
// IF err is a broken pipe on a socket.
|
||||||
|
return true
|
||||||
case strings.Contains(strings.ToLower(err.Error()), "503 service unavailable"):
|
case strings.Contains(strings.ToLower(err.Error()), "503 service unavailable"):
|
||||||
// Denial errors
|
// Denial errors
|
||||||
return true
|
return true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user