MongoDB 서버는 보안을 위해 크게 다음과 같이 5가지 형태의 코어 기능을 제공한다.
형태 | 설명 |
인증 Authentication | |
권한 Authorization | |
암호화 Encryption | 데이터 필드 단위의 암호화와 데이터 파일을 DBMS 서버 하단에서 처리해주는 TDE 로 나눠볼수 있는데, 일반적으로 DBMS 에서 지원하는 방식은 TDE 방식이 많이 사용됨 현재 MongoDB 서버에서 TDE 는 엔터프라이즈 버전에서만 지원되는데, WiredTiger 스토리지 엔진의 플러그인 모듈로 직접 개발해 사용할 수 있음 ( 하단 설명 ) |
감사 Auditing | 어떤 사용자가 어떤 쿼리를 언제 실행했는지 모두 로그로 기록하여 DBMS 의 데이터에 문제가 발생했을 때 언제 누가 실행한 쿼리때문에 문제가 발생했는지 확인할 수 있음 |
데이터 관리 Data Governance | 보안적인 관점보다는 데이터의 일관성을 유지하기 위해 사용하는 도큐먼트 체크 기능을 의미 |
인증
MongoDB 자체 인증 방식과 외부 인증 방식 2개로 나뉜다.
외부 인증은 LDAP 나 액티브 디렉터리를 이용해서 사용자 인증을 받는 방식을 의미로 외부 인증 방식은 별도의 솔류션이 필요하고 장애의 범위가 넓어져 자주 사용되지는 않는다.
MongoDB 자체 인증 방식은 다시 '내부 인증'과 '사용자 인증'으로 나뉜다.
내부 인증
샤딩된 클러스터나 레플리카 셋에서 각 멤버는 데이터 동기화나 멤버들의 상태를 체크하기 위해 서로 통신이 필요하다.
이 때 각 멤버가 서로 인증하는 방식을 내부 인증이라고 표현한다.
내부 인증은 키 파일과 x.509 인증서 두 가지 방식을 선택해서 사용할 수 있다.
인증을 활성화하려면 서버의 설정 파일에서 인증과 관련된 옵션을 활성화해야 한다.
security.authorization 옵션을 enabled 로 설정하면 MongoDB 서버 간의 통신을 위핸 내부 인증뿐 아니라 사용자의 로그인을 위한 인증까지 모두 활성화된다.
이는 결국 내부 통신을 위한 인증과 사용자 인증을 개별로 설정할 수 없다는 의미다.
우선 enabled 로 설정하면 클러스터 멤버 간 통신을 위한 내부 인증과 관련된 clusterAuthMode 옵션과 keyFile 옵션이 필요하다.
clusterAuthMode 는 keyFile 과 x.509 둘로 나누어 볼 수 있는데 keyFile 은 평문의 단순 문자열로 구성된 비밀번호 파일을 MongoDB 서버가 내부 인증으로 사용하도록 하는 방식이다.
x.509 는 CA 의 인증을 받는 인증서를 이용해 클러스터 멤버 간 통신을 인증하는 방식이다.
keyFile 을 생성할 때 주의해야 할 점으로 다음과 같이 4가지 사항이 있다.
- keyFile 은 MongoDB 서버 프로세스가 읽을 수 있어야 한다.
- keyFile 의 접근 권한은 반드시 600 또는 700 으로 파일의 소유주만 접근할 수 있어야 한다.
- keyFile 의 내용에서 공백문자는 자동으로 무시된다.
- keyFile 은 6개 이상 1024 개 이항의 문자로 구성돼야 하며 BASE-64 셋에 포함되는 문자만 사용할 수 있다.
이렇게 준비된 키 파일은 클러스터에 참여하는 모든 MongoDB 서버와 MongoDB 라우터 서버가 공유해야 한다.
즉 모든 멤버의 서버에 복사해서 사용해야 한다.
사용자 인증
MongoDB 서버 자체적으로 지원하는 사용자 인증은 다른 DBMS 와 같이 아이디/패스워드 기반의 인증을 사용하는데 MongoDB 서버는 인증 데이터베이스 정보를 추가로 더 필요로 한다.
MongoDB 서버에서는 사용자를 생성할 때 반드시 특정 데이터베이스로 이동해서 생성해야 하는데, 이 때 데이터베이스를 인증 데이터베이스라고 한다.
물론 하나의 사용자 계정이 여러 다른 데이터베이스에 대해 권한을 가질 수는 있지만, 인증 데이터베이스는 사용자 계정으로 로그인할 때 인증을 위한 데이터베이스이므로 하나만 가질 수 있다.
MongoDB 서버의 사용자 인증을 사용하려면 MongoDB 설정 파일에 아래의 내용을 활성화해야 한다.
security:
authorization: enabled
MongoDB 서버에서 사용자 계정을 생성할 때는 특정 데이터베이스로 이동하여 계정을 생성한다.
다음 예제에서 user 사용자 계정의 인증 데이터베이스는 mysns 데이터베이스가 되는것이다.
use mysns
db.createUser ({user:"user", pwd:"mypassword", roles:[ "readWrite" ]})
db.createUser 명령으로 사용자 계정을 생성하는데 roles 필드에는 user 계정이 mysns 데이터베이스에 대해 어떤 권한을 부여할 것인지 설정한다. MongoDB 서버의 사용자 계정은 인증 데이터가 달라지만 다른 계정으로 인식된다.
만약 2개의 사용자 계정의 이름과 비밀번호가 같다 하더라도 서로 다른 데이터베이스에 생성한다면 MongoDB 서버는 서로 다른 계정으로 인식한다.
만약 하나의 사용자 계정이 여러 데이터베이스에 대해 권한을 가지도록 하고자 한다면 다음과 같이 createUser 명령에 다른 데이터베이스에 대한 권한을 같이 설정하거나 db.grantRolesToUser 명령으로 권한을 추가해줘야 한다.
이렇게 생성된 사용자 계정의 비밀번호와 권한 정보는 인증 데이터베이스와 무관하게 admin 데이터베이스에 저장된다.
admin 데이터베이스의 system.users 컬렉션에 저장된 도큐먼트에 db 필드가 명시돼 있는데 이는 사용자 계정의 인증 데이터베이스를 의미한다.
credentials 필드에는 SCRAM-SHA-1 이 저장되는데 이는 해당 사용자 계정을 인증할 방식을 나타낸다.
MongoDB 서버가 자체적으로 지원하는 인증 방식을 사용하는 경우에는 다음 3가지 메커니즘을 사용할 수 있다.
- SCRAM-SHA-1 ( 기본값 )
- MONGODB-CR
- X.509 Certificate Authentication
권한
기존 RDBMS 서버의 권한은 각 실행 명령어 단위로 권한이 부여되는 경우가 많다.
MongoDB 서버의 권한은 명령과 권한이 1:1 관계가 아니다. 사용자가 실행할 수 있는 명령과는 별개로 액션이 정의되고, 이런 액션을 묶어서 역할을 정의한다.
그래서 실제 사용자가 사용하는 명령이 어떤 액션들로 구성되는지 알아야 명령을 위해 어떤 역할이 필요한지 식별할 수 있다.
액션
MongoDB 서버에서는 역할 기반의 권한 부여 방식을 사용하는데, 역할은 특정 리소스에 대해 액션을 미리 매핑해 둔 것이다.
MongoDB 서버에서는 다음과 같이 액션이 이미 정의되어 있다.
액션 | MongoDB 명령 |
find | aggregate, count, dataSize, distinct, find, group , 등등 |
insert | insert, create, clone , 등등 |
remove | delete |
bypassDocumentValidation | aggregate, applyOps, clone, insert, update 등등 |
한 가지 주의해야 할 사항이 액션이 서버 명령들의 묶음이 아니다.
하나의 MongoDB 명령은 여러 개의 액션을 필요로 한다.
예를들어 Aggregate 명령은 find, insert, bypassDocumentValidation 을 필요로 한다.
내장된 역할
서버의 역할은 이렇게 정의된 액션을 묶어서 하나의 그룹으로 만든 것으로 볼 수 있다.
역할 | 액선 |
read | collStats, dbHash, find, 등등 |
readWrite | collStats, dbHash, dbStats, find, insert, remove 등등 |
dbAdmin | collStats, dbHash, find, cillCursors, listIndexes 등등 |
MongoDB 서버에서 사용자 계정을 생성하고 사용자별로 권한을 할당할 때는 다음 예제와 같이 액션의 모음인 역할을 설정해야 한다.
사용자 정의 역할
MongoDB 는 이미 많은 역할을 정의해서 사용자가 쉽게 선택해서 사용할 수 있도록 준비했다.
하지만 100 % 만족할 수 없을경우를 위해 사용자가 자신의 서비스나 요건에 맞게 새롱누 역할을 정의해서 사용할 수 있도록 기능을 제공한다.
사용자가 직접 정의하는 역할은 크게 2가지로 '전역 역할' 과 '데이터베이스 단위 역할' 이다.
admin 데이터베이스에서 생성한 역할은 전역적으로 모든 데이터베이스의 오브젝트에 대한 권한을 포함할 수 있지만
admin 이 외 데이터베이스에서 생성된 역할은 해당 데이터베이스의 오브젝트에 대한 권한만 설정할 수 있다.
역할은 db.createRole 명령으로 생성하며 생성된 사용자 역할에 새로운 액션을 추가하고 제거하는 작업은 db.grantPrivilegesToRole() 명령과 revokePrivilegesFromRole() 명령을 사용한다.
암호화
데이터 암호화 방식
DBMS 서버에서 데이터 암호화는 크게 응용 프로그램 수준의 암호화와 데이터베이스 서전 수준의 암호화로 나눠볼 수 있다.
응용 프로그램 수준의 암호화는 응용 프로그램을 개발하는 개발자가 직접 프로그램의 코드상에서 데이터를 암호화하고 복호화 하는 작업을 수행하므로 암호화와 관련된 지식이 필요할 수 있다.
하지만 익숙해지면 데이터베이스에 의존하지 않고 암호화/복호화 할 수 있기 때문에 개발 생산성이 더 높아질 수 있다.
따라서 DBMS 수준에서 복호화가 필요한 것이 아니라면 응용 프로그램에서 암호화하는 것이 더 쉬운 방법일 수 있다.
그러나 암호화된 데이터는 인덱스를 이용한 범위검색을 수행할 수 없다.
이렇게 인덱스로 검색이나 정렬 작업을 필요로 하는 경우를 위해 많은 DBMS 서버들이 TDE 기능을 제공하고 있다.
TDE 기능은 프로그램 코드로부터 투명하게 작동하며 실제 DBMS 서버의 내부적인 처리에서도 투명하게 작동한다.
MongoDB 서버의 TDE 는 WiredTiger 스토리지 엔진의 블록 캐시에서 디스크로 데이터 블록이 기록될 때 암호화해서 저장하고 블록 캐시가 디스크의 데이터 블록을 읽을 때 암호화를 해제해서 블록 캐시에 적재해둔다.
그래서 MongoDB 서버가 메모리상의 데이터를 읽고 변경할 때는 암호화와 관련된 작업이 전혀 필요하지 않다.
MongoDB TDE 구현
커뮤니티 버전의 MongoDB 서버에서는 데이터 파일 암호화 기능을 사용할 수가 없다.
다힝애 커뮤니티 버전의 MongoDB 서버에 내장된 WiredTiger 스토리지 엔진은 데이터 파일 암호화를 위한 인터페이스가 제공되고 있고 커뮤니티 버전에서 사용할 수 있다.
"TDE for wiredTiger storage engine" 이라는 제목으로 깃헙 사이트에 있다.
그런데 이건 MongoDB 에서 공식지원하는건 아니기 때문에 주의하는게 좋을 것 같다.
'Database > MongoDB' 카테고리의 다른 글
[MongoDB] 백업 및 복구(1) (0) | 2024.12.10 |
---|---|
[MongoDB] 실행 계획 및 쿼리 최적화(2) (0) | 2024.11.25 |
[MongoDB] 실행 계획 및 쿼리 최적화(1) (0) | 2024.11.18 |
[MongoDB] 쿼리 개발과 튜닝(1) (6) | 2024.10.06 |
[MongoDB] 데이터 모델링 (1) | 2024.09.19 |