::: IT인터넷 :::

MongoDB 권한과 역할 관리 방법

곰탱이푸우 2022. 8. 15. 08:20
MongoDB에서 권한과 역할을 생성하고 관리하는 방법에 대해 정리한다.
 
MongoDB의 특징과 주요 개념은 아래 포스팅을 참고한다.
MongoDB를 Docker로 설정하는 방법은 아래 포스팅을 참고한다.
 
본 포스팅은  MongoDB 공식 문서와 아래 문서를 참고하여 작성했다.
정말 깔끔하게 정리가 잘 되어 있으므로 해당 포스팅을 읽어볼 것을 권한다.
MongoDB의 공식 문서는 아래 사이트를 참고한다.

준비 사항

DB 명령어는 MongoDB Docker 컨테이너 내부에서 mongosh를 실행해서 진행한다.
 
Docker를 이용한 MongoDB 설정과 mongosh 실행 방법은 아래 포스팅을 참고한다.
 

역할 관리

MongoDB도 권한 관리는 역할 기반 관리 (Role-based Authorization Control)를 사용한다.
따라서 계정의 역할 별로 권한을 부여하고, 각 계정에 정의한 역할을 부여하는 방법으로 진행한다.
 
MongoDB의 역할 기반 관리에 대한 자세한 내용은 아래 기술 문서를 참고한다.
MongoDB는 기본적으로 접근 제어 기능이 비활성화 되어 있기 때문에 해당 기능을 활성화 해야 한다.
접근 제어 기능을 활성화 하는 방법은 계정 생성의 접근 제어 활성화 부분을 참고한다.
 

역할 조회

MongoDB에 정의 된 역할 목록 전체를 출력하는 명령어가 없다.
 
admin Database의 system.roles.roles 컬력션에 있지만 아래처럼 관리자 권한이 필요하다.
admin> db.system.roles.roles.find()
MongoServerError: not authorized on admin to execute command
{ find: "system.roles.roles", filter: {},
lsid: { id: UUID("9de4c872-9b46-48f2-868e-c90bd9083d74") }, $db: "admin" }
 
따라서 아래 문서에 정리 된 MongoDB의 기본 역할들에 대해 정리한다.
 

All-Database Roles

전체 Database에 대한 모든 권한을 가지고 있다.
구분
내용
readAnyDatabase
전체 Database 읽기 가능
readWriteAnyDatabase
전체 Database 읽기 쓰기 가능
userAdminAnyDatabase
전체 Database에서 역할과 사용자의 생성과 수정 가능
dbAdminAnyDatabase
전체 Database에서 스키마 작업 가능, 권한 부여 불가
local과 config 부분은 제외
 

User Roles

일반적인 사용자에게 부여되는 역할로 읽기는 모두 가능하고, 쓰기 권한에서 차이가 있다.
구분
내용
read
특정 Database 읽기 가능 (system Collection 제외)
readWrite
특정 Database 읽기 쓰기 가능 (system Collection 제외)
 

Administration Roles

관리자에게 요구 되는 권한이 부여될 때 사용되는 역할이다.
구분
내용
dbAdmin
indexing, gathering, statistics, 스키마 작업 등 수행 가능
사용자와 역할에 대한 권한 부여와 관리 불가
userAdmin
특정 DB의 사용자와 역할 생성과 수정 가능
superUser 생성 가능
dbOwner
readWrite + dbAdmin + userAdmin
 

Superuser Roles

모든 Database에 대한 권한을 자신에게 할당 할 수 있다.
구분
내용
root
userAdmin에 의해 생성 된 superUser 권한
admin Database에 dbOnwer 또는 userAdmin 권한이 부여 된 경우
userAdminAnyDatabase 권한이 부여 된 경우
 

기타

클러스터 관리, 백업과 복원 같은 역할도 존재한다.
역할 타입
구분
내용
Cluster Administration
Roles
clusterAdmin
클러스터에 대한 최대 권한 부여 가능
clusterManager + clusterMonitor + hostManager + dropDatabase
clusterManager
cluster에 대한 관리와 모니터링 가능
clusterMonitor
모니터링 목적의 read 권한만 가능
hostManager
각각의 서버에 대한 관리와 모니터링 가능
Backup and Restoration
Roles
backup
mongoduimp 등으로 backup 수행
restore
mongorestore 등으로 restore 수행
Internal Roles
__ system
해당 소유자가 Database의 모든 개체에 조치를 취할 수 있는 내부 권한
사용 금지 (별도 사용자 정의 역할 생성 권장)
 
 

역할 생성

MongoDB에 사용자 정의 역할을 생성한다.
이미 기본으로 정의 되어 있는 역할이 상당수 정의 되어 있어 새롭게 역할을 정의하는 일은 많지 않다.
주로 필요에 따라 기본으로 제공되는 역할들을 조합해야 할 때 사용한다.
 

db.createRole

특정 Database에서 역할을 생성한다.
권한을 지정하거나 다른 역할을 상속 받아 지정할 수 있다.
> db.createRole(role, writeConcern)
 
role은 키와 값으로 구성 된 Document 형태이며, 구성은 다음과 같다.
구분
유형
내용
role
string
생성할 Role의 이름
privileges
array
부여할 역할 목록 (없으면 빈 배열 사용)
roles
array
상속하는 역할 목록 (없으면 빈 배열 사용)
authenticationRestrictions
array
Optional, 계정의 인증 제한 표시 여부
 
role로 전달하는 Document의 형식은 다음과 같다.
{
  role: "<name>",
  privileges: [
    { resource: { <resource> }, actions: [ "<action>", ... ] },
    ...
  ],
  roles: [
    { role: "<role>", db: "<database>" } | "<role>",
      ...
  ],
  authenticationRestrictions: [
    {
      clientSource: ["<IP>" | "<CIDR range>", ...],
      serverAddress: ["<IP>" | "<CIDR range>", ...]
    },
    ...
  ]
}
 
사용자 정의 권한을 생성하는 예제는 다음과 같다.
> use admin
> db.createRole(
  {
    role: "myClusterwideAdmin",
    privileges: [
      { resource: { cluster: true }, actions: [ "addShard" ] },
      { resource: { db: "config", collection: "" }, actions: [ "find", "update", "insert", "remove" ] },
      { resource: { db: "users", collection: "usersCollection" }, actions: [ "update", "insert", "remove" ] },
      { resource: { db: "", collection: "" }, actions: [ "find" ] }
    ],
    roles: [ { role: "read", db: "admin" } ]
  },
  { w: "majority" , wtimeout: 5000 }
)
 
자세한 내용은 아래 기술 문서를 참고한다.
 

db.rolesInfo

사용자가 정의한 역할에 대한 정보를 출력한다.
시스템에 정의 된 기본 역할 정보는 출력되지 않는다.
 
사용자 정의 역할의 전체 목록 출력은 아래와 같이 실행한다.
> db.runCommand("rolesInfo")
{
  roles: [
    {
      _id: 'admin.myClusterwideAdmin',
      role: 'myClusterwideAdmin',
      db: 'admin',
      roles: [ { role: 'read', db: 'admin' } ],
      isBuiltin: false,
      inheritedRoles: [ { role: 'read', db: 'admin' } ]
    }
  ],
  ok: 1
}
 
특정 사용자 정의 역할의 세부 내용만 출력하려면 아래와 같이 실행한다.
> db.runCommand({ rolesInfo: "myClusterwideAdmin" })
{
  roles: [
    {
      _id: 'admin.myClusterwideAdmin',
      role: 'myClusterwideAdmin',
      db: 'admin',
      roles: [ { role: 'read', db: 'admin' } ],
      inheritedRoles: [ { role: 'read', db: 'admin' } ],
      isBuiltin: false
    }
  ],
  ok: 1
}
 
자세한 내용은 아래 기술 문서를 참고한다.
 

역할 수정

사용자가 정의한 역할에 대한 정보를 수정할 때 사용한다.
시스템에 정의 된 기본 역할 정보는 포함되지 않는다.
 

db.updateRole

생성 되어 있는 사용자 정의 역할을 수정할 때 사용한다.
 
기본 형식은 다음과 같다.
> db.updateRole(rolename, update, writeConcern)
 
rolename은 수정할 역할의 이름을 의미하며, 해당 역할이 존재하지 않으면 오류를 반환한다.
> db.updateRole("inventoryControl", { ...생략... } )
MongoServerError: Could not find role: inventoryControl@admin
 
update는 키와 값으로 구성 된 Document 형태의 수정할 역할 정보이며 구성은 다음과 같다.
구분
유형
내용
privileges
array
부여할 역할 목록 (없으면 빈 배열 사용)
roles
array
상속하는 역할 목록 (없으면 빈 배열 사용)
authenticationRestrictions
array
Optional, 계정의 인증 제한 표시 여부
 
예제 코드는 다음과 같다.
> use products
> db.updateRole("inventoryControl",
  {
    privileges: [
      {
        resource: { db:"products", collection:"clothing" },
        actions: [ "update", "createCollection", "createIndex"]
      }
    ],
    roles: [ { role: "read", db: "products" } ]
  },
  { w:"majority" }
)
 
자세한 내용은 아래 기술 문서를 참고한다.
 
db.grantPrivilegesToRole
이미 생성 된 사용자 정의 역할에 추가 권한을 부여한다.
 
기본 형식은 다음과 같다.
> db.grantPrivilegesToRole(rolename, privileges, writeConcern)
 
privileges는 역할에 추가할 권한을 의미하며 array 타입이다.
 
