MSSQL 데이터베이스 시크릿 엔진

MSSQL 데이터베이스 시크릿 엔진 (MSSQL database secrets engine)

데이터베이스 시크릿 엔진에서 Microsoft SQL Server 자격 증명을 동적으로 생성하는 mssql 플러그인을 다룹니다.

출처: 문서

본문

MSSQL은 데이터베이스 시크릿 엔진이 지원하는 플러그인 중 하나예요. 이 플러그인은 MSSQL 데이터베이스에 대해 설정된 역할을 기반으로 데이터베이스 자격 증명을 동적으로 생성합니다.

데이터베이스 시크릿 엔진 설정에 대한 자세한 내용은 데이터베이스 시크릿 엔진 문서를 참고하세요.

다음 권한은 최소 기능을 위해 플러그인에 필요해요. 데이터베이스 역할에 구성된 SQL에 따라 추가 권한이 필요할 수 있어요.

-- 로그인 만들기
CREATE LOGIN vault_login WITH PASSWORD = '<PASSWORD>';

-- 사용자 만들기
CREATE user vault_user for login vault_login;

-- 권한 부여
GRANT ALTER ANY LOGIN TO "vault_user";
GRANT ALTER ANY USER TO "vault_user";
GRANT ALTER ANY CONNECTION TO "vault_login";
GRANT VIEW ANY DEFINITION TO "vault_login";
GRANT VIEW SERVER STATE TO "vault_login";
GRANT VIEW DEFINITION TO "vault_user";
GRANT CONTROL ON SCHEMA::<SCHEMA> TO "vault_user";
EXEC sp_addrolemember "db_accessadmin", "vault_user";

기능 (Capabilities)

플러그인 이름 루트 자격 증명 회전 동적 역할 정적 역할 사용자명 커스터마이즈
mssql-database-plugin Yes Yes Yes Yes (1.7+)

설정 (Setup)

  1. 데이터베이스 시크릿 엔진이 아직 활성화되지 않았다면 활성화해요.
$ vault secrets enable database
Success! Enabled the database secrets engine at: database/

기본적으로 시크릿 엔진은 엔진 이름으로 활성화돼요. 다른 경로에 활성화하려면 -path 인자를 사용하면 됩니다.

  1. 적절한 플러그인과 연결 정보로 Vault를 구성해요.
$ vault write database/config/my-mssql-database \
    plugin_name=mssql-database-plugin \
    connection_url='sqlserver://{{username}}:{{password}}@localhost:1433' \
    allowed_roles="my-role" \
    username="vaultuser" \
    password="yourStrong(!)Password"

참고: 위 예제는 vaultuser라는 SQL 서버 사용자로 연결하는 것을 보여줘요. 하지만 vaultuser 사용자는 Active Directory 도메인의 일부인 Windows 인증 사용자일 수도 있어요. 예: DOMAIN\vaultuser.

이 경우 Vault에 "vaultuser" 사용자와 "yourStrong(!)Password" 비밀번호로 구성해 포트 1433의 "localhost" 인스턴스에 연결합니다. Vault가 vaultuser 로그인을 가질 필요는 없지만, 그 사용자는 로그인을 만들고 프로세스를 관리할 권한이 있어야 해요. 고정 서버 역할인 securityadminprocessadmin은 이러한 권한을 부여하는 내장 역할의 예시입니다. 또 그 사용자는 데이터베이스 사용자를 만들고 Vault가 관리하는 데이터베이스에서 권한을 부여할 권한도 있어야 해요. 고정 데이터베이스 역할인 db_accessadmindb_securityadmin은 이 권한을 부여하는 내장 역할의 예입니다.

  1. Vault의 이름을 데이터베이스 자격 증명을 만드는 SQL 문에 매핑하는 역할을 구성해요.
