Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Invalid Sigv4 on requests without a body using AWS SDK v1 #492

Closed
rblcoder opened this issue Mar 23, 2024 · 9 comments · Fixed by #496
Closed

[BUG] Invalid Sigv4 on requests without a body using AWS SDK v1 #492

rblcoder opened this issue Mar 23, 2024 · 9 comments · Fixed by #496
Labels
bug Something isn't working

Comments

@rblcoder
Copy link

What is the bug?

Getting Error: status: [403 Forbidden] exit status 1 when connecting to OpenSearch using AWS SDK v1

How can one reproduce the bug?

The following code gives Error: status: [403 Forbidden]
exit status 1

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/aws/aws-sdk-go/aws/session"
	requestsigner "github.com/opensearch-project/opensearch-go/v3/signer/aws"

	"github.com/opensearch-project/opensearch-go/v3"
	"github.com/opensearch-project/opensearch-go/v3/opensearchapi"
)

const IndexName = "go-test-index1"

func main() {
	if err := example(); err != nil {
		fmt.Println(fmt.Sprintf("Error: %s", err))
		os.Exit(1)
	}
}

const endpoint = "endpoint url" // e.g. https://opensearch-domain.region.com

func example() error {
	// Create an AWS request Signer and load AWS configuration using default config folder or env vars.
	// See https://docs.aws.amazon.com/opensearch-service/latest/developerguide/request-signing.html#request-signing-go
	signer, err := requestsigner.NewSignerWithService(
		session.Options{Profile: "default"},
		requestsigner.OpenSearchService, // Use requestsigner.OpenSearchServerless for Amazon OpenSearch Serverless.
	)
	if err != nil {
		return err
	}
	// Create an opensearch client and use the request-signer.
	client, err := opensearchapi.NewClient(
		opensearchapi.Config{
			Client: opensearch.Config{
				Addresses: []string{endpoint},
				Signer:    signer,
			},
		},
	)
	if err != nil {
		return err
	}

	ctx := context.Background()

	ping, err := client.Ping(ctx, nil)
	if err != nil {
		return err
	}

	fmt.Println(ping)

	return nil
}

What is the expected behavior?

Connection should be successful

What is your host/environment?

Distributor ID: Debian
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
Codename: bullseye

Do you have any screenshots?

golangawssdkopensearch

Do you have any additional context?

I am able to connect using AWS SDK v1 with the same credentials.

@rblcoder rblcoder added bug Something isn't working untriaged labels Mar 23, 2024
@dblock
Copy link
Member

dblock commented Mar 25, 2024

I don't see any region specified, maybe you're just missing that?

Can you try running my working sample in https://github.com/dblock/opensearch-go-client-demo, does it work or cause the same error?

@rblcoder
Copy link
Author

opensearch-go-client-demo uses AWS SDK V2. The code with AWS SDK v2 works perfectly. I was trying to get the code work for AWS SDK v1.
I tried adding region and am getting the same error.

package main

import (
   "context"
   "fmt"
   "os"

   "github.com/aws/aws-sdk-go/aws"
   "github.com/aws/aws-sdk-go/aws/session"
   requestsigner "github.com/opensearch-project/opensearch-go/v3/signer/aws"

   "github.com/opensearch-project/opensearch-go/v3"
   "github.com/opensearch-project/opensearch-go/v3/opensearchapi"
)

const IndexName = "go-test-index1"

func main() {
   if err := example(); err != nil {
   	fmt.Println(fmt.Sprintf("Error: %s", err))
   	os.Exit(1)
   }
}

const endpoint = "url" // e.g. https://opensearch-domain.region.com

func example() error {
   // Create an AWS request Signer and load AWS configuration using default config folder or env vars.
   // See https://docs.aws.amazon.com/opensearch-service/latest/developerguide/request-signing.html#request-signing-go
   signer, err := requestsigner.NewSignerWithService(
   	session.Options{Profile: "default",
   		Config: aws.Config{
   			Region: aws.String("us-east-1"),
   		}},
   	requestsigner.OpenSearchService, // Use requestsigner.OpenSearchServerless for Amazon OpenSearch Serverless.
   )
   if err != nil {
   	return err
   }
   // Create an opensearch client and use the request-signer.
   client, err := opensearchapi.NewClient(
   	opensearchapi.Config{
   		Client: opensearch.Config{
   			Addresses: []string{endpoint},
   			Signer:    signer,
   		},
   	},
   )
   if err != nil {
   	return err
   }

   ctx := context.Background()

   ping, err := client.Ping(ctx, nil)
   if err != nil {
   	return err
   }

   fmt.Println(ping)

   return nil
}

@dblock
Copy link
Member

dblock commented Mar 26, 2024

I can confirm that it doesn't work for requests without a body (works for PUT, POST, etc., but not GET or DELETE). Made a v1 version in https://github.com/dblock/opensearch-go-client-demo/tree/aws-sdk-v1/aws-sdk-v1 and I get an invalid signature for those as well.

It's probably something we broke in the signer in the way empty body is handled, or something that changed on the server. Maybe you can help debug/fix?

@dblock dblock removed the untriaged label Mar 26, 2024
@dblock dblock changed the title [BUG] Getting Error: status: [403 Forbidden] exit status 1 when connecting to OpenSearch using AWS SDK v1 [BUG] Invalid Sigv4 on requests without a body using AWS SDK v1 Mar 26, 2024
@dblock
Copy link
Member

dblock commented Mar 26, 2024

Fix in #496. Looks like this was introduced in efe6d62 when serverless support was added, I bet the empty body signature is required, but not checked in serverless on GET/DELETE, cc: @harrisonhjones.

I tested with AWS SDK v1 with https://github.com/dblock/opensearch-go-client-demo/tree/aws-sdk-v1 against both managed and serverless by adding replace "github.com/opensearch-project/opensearch-go/v3" => "...../opensearch-go/dblock-opensearch-go" in go.mod.

@rblcoder
Copy link
Author

Thank you @dblock , I was trying to understand the code and it was taking time.

I can confirm that it doesn't work for requests without a body (works for PUT, POST, etc., but not GET or DELETE). Made a v1 version in https://github.com/dblock/opensearch-go-client-demo/tree/aws-sdk-v1/aws-sdk-v1 and I get an invalid signature for those as well.

It's probably something we broke in the signer in the way empty body is handled, or something that changed on the server. Maybe you can help debug/fix?

@dblock
Copy link
Member

dblock commented Mar 27, 2024

@rblcoder My PR got merged, can you try the version from HEAD? We can cut a release if it works well for you.

@rblcoder
Copy link
Author

@dblock tested on the version from HEAD, works perfectly now.

@harrisonhjones
Copy link
Contributor

Sorry for the bug on my end folks. Thanks for fixing it!

@dblock
Copy link
Member

dblock commented Mar 28, 2024

Sorry for the bug on my end folks. Thanks for fixing it!

No stress! Looks like AOSS was not enforcing the header check (I suppose it makes sense because SSL is required), so this took a while to get noticed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants