본문 바로가기
코딩과 알고리즘

몽고DB, 데이터베이스별 관리자 계정 생성

이번 시간에는 지난번의 몽고 DB 최고관리자 계정 생성에 이어,
데이터베이스별로 각각 관리자 아이디를 생성하는 방법을 알아보도록 하겠습니다.

itadventure.tistory.com/380

 

몽고DB, 계정 보안! 최고관리자 계정 만들기

이번 시간에는 몽고DB 의 계정 보안에 대해 살펴보겠습니다. 관계형 데이터베이스 대부분은 데이터베이스에 로그인할 때 관리자 계정이라는게 있습니다. 보통 mysql(or mariadb)과 mssql 계열은 root,

itadventure.tistory.com

1대의 서버를 여러 다중 목적으로 사용한다고 생각해 봅시다.
이를 테면 대학교 홈페이지, 도서관, 건설사 홈페이지를
한대의 서버에 폴더를 따로 두어 각각 도메인을 세팅하여 서비스 한다고 가정해 볼까요?
※ 이를 가상 호스트(Virtual Host)라고 합니다.

각각의 대학교, 도서관, 건설사 전산 관리자에게는 홈페이지 유지보수를 위해
각 관리자의 몽고 DB 에는 접근은 할 수 있게 하되
다른 기관으로의 DB에는 접근을 허용하지 않아야 합니다.

몽고DB에서는 데이터베이스마다 각각의 관리자 계정을 둘 수 있는데요.
각 관리자는 자신에게 허용된 데이터베이스에는 접근할 수 있지만 다른 데이터베이스에는 접근할 수 없습니다.

이런 이유가 아니더라도 최고관리자 계정과 데이터베이스 관리자 계정은 따로 두는 것이 좋습니다.
홈페이지 개발을 한다고 치면 분명 DB에 접속하기 위해 패스워드를 소스 내에 위치할 수 밖에 없는데요.
( 암/복호화 기법으로 약간 예외처리를 할 수는 있습니다 )
이런 이유로 사용하는 패스워드가 혹시 해커에 의해 탈취당하더라도
몽고DB 최고관리자 계정이 아닌 하나의 데이터베이스 계정 정보만 탈취당한다면
몽고DB 전체를 좌지우지할 수 있는 최고관리자 권한을 뺏기지는 않기 때문이지요.

이런 데이터베이스별 관리자 규칙은 누구 정하는 것일까요?
바로 몽고 DB 최고 관리자가 정해주는 것이지요.

AWS(Amazon Web Service)에 접속하신 다음,
root 계정으로 변!신!해봅시다. ( sudo su - root )
그리고 몽고 DB에 최고관리자 계정으로 접속하도록 합니다.
( 최고관리자 계정을 root 가 아닌 다른 아이디로 생성하신 경우 -u 다음에는 그 계정명을 적어 줍니다 )

mongo -u root

그리고 패스워드를 입력해 주시면 됩니다.

이제 대학교 홈페이지 관리자 계정을 한번 추가해봅시다.
먼저 use 명령으로 데이터베이스를 선택해야 하는데요
크레이는 crayUniversity 라는 데이터베이스명으로 해보도록 하겠습니다만,
명칭은 독자 여러분께서 자유롭게 정해 주세요 :)

use crayUniversity

이제 crayUniversity 데이터베이스의 관리자 계정을 추가해봅시다.
크레이는 관리자 아이디를 'uadmin' 으로 하겠습니다.
createUser 명령을 이용하여 아래와 같이 json 스타일로 입력하시면 되는데요.
user 아이디는 대학교 DB 관리자의 아이디를 입력하고,
db 에는 데이터베이스 명칭을 적어주시면 됩니다.
참고로 role 은 DB의 사용권한인데 읽고 쓸 수 있는 권한을 의미하지만,
'read'만을 준 경우 읽기만 허용이 된다고 합니다.
이 부분은 추후 제대로 작동되는지 테스트 해볼 예정입니다.

db.createUser({
    user: "uadmin",
    pwd: passwordPrompt(),
    roles: [ { role: "readWrite", db: "crayUniversity" } ]
})

pwd 에는  passwordPrompt() 명령을 사용하였기 떄문에, 패스워드를 묻는 창이 나옵니다.
여기서 대학교 관리자의 패스워드를 정해주시면 됩니다.
당연히 보안을 위한 거니 root 패스워드와 다른게 좋겠지요 ?

패스워드를 입력 후 Successfully 화면이 등장하면 계정이 정상 추가된 것입니다.

현재 추가된 사용자 계정을 조회하려면 db.getUser() 명령을 내려주시면 됩니다.

> db.getUsers()
[
        {
                "_id" : "crayUniversity.uadmin",
                "userId" : UUID("7badcd0b-6f46-4931-9d15-b97839f55968"),
                "user" : "uadmin",
                "db" : "crayUniversity",
                "roles" : [
                        {
                                "role" : "readWrite",
                                "db" : "crayUniversity"
                        }
                ],
                "mechanisms" : [
                        "SCRAM-SHA-1",
                        "SCRAM-SHA-256"
                ]
        }
]

만일 아이디나 패스워드를 잘못 기입하셨다면 계정을 삭제하고 다시 추가해주시면 되는데요.
계정 삭제명령은 아래와 같습니다. 그리고 다시 계정을 추가해주시면 됩니다.

db.dropUser('아이디')

내친 김에, 도서관, 건설사 홈페이지 관리자 계정도 추가해 봅시다.

아래 명령을 차례대로 입력해 도서관 관리자 계정을 추가하고,

use library
db.createUser({
    user: "ladmin",
    pwd: passwordPrompt(),
    roles: [ { role: "readWrite", db: "library" } ]
})

이어서 건설사 관리자 계정을 추가해봅시다

use construct
db.createUser({
    user: "cadmin",
    pwd: passwordPrompt(),
    roles: [ { role: "readWrite", db: "construct" } ]
})

여기서 한가지 의문이 드시는 점이 있을 수 있을 것입니다.
db.createUser 명령 안에 db 를 명시해주는데 굳이 use 에서 db를 선택해줄 필요가 있는가입니다.

답은 "항상 db를 선택해주어야 한다는 것입니다."
그것은 접속 권한 때문인데요.
db 접근권한은 roles 에서 정해진 규칙으로 처리하지만,
db 접속권한은 use 로 선택한 데이터베이스에서 담당하기 때문입니다.
깊게 들어가면 너무 길어지니까 이 정도로만 알아 두시면 좋을것 같습니다 :)

이제 데이터베이스 1개의 관리자 계정으로 접속해서 확인해 봅시다

exit 명령으로 몽고 DB를 종료하신 다음

대학교 DB 로 접속해봅니다. mongo -u 관리자아이디 데이터베이스를 기재합니다.
root 접속과 다른 점은 뒤에 DB명을 써주어야 한다는 점입니다.
안 그러면 접속권한 문제로 접속이 안됩니다. 

mongo -u uadmin crayUniversity

이제 데이터베이스를 사용할 수 있는지 show dbs 명령을 내려볼까요?
엇, 이상하게 아무 내용도 나오지 않습니다.
그것은 데이터베이스에 아무 내용도 없기 때문입니다.

현재 사용중인 DB 이름을 확인하시려면 그냥 db 라고 입력해 주시면 됩니다. 

이제 crayUniversity DB에 자료를 추가해 볼까요?
대학교이니 학과가 있을것 같습니다.

컬렉션명department  로 정하기로 하고,
컬럼명은 학과명 name, 학과코드 code 로 정하기로 하고
3개의 학과를 입력해볼까요?
참고로 한글을 타이핑하시려면 AWS 기본 터미널로는 안되고 지난 내용중 다루었던 모바XTERM을 이용하셔야 합니다.

db.department.insert( { name:'컴퓨터공학과', code:'10001' } )
db.department.insert( { name:'정보보안학과', code:'10002' } )
db.department.insert( { name:'멀티미디어시스템공학과', code:'10003' } )

참고로 컬렉션명과 각 속성을 아래처럼 한글로도 지정할 수 있습니다.
이건 그냥 참고로 알아 두세요 :)

db.학과.insert( { 과명:'컴퓨터공학과', 코드:'10001' } )
db.학과.insert( { 과명:'정보보안학과', 코드:'10002' } )
db.학과.insert( { 과명:'멀티미디어시스템공학과', 코드:'10003' } )

이제 학과를 조회해봅시다.
한가지 편리한 팁을 하나 이쯤에서 소개해드립니다.
자동완성이란 기능인데요,

학과를 조회하려면 아래 명령을 내려야 합니다.

db.department.find()

터미널 창에서 db.de  까지만 타이핑하고,

TAB 키를 눌러보세요. 그러면 de 로 시작되는 중복된 컬렉션 명이 유일하게 1개만 존재하는 경우 자동 완성해줍니다.

다시 .f 를 입력하고,

TAB 키를 눌러 봅시다. 그러면 나머지 find 까지를 자동완성해 주지요.

마지막으로 () 를 입력, Enter 키를 치시면 됩니다.
익숙해진 컬렉션명을 빨리 입력할 때, 매우 유용하시겠지요?
아래와 같이 3개의 학과가 입력된 것을 보실 수 있고,

만약 한글로 입력했다면 아래와 같이 결과가 나옵니다.

> db.학과.find()
{ "_id" : ObjectId("5fc222abb41c0709f3fa495e"), "과명" : "컴퓨터공학과", "코드" : "10001" }
{ "_id" : ObjectId("5fc222abb41c0709f3fa495f"), "과명" : "정보보안학과", "코드" : "10002" }
{ "_id" : ObjectId("5fc222acb41c0709f3fa4960"), "과명" : "멀티미디어시스템공학과", "코드" : "10003" }

이제는 DB에 자료가 입력되었기 때문에,
show dbs 명령을 내리면 crayUniversity DB가 조회가 됩니다.

이처럼 crayUniversity 데이터베이스의 uadmin 관리자는 crayUniversity 에 자료를 삽입할 수는 있지만,
다른 데이터베이스에는 접근할 수 없습니다.

도서관 db에 접근하기 위해 library DB를 선택해봅시다. ( use library )
엇, db가 전환되었다고 나옵니다. 하지만 이 문구는 접근 권한이 있다는 의미가 아닙니다.

book 이라는 컬렉션에 '로빈훗의 대모험'이라는 책을 하나 입력해볼까요?

db.book.insert({ name:'로빈훗의 대모험' })

그러면 아래와 같이 오류가 납니다.
errmsg : not authorized on library to execute command { insert 어쩌고..
해석하면 오류메시지 : library에 대해 { insert 어쩌고... 명령을 실행할 권한을 부여받지 않았습니다. 의 의미입니다.

이처럼 각 데이터베이스 관리자는 권한을 부여받은 데이터베이스에 대해서만 접근이 가능합니다.
다음 시간에는 이렇게 설정된 권한의 데이터베이스 관리자 권한을 이용하여
PHP에서 접속하는 방법을 살펴보도록 하겠습니다.

필요하신 분께 도움이 되셨을지 모르겠습니다.
오늘도 여기까지 읽어주셔서 감사합니다 :)


하나님의 말씀은 마지막 때에 죽은 자, 곧 잠자는 자들을 부활케 하시는 능력이 있는 줄 믿습니다.
이 말씀을 믿는 분들에게 그러한 은혜가 충만하시기를 소원합니다.

그러나 이제 그리스도께서 죽은 자 가운데서 다시 살아 잠자는 자들의 첫 열매가 되셨도다
- 고린도전서 15장 20절 말씀 -