连接启用IAM认证的AWS Neptune实例时触发Bad Handshake错误求助
AWS Neptune启用IAM认证后出现Websocket Bad Handshake问题解决
问题背景
- 已启用IAM认证的AWS Neptune实例,关闭IAM认证时可正常执行CRUD操作
- 启用IAM认证后,Lambda函数调用Neptune时出现
websocket: bad handshake错误 - Lambda函数已配置Neptune全权限,且已尝试对请求进行签名,但认证仍失败
错误日志
Failed to instantiate the new connection; setting connection state to closed.
Error creating new connection for connection pool: websocket: bad handshake
'E0104: no successful connections could be made: websocket: bad handshake'
问题代码
package main import ( "fmt" "log" "net/http" "os" "time" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver" "github.com/aws/aws-sdk-go/aws/session" v4 "github.com/aws/aws-sdk-go/aws/signer/v4" ) func main() { lambda.Start(lambdaHandler) } func lambdaHandler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { driverConn, g = connect() result, err = g.AddV("User").Property("userId", "Check").Next() if err != nil { fmt.Println(err) } } func connect() { awsSess, err := session.NewSesionWithOptions(session.Options{ SharedCondfigState: session.SharedConfigEnable, }), if err != nil { log.Fatalf("Failed to creating session: %s", err) } db_endpoint := os.Genenv("DB_ENDPOINT") connString := "wss://" +db_endpoint+":8182/gremlin" // Signing Request req, _ := http.NewRequest(http.MethodGet, connString, nil) signer := v4.NewSigner(awsSess.Config.Credentials) headerToUse, err := signer.Sign(req, nil, "neptune", *awsSess.Config.Region, time.Now()) driverRemoteConnection, err := gremlingo.NewDriverRemoteConnection(connString, func(settings *gremlingo.driverRemoteConnectionSettings) { settings.TraversalSource = "g" settings.AuthInfo.Header = headerToUse }) return driverRemoteConnection, traversalSource(driverRemoteConnection) } func traversalSource(driverConn *gremlingo.DriverRemoteConnection) *gremlingo.GraphTraversalSource { return gremlingo.Traversal_().WithRemote(driverConn) }
解决步骤
1. 修正代码拼写与语法错误
代码中存在多处拼写和语法问题,会导致签名或连接逻辑异常:
session.NewSesionWithOptions→ 修正为session.NewSessionWithOptionsSharedCondfigState→ 修正为SharedConfigStateos.Genenv→ 修正为os.Getenvconnect()函数缺少返回类型声明,需定义为:func connect() (*gremlingo.DriverRemoteConnection, *gremlingo.GraphTraversalSource, error)(同时需处理错误返回)lambdaHandler中变量未声明,改为driverConn, g := connect()
2. 修正AWS V4签名逻辑
Neptune的IAM签名服务名称应为neptune-db,而非neptune,且签名操作会直接修改请求Header,无需单独返回Header:
// 修正签名部分代码 req, err := http.NewRequest(http.MethodGet, connString, nil) if err != nil { log.Fatalf("Failed to create request: %s", err) } signer := v4.NewSigner(awsSess.Config.Credentials) // 服务名称改为neptune-db,Sign方法直接修改req.Header _, err = signer.Sign(req, nil, "neptune-db", *awsSess.Config.Region, time.Now()) if err != nil { log.Fatalf("Failed to sign request: %s", err) }
3. 调整Gremlin驱动的Header传递方式
Gremlin Go驱动的AuthInfo.Header并非用于传递AWS签名Header,需使用CustomHeaders字段传递签名后的完整Header:
driverRemoteConnection, err := gremlingo.NewDriverRemoteConnection(connString, func(settings *gremlingo.DriverRemoteConnectionSettings) { settings.TraversalSource = "g" // 将签名后的请求Header设置为驱动自定义Header settings.CustomHeaders = req.Header })
4. 验证IAM权限配置
确认Lambda执行角色的权限策略正确,资源ARN需匹配Neptune集群:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "neptune-db:*", "Resource": "arn:aws:neptune-db:你的区域:你的账号ID:cluster/你的集群ID/*" } ] }
同时检查角色信任关系,确保允许lambda.amazonaws.com扮演该角色。
内容的提问来源于stack exchange,提问作者Vijay_Neethipudi
相关产品推荐
相关产品推荐

