0

I have created a java client to upload files to S3 buckets using the AWS SDK. It works perfectly fine.

Now I am trying to do the same thing with Nginx in the middle. As in all the request from my client will pass through NGINX.

I new to Nginx so somehow compiled this nginx.conf

events {}
http {

  server {
    listen 9091;

    location / {
      proxy_pass http://bucket-name.s3.ap-south-1.amazonaws.com/;
    }
  }
}

This config gives the below exception:

Caused by: com.amazonaws.services.s3.model.AmazonS3Exception: The request signature we calculated does not match the signature you provided. Check your key and signing method. (Service: Amazon S3; Status Code: 403; Error Code: SignatureDoesNotMatch; Request ID: 7BB1301CCDE06B05; S3 Extended Request ID: qAVh3RMieyqgwOrzNeiMAVQyb9V59J0rThHYqnfzUibZxqDIzzMUPI8SdWLCa9tL15YyekI2ukQ=), S3 Extended Request ID: qAVh3RMieyqgwOrzNeiMAVQyb9V59J0rThHYqnfzUibZxqDIzzMUPI8SdWLCa9tL15YyekI2ukQ=
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1799)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1383)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1359)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1139)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:796)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:764)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:738)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:698)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:680)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:544)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:524)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5052)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4998)
    at com.amazonaws.services.s3.AmazonS3Client.initiateMultipartUpload(AmazonS3Client.java:3574)... 19 more

I tried to tweak the configs but couldn't succeed.

halfer
  • 19,824
  • 17
  • 99
  • 186
Pratik
  • 144
  • 2
  • 12
  • Have you considered using [presigned URLs](https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObjectJavaSDK.html) to upload directly to S3 from the client? I'm trying to understand the need for Nginx in the middle – maafk Jun 01 '20 at 08:50
  • I have a requirement. I have written a retry logic that will retry if S3 is not available. For this, I have to write a test case. To replicate this scenario I want to use Nginx. So that I can interrupt connection by killing Nginx container. – Pratik Jun 01 '20 at 08:53

1 Answers1

0

You could try to set the Host header originally used by the client (Nginx rewrites this header by default), since AWS signature is also calculated from this field.

The Nginx config may look like (note the added proxy_set_header line):

events {}
http {

  server {
    listen 9091;

    location / {
      proxy_set_header       Host $http_host;
      proxy_pass http://bucket-name.s3.ap-south-1.amazonaws.com/;
    }
  }
}

This is based on the following answer from another StackOverflow problem: Nginx confg issue - couldn't connect to S3 compatible storage from NodeJS test program

George
  • 91
  • 1
  • 3