사용 예제는 다음과 같다.
> use products
> db.grantPrivilegesToRole("inventoryCntrl01",
  [
    { resource: { db: "products", collection: "" }, actions: [ "insert" ] },
    { resource: { db: "products", collection: "system.js" }, actions: [ "find" ] }
  ],
  { w: "majority" }
)
 
자세한 내용은 아래 기술 문서를 참고한다.

db.revokePrivilegesFromRole

이미 생성 된 사용자 정의 역할에 지정한 권한을 제거한다.
 
기본 형식은 다음과 같다.
> db.revokePrivilegesFromRole(rolename, privileges, writeConcern)
 
privileges는 역할에서 삭제할 권한을 의미하며 array 타입이다.
privileges 내부의 resoucre와 actions 필드 값들이 기존 역할 정보와 정확하게 일치해야 한다.
 
> db.revokePrivilegesFromRole("accountRole",
  [ {
    resource : { db : "products", collection : "gadgets" },
    actions : [  "find" ]
  } ]
)
 
자세한 내용은 아래 기술 문서를 참고한다.
 
 

db.grantRolesToRole

이미 생성 된 사용자 정의 역할에 추가 역할을 부여한다.
 
기본 형식은 다음과 같다.
> db.grantRolesToRole(rolename, roles, writeConcern)
 
roles는 추가할 역할을 의미하며 array 타입이다.
 
예제 코드는 다음과 같다.
> use products
> db.grantRolesToRole("productsReaderWriter",
    [ "productsReader" ], 
    { w: "majority" , wtimeout: 5000 }
)
 
roles 부분은 예제처럼 "role이름" 형태로 지정할 수도 있고, 아래와 같이 Document 형태로 전달 할 수도 있다.
[ { role: "role이름", db: "database이름" } ]
 
자세한 내용은 아래 기술 문서를 참고한다.

db.revokeRolesFromRole

이미 생성 된 사용자 정의 역할에서 지정한 역할을 제거한다.
 
기본 형식은 다음과 같다.
> db.revokeRolesFromRole(rolename, roles, writeConcern)
 
roles는 삭제할 역할을 의미하며 array 타입이다.
 
예제 코드는 다음과 같다.
> use emea
> db.revokeRolesFromRole( "purchaseAgents",
  [ "writeOrdersCollection", "readOrdersCollection" ],
  { w: "majority" , wtimeout: 5000 }
)
 
roles 부분은 예제처럼 "role이름" 형태로 지정할 수도 있고, 아래와 같이 Document 형태로 전달 할 수도 있다.
[ { role: "role이름", db: "database이름" } ]

 

자세한 내용은 아래 기술 문서를 참고한다.
 

역할 삭제

특정 Database에 생성되어 있는 사용자 정의 역할을 삭제한다.
시스템에 의해 기본 생성 된 역할은 삭제하지 못한다.
 

db.dropRole

특정 Database에 생성되어 있는 사용자 정의 역할을 삭제한다.
 
기본 형식은 다음과 같다.
> db.dropRole(rolename, writeConcern)
 
예제 코드는 다음과 같다.
> use products
> db.dropRole( "readPrices", { w: "majority" } )
 
자세한 내용은 아래 기술 문서를 참고한다.
 

db.dropAllRoles

특정 Database에 생성되어 있는 모든 사용자 정의 역할을 삭제한다.
 
기본 형식은 다음과 같다.
> db.dropAllRoles(writeConcern)
 
예제 코드는 다음과 같다.
> use products
> db.dropAllRoles( { w: "majority" } )
 
자세한 내용은 아래 기술 문서를 참고한다.

역할 부여

지정한 사용자에게 추가 역할을 부여한다
 
기본 형식은 다음과 같다.
> db.grantRolesToUser(username, roles, writeConcern)
 
roles 부분은 예제처럼 "role이름" 형태로 지정할 수도 있고, 아래와 같이 Document 형태로 전달 할 수도 있다.
[ { role: "role이름", db: "database이름" } ]
 
예제 코드는 다음과 같다.
> use products
> db.grantRolesToUser( "accountUser01",
  [ "readWrite" , { role: "read", db: "stock" } ],
  { w: "majority" , wtimeout: 4000 }
)
 
자세한 내용은 아래 기술 문서를 참고한다.
 

역할 회수

사용자에게 부여한 역할을 회수한다.
 
기본 형식은 다음과 같다.
> db.revokeRolesFromUser(username, roles, writeConcern)
 
roles 부분은 예제처럼 "role이름" 형태로 지정할 수도 있고, 아래와 같이 Document 형태로 전달 할 수도 있다.
[ { role: "role이름", db: "database이름" } ]
 
예제 코드는 다음과 같다.
> use products
> db.revokeRolesFromUser( "accountUser01",
  [ { role: "read", db: "stock" }, "readWrite" ],
  { w: "majority" }
)
 
자세한 내용은 아래 기술 문서를 참고한다.