使用开放连接在 AWS 中轮换 RDS 机密

Rotating RDS secrets in AWS with open connections

如果在与 RDS 的连接当前处于打开状态时轮换机密,该连接是否仍然能够查询数据库,还是会变为非活动状态?

如果您轮换用户帐户的密码,用户将无法访问数据库,直到他们获取新密码。

一个常见的策略是拥有两个用户帐户(user1 和 user2)并按交错的时间表轮换密码。当客户端检测到 user2 并开始使用它时,user1 的凭据仍然有效。请注意,要使其生效,客户端必须定期检查更新的凭据。

https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets-two-users.html

大多数数据库,包括 RDS 中的所有数据库,在您更改密码时不会关闭 sessions/connections(例如,请参阅此 answer for oracle)。终止会话需要明确的终止命令。

如果您使用 Java 和连接池管理器,您可以使用 AWS 提供的 JDBC wrapper 在需要重新建立连接时自动获取最新密码。

我可以通过以下方式进行测试:

  • 启动 MySQL RDS 实例
  • 在 Secrets Manager 中存储主密码
  • 通过控制台设置单用户轮换
  • 使用 MySQL CLI
  • 连接到数据库
  • 通过查询验证连接
  • 通过从 CLI 启动子 shell 来保持连接打开
  • 转储当前密码
  • 开始异步轮换并稍等
  • 通过转储新密码验证轮换
  • 通过退出 subshel​​l
  • 返回 CLI 中现有的 MySQL 连接
  • 运行另一个查询

    $ mysql -h testdb -Dmysql -u root -p$(aws --region us-east-2 secretsmanager get-secret-value --secret-id testdb-root --query SecretString --output text | jq -r '.password')
       ...
    mysql> select user from user;
    +-----------+
    | user      |
    +-----------+
    | root      |
    | mysql.sys |
    | rdsadmin  |
    +-----------+
    3 rows in set (0.05 sec)

    mysql> \! bash
    $ # Show current password
    $ aws --region us-east-2 secretsmanager get-secret-value --secret-id testdb-root --query SecretString --output text | jq -r '.password'
    3%c70'-e9s<Dy5ecX-(0mV%&E6Y[<jnJ
    $ aws --region us-east-2 secretsmanager rotate-secret --secret-id testdb-root
       ...
    $ sleep 60 # Give rotation time to complete
    $ aws --region us-east-2 secretsmanager get-secret-value --secret-id testdb-root --query SecretString --output text | jq -r '.password'
    .z,B{,P]jE~pr3?0mZ5H,6rJi;aXrQVO
    $ exit
    mysql> select user from user;
    +-----------+
    | user      |
    +-----------+
    | root      |
    | mysql.sys |
    | rdsadmin  |
    +-----------+
    3 rows in set (0.05 sec)

来自 Secret Manager documentation:

Secrets Manager can automatically rotate your secret for you on a specified schedule. You can rotate credentials without interrupting the service if you choose to store a complete set of credentials for a user or account, instead of only the password. If you change or rotate only the password, then the old password immediately becomes obsolete, and clients must immediately start using the new password or fail. If you can instead create a new user with a new password, or at least alternate between two users, then the old user and password can continue to operate side by side with the new one, until you choose to deprecate the old one. This gives you a window of time when all of your clients can continue to work while you test and validate the new credentials. After your new credentials pass testing, you commit all of your clients to using the new credentials and remove the old credentials.