$ vault write database/roles/my-role \
    db_name=my-mssql-database \
    creation_statements="CREATE LOGIN [{{name}}] WITH PASSWORD = '{{password}}';\
        CREATE USER [{{name}}] FOR LOGIN [{{name}}];\
        GRANT SELECT ON SCHEMA::dbo TO [{{name}}];" \
    default_ttl="1h" \
    max_ttl="24h"
Success! Data written to: database/roles/my-role

주의하세요! revocation_statement가 제공되지 않으면 vault가 기본 폐기 절차를 실행합니다. 폐기 절차는 connection_url에 정의된 데이터베이스로 범위 지정된 메타데이터 쿼리를 사용해요. 문이 다른 데이터베이스에서 사용자를 만들면 Vault는 그 사용자를 자동으로 감지·제거할 수 없습니다. 더 큰 데이터베이스에서는 이로 인해 연결 타임아웃이 발생할 수 있어요. 이런 시나리오에서는 폐기 문을 지정해 주세요.

경고: ALTER ROLE ... ADD MEMBER ... 같은 작업의 경우 Vault는 스키마 수정(SCH-M) 락을 획득하는데, 이는 읽기 작업이 스키마 안정성 락(SCH-S)을 획득하므로 읽기를 포함한 모든 작업을 차단해요. 그 결과 ALTER ROLE ... ADD MEMBER ...를 사용한 자격 증명 회전은 데이터베이스에 일시적인 교착 상태(deadlock)를 일으킬 수 있습니다. 관련 내용은 Microsoft 문서를 참고하세요.

사용법 (Usage)

시크릿 엔진이 구성되고 사용자/머신이 적절한 권한을 가진 Vault 토큰을 가지면 자격 증명을 생성할 수 있어요.

  1. 역할 이름으로 /creds 엔드포인트를 읽어 새 자격 증명을 생성해요.
$ vault read database/creds/my-role
Key                Value
---                -----
lease_id           database/creds/my-role/2f6a614c-4aa2-7b19-24b9-ad944a8d4de6
lease_duration     1h
lease_renewable    true
password           wJKpk9kg-T1Ma7qQfS8y
username           v-vaultuser-my-role-r7kCtKGGr3eYQP1OGR6G-1602542258

Azure SQL 데이터베이스 예제

Azure SQL Database를 사용하는 완전한 예제입니다. Azure SQL Database의 데이터베이스는 포함된 데이터베이스(contained databases)이며 사용자에 대한 로그인을 만들지 않고 비밀번호를 사용자 자체와 직접 연결한다는 점에 주의하세요. 또한 동적 자격 증명을 생성하려는 각 Azure SQL 데이터베이스마다 별도의 연결과 역할이 필요합니다. 하나의 데이터베이스 백엔드 마운트를 모든 데이터베이스에 사용하거나, 각각에 별도의 마운트를 사용할 수 있어요. 이 예제에서는 데이터베이스 백엔드에 커스텀 경로를 사용합니다.

참고: Azure SQL 데이터베이스는 SQL 서버에 구성된 다른 인증 메커니즘을 사용할 수 있어요. Vault는 SQL 인증만 지원합니다. Azure AD 인증은 지원되지 않아요.

먼저 vault secrets enable -path=azuresql database로 azuresql 경로에 데이터베이스 백엔드를 마운트한 다음, "test-vault"라는 데이터베이스에 연결하는 "testvault"라는 연결을 구성하고 contained_db 필드를 설정해요.

참고: Windows vault 클라이언트를 cmd.exe로 사용한다면 연결 문자열의 단일 따옴표를 이중 따옴표로 바꾸세요. Windows cmd.exe는 단일 따옴표를 연속 문자열로 해석하지 않습니다.

$ vault write azuresql/config/testvault \
    plugin_name=mssql-database-plugin \
    connection_url='server=hashisqlserver.database.windows.net;port=1433;user id=admin;password=pAssw0rd;database=test-vault;app name=vault;' \
    contained_db=true \
    allowed_roles="test"

