1. Giới thiệu

Khi sử dụng database (DB), ta thường lo lắng về vấn đề bảo mật của nó. Một trong các vấn đề đó là làm sao để quản lý password của DB một cách hiệu quả và bảo mật.

Khi làm việc với DB RDS trong AWS, bạn có thể cấu hình sử dụng AWS Secret Manager và AWS Lambda để tự động thay đổi password của DB sau một khoảng thời gian nhất định. Điều này làm giảm nguy cơ khi password bị lộ ra ngoài, vì password được tự động thay đổi theo thời gian nên hacker sẽ bị hạn chế khi biết được password cũ.

Khi sử dụng cấu hình trên, bạn sẽ không fix cứng password của DB trong server hay application nữa. Nếu bạn đặt password cố định như vậy trong source code thì lúc password tự động thay đổi, bạn phải sửa lại tất cả các source code đang sử dụng password cũ. Để khắc phục điều đó, lúc sử dụng AWS Secret Manager quản lý password cho RDS DB, bạn sẽ sử dụng đoạn code do AWS Secret Manager cung cấp để lấy password. Lúc tạo AWS Secret Manager quản lý password cho RDS DB, bạn có thể lấy đoạn code này ở trong đó tương ứng với ngôn ngữ bạn sử dụng:

Sử dụng Secret Manager với RDS

 

2. Luồng dữ liệu khi muốn kết nối tới RDS DB

Lúc server của bạn muốn kết nối tới RDS sẽ thực hiện các bước sau:

  • Server sẽ request tới AWS Secret Manager để lấy password của RDS.
  • Server sẽ sử dụng password đó để truy cập tới RDS.

Chính vì thế server của bạn ngoài việc có thể kết nối tới RDS, cũng phải kết nối được tới AWS Secret Manager. Bạn có thể cho server này request tới AWS Secret Manager thông qua internet hoặc có thể sử dụng VPC endpoint để kết nối tới AWS Secret Manager mà không cần đi ra ngoài internet:

kết nối server tới secret manager aws

3. Luồng dữ liệu khi thay đổi password của DB

Sau một khoảng thời gian nhất định, lambda sẽ thực hiện các bước sau để thay đổi password cho DB:

  • Lambda request tới Secret Manager để lấy password hiện tại.
  • Lambda sử dụng passowrd hiện tại để login thử vào DB.
  • Lambda put password mới tới Secret Manager với trạng thái là AWSPENDING.
  • Lambda request tới RDS và thay password cũ bằng password mới.
  • Lambda login thử vào RDS bằng password mới.
  • Lambda request tới Secret Manager để set trạng thái của password mới từ AWSPENDING thành AWSCURRENT. Đồng thời set AWS CURRENT cũ thành AWSPREVIOUS.

 

Thứ tự lambda thay đổi password của RDS DB

 

Để thực hiện các bước trên, yêu cầu lambda phải kết nối tới được cả RDS và Secret Manager. Mọi chuyện sẽ đơn giản nếu RDS của bạn nằm trong public subnet và lambda kết nối được với internet để request tới Secret Manager. Nhưng sẽ khá phức tạp nếu RDS của bạn nằm trong private subnet.

Khi RDS của bạn nằm trong private subnet, bạn phải cấu hình lambda nằm trong cùng VPC với RDS để lambda kết nối được tới nó. Lúc sử dụng Secret Manager, AWS sẽ tạo một cloudformation và tạo lambda này cho bạn. Nhưng vấn đề ở chỗ khi lamba được gắn vào VPC thì nó sẽ không thể truy cập internet được nữa dẫn tới không thể truy cập tới Secret Manager. Lúc này bạn cần phải tạo NAT hoặc VPC endpoint cho Secret Manager.

Dưới đây mình sẽ trình bày cách tạo Secret Manager và cấu hình sử dụng lambda tự động thay đổi password của DB nằm trong private subnet.

 

4. Cách cấu hình

  • Bước 1: Đầu tiên bạn cần tạo một RDS, giả sử DB của mình được tạo với username là admin và password là 12345678. Lúc tạo DB bạn nhớ chọn publicity là No và chọn subnet là private subnet nhé.
  • Bước 2: Bạn có thể sử dụng docker hoặc EC2 để test thử kết nối tới DB vừa tạo:
