You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法通过IAM用户连接RDS数据库:合规权限仍报错求助

Troubleshooting IAM Authentication Failure for RDS with Golang

Let's walk through the common issues that could be causing your 1045 Access denied error when trying to connect to RDS using IAM authentication. Even if your IAM policy looks correct, there are several easy-to-miss steps that often trigger this problem.


1. Verify IAM Database Authentication is Enabled on Your RDS Instance

First things first: if your RDS instance doesn't have IAM database authentication turned on, no amount of correct IAM policies will work.

  • Go to the AWS RDS Console, select your instance
  • Check the Configuration tab for the "IAM database authentication" setting
  • Ensure it's set to Enabled (you may need to modify the instance if it's not)

2. Validate Your IAM Policy's Resource ARN

Your policy uses the right format, but double-check the placeholder values are 100% accurate:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["rds-db:connect"],
      "Resource": ["arn:aws:rds-db:REGION:ACCOUNT-ID:USER:dbi-resource-id/master"]
    }
  ]
}
  • REGION: Must match your RDS instance's region (e.g., us-east-1, avoid typos like useast-1)
  • ACCOUNT-ID: Your 12-digit AWS account ID (no hyphens)
  • dbi-resource-id: Find this in your RDS instance's Details tab under "Resource ID", or run aws rds describe-db-instances --query "DBInstances[*].DbiResourceId"
  • master: Ensure this matches your MySQL username exactly (MySQL is case-sensitive by default)

Test if the policy works using the AWS CLI to simulate the action:

aws iam simulate-custom-policy \
  --policy-document file://rds-permission.json \
  --action-names rds-db:connect \
  --resource-arns arn:aws:rds-db:REGION:ACCOUNT-ID:USER:dbi-resource-id/master

Look for Allowed: true in the output to confirm the policy grants access.

3. Ensure Your MySQL User is Configured for IAM Authentication

Even with the right IAM permissions, your MySQL user master needs to be set up to use the AWS authentication plugin. Run these commands in your MySQL instance (use a regular password-based connection first):

-- Grant basic usage (adjust the database scope as needed)
GRANT USAGE ON *.* TO 'master'@'%' REQUIRE SSL;

-- Enable AWS IAM authentication for the user
ALTER USER 'master'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';

-- Flush privileges to apply changes immediately
FLUSH PRIVILEGES;

Note: @'%' allows connections from any IP; you can restrict this to your client's IP later, but keep it open for testing.

4. Fix Issues in Your Golang Code

Looking at your code, there are a couple of potential problems:

  • Duplicate TLS Config Registration: You register the custom TLS config twice, which can cause unexpected behavior. Combine these into one step.
  • InsecureSkipVerify: While this works for testing, it's better to use the RDS CA bundle properly instead of skipping verification.
  • Missing Connection Ping: sql.Open() only creates the connection pool, it doesn't test the connection—add a Ping() call to validate.

Here's an optimized version of your code:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "database/sql"
    "fmt"
    "io/ioutil"
    "log"
    "os"

    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/service/rdsutils"
    _ "github.com/go-sql-driver/mysql"
)

var (
    dbUser     = os.Getenv("DB_USER")
    dbEndpoint = os.Getenv("DB_ENDPOINT")
    awsRegion  = os.Getenv("AWS_REGION")
    dbPort     = os.Getenv("DB_PORT")
    dbName     = os.Getenv("DB_NAME")
)

func main() {
    // Load and validate AWS credentials
    awsCreds := credentials.NewEnvCredentials()
    _, err := awsCreds.Get()
    if err != nil {
        log.Fatalf("Failed to load AWS credentials: %v", err)
    }

    // Build IAM authentication token
    authToken, err := rdsutils.BuildAuthToken(dbEndpoint, awsRegion, dbUser, awsCreds)
    if err != nil {
        log.Fatalf("Failed to build auth token: %v", err)
    }

    // Load RDS CA certificate bundle
    rootCertPool := x509.NewCertPool()
    pemBytes, err := ioutil.ReadFile("rds-ca-bundle.pem")
    if err != nil {
        log.Fatalf("Could not read RDS CA file: %v", err)
    }
    if !rootCertPool.AppendCertsFromPEM(pemBytes) {
        log.Fatal("Failed to add RDS CA certificate to pool")
    }

    // Register TLS config once
    err = mysql.RegisterTLSConfig("custom", &tls.Config{
        RootCAs: rootCertPool,
        // Disable InsecureSkipVerify in production!
        InsecureSkipVerify: false,
    })
    if err != nil {
        log.Fatalf("Failed to register TLS config: %v", err)
    }

    // Build MySQL connection string
    dnsStr := fmt.Sprintf(
        "%s:%s@tcp(%s:%s)/%s?allowCleartextPasswords=true&tls=custom",
        dbUser, authToken, dbEndpoint, dbPort, dbName,
    )

    // Open connection pool and verify connection
    db, err := sql.Open("mysql", dnsStr)
    if err != nil {
        log.Fatalf("Failed to open connection pool: %v", err)
    }
    defer db.Close()

    // Ping to confirm the connection works
    if err := db.Ping(); err != nil {
        log.Fatalf("Failed to connect to RDS: %v", err)
    }

    fmt.Println("Successfully connected to RDS using IAM authentication!")
}

5. Double-Check Network and Security Group Settings

While your error is an authentication issue (not a connection timeout), it's worth confirming:

  • Your RDS security group allows inbound traffic on port 3306 from your client's IP
  • Your client has internet access to the RDS instance (or is in the same VPC with proper routing)

Work through these steps in order—most likely, the issue is either missing the RDS IAM authentication toggle, incorrect MySQL user configuration, or a typo in your IAM policy's resource ARN.

内容的提问来源于stack exchange,提问作者thelearner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:39:44