이제 "testvault" 연결과 함께 사용할 "test"라는 역할을 추가해요.

$ vault write azuresql/roles/test \
    db_name=testvault \
    creation_statements="CREATE USER [{{name}}] WITH PASSWORD = '{{password}}';" \
    revocation_statements="DROP USER IF EXISTS [{{name}}]" \
    default_ttl="1h" \
    max_ttl="24h"

이제 이 역할로 Azure SQL 데이터베이스 test-vault용 자격 증명을 동적으로 생성할 수 있어요.

$ vault read azuresql/creds/test
Key             Value
---             -----
lease_id        azuresql/creds/test/2e5b1e0b-a081-c7e1-5622-39f58e79a719
lease_duration  1h0m0s
lease_renewable true
password        cZ-BJy-SqO5tKwazAuUP
username        v-token-test-tr2t4x9pxvq1z8878s9s-1513446795

백엔드가 더 이상 필요 없으면 vault unmount azuresql로 마운트를 해제할 수 있어요. 이제 Azure SQL 데이터베이스에서 MSSQL Database Plugin을 사용할 수 있습니다.

Amazon RDS

MSSQL 플러그인은 Amazon RDS에서 실행되는 데이터베이스를 지원해요.

Vault 2.0.1부터 기본 폐기 프로세스는 커스텀 문 없이 Amazon RDS에서도 동작해요. 플러그인은 RDS가 지원하지 않는 sysadmin 역할 대신 표준 권한(VIEW ANY DEFINITION, VIEW SERVER STATE, VIEW DEFINITION)을 사용합니다.

폐기 동작을 커스터마이즈하려면 커스텀 폐기 문을 제공해요.

vault write database/roles/my-role revocation_statements="\
   USE my_database \
   IF EXISTS \
     (SELECT name \
      FROM sys.database_principals \
      WHERE name = N'{{name}}') \
   BEGIN \
     DROP USER [{{name}}] \
   END \

   IF EXISTS \
     (SELECT name \
      FROM master.sys.server_principals \
      WHERE name = N'{{name}}') \
   BEGIN \
     DROP LOGIN [{{name}}] \
   END"

가용성 그룹 고려사항 (Availability Group considerations)

Microsoft SQL Server 가용성 그룹은 서버 수준 로그인을 복제하지 않아요.

Microsoft SQL Server 가용성 그룹(AG)과 함께 Vault 데이터베이스 시크릿 엔진을 사용할 때 rotate-root 작업을 실행하면 데이터베이스 시크릿 엔진에 구성된 인스턴스의 로그인/사용자 비밀번호만 업데이트돼요. 그러면 가용성 그룹의 다른 인스턴스는 동기화되지 않은 상태로 남고, 장애 조치(failover)가 일어나면 인증 실패를 일으킬 수 있습니다.

Microsoft SQL Server 가용성 그룹(AG)을 사용한다면 고려할 다른 워크플로가 있어요.

  1. Microsoft SQL Server를 Active Directory 인증으로 구성하고, LDAP 시크릿 엔진으로 Active Directory 사용자 자격 증명을 관리해요. LDAP 자격 증명으로 가용성 그룹의 모든 인스턴스에 로그인할 수 있어요.
  2. 가용성 그룹의 모든 인스턴스에서 Vault 밖에서 데이터베이스 시크릿 엔진 구성의 로그인/사용자 비밀번호를 회전해요. 예를 들어 Terraform이나 Ansible을 사용해요. 비밀번호를 업데이트한 후 Vault 구성을 업데이트해요.

API

구성 가능한 전체 옵션 목록은 MSSQL 데이터베이스 플러그인 API 페이지에서 확인할 수 있어요.

데이터베이스 시크릿 엔진 HTTP API에 대한 자세한 내용은 데이터베이스 시크릿 엔진 API 페이지를 참고하세요.

더 알아보기 (Learn more)