$ yum install mysql
$ mysql -h your_db_endpoint -u admin -p
Enter password: 12345678

 

  • Bước 3: Vào Secret Manager và tạo Credentials for RDS database 

Tạo secret manager thay đổi password DB

Chú ý: User name và Password phải trùng với username và password hiện tại của DB 

Chọn DB tương ứng phía dưới rồi ấn Next:

Chọn DB trong secret manager

 

Ở Step 3, bạn giữ nguyên là Disable automatic rotation:

tạo secret manager

 

  • Bước 4: Sau khi tạo xong Secret Manager, bạn có thể lấy đoạn code trong đó để test thử kết nối tới DB. Bạn có thể bỏ qua bước này.
  • Bước 5: Trong Secret Manager vừa tạo ở trên, bật Enable automic rotation lên: Chọn số ngày sẽ tự động thay password DB và nhập tên lambda function

Bật enable automatic rotation

 

Sau khi ấn Save, bạn vào CloudFormation để xem trạng thái hoặc xem có lỗi gì xảy ra không:

Check cloudFormation với secret manager

 

Sau khi trạng thái trên AWS Secret Manager thông báo thành công thì bạn vào Lambda để thấy được function được tạo. Bạn vào Configuration -> VPC sẽ thấy Lambda tự động được gắn vào VPC của RDS và tự động gắn vào các subnet, mình có một private subnet và một public subnet nên Lambda gắn vào cả 2:

Gắn VPC vào lambda

 

Tiếp theo bạn vào Cloudwatch để xem log của Lambda function trên, bạn sẽ thấy log báo là timeout nghĩa là quá trình rotation đã thất bại:

Timeout của lambda rotate rds password

Lý do timeout là vì Lambda của bạn hiện đang được gắn vào VPC nên mặc định sẽ không thể kết nối tới internet, dẫn tới không thể kết nối tới Secret Manager.

Chú ý: Dù Lambda có gắn vào public subnet đi chăng nữa, nó cũng không thể kết nối với internet vì lambda không có public IP.

Để Lambda có thể kết nối tới Secret Manager, bạn phải tạo NAT hoặc VPC endpoint. Dưới đây mình trình bày cách tạo VPC endpoint cho service Secret Manager.

(Xem thêm về NAT tại https://blog.daovanhung.com/post/su-dung-nat-trong-aws)

 

  • Bước 6: Tạo VPC endpoint cho service Secret Manager

Chú ý: Lúc tạo VPC endpoint bạn chọn subnet nhưng VPC endpoint gắn với VPC chứ không gắn với subnet, mình đã thử các trường hợp dưới đây và đều thành công:

  • VPC endpoint gắn với public subnet, lambda gắn với public subnet.
  • VPC endpoint gắn với private subnet, lambda gắn với private subnet.
  • VPC endpoint gắn với public subnet, lambda gắn với private subnet.
  • VPC endpoint gắn với private subnet, lambda gắn với public subnet.

Vào VPC -> Endpoints và tạo VPC endpoint:

Tạo VPC endpoint cho secret manager

Để mặc định là bật Enable DNS Name nhé.

 

  • Bước 7: Sau khi trạng thái của VPC endpoint thành Available, bạn vào lại Secret Manager và ấn Rotate Secret Immediately, vào Cloudwatch đợi một lúc để thấy kết quả thành công:

Cloudwatch với secret manager

 

  • Bước 8: Vào lại Secret Manager, ấn Retrive Secret Value để lấy password vừa được thay:

Lấy password trong secret manager

 

Sử dụng password này và login thử vào DB:

$ mysql -h hungdv-db.cshr0pbs5nmx.ap-northeast-1.rds.amazonaws.com -u admin -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 29
Server version: 8.0.20 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> 

 

Như thế là xong, từ giờ password DB của bạn sẽ được thay đổi sau mỗi 30 ngày, application của bạn sử dụng đoạn code của Secret Manager để lấy password mới nên bạn không cần phải đặt password vào source code nữa.

 

Linh tham khảo:

https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets-one-user-one-password.html