이 문서는 MongoDB Community Edition 를 리눅스 플랫폼에서 시작과 운영에 필요한 구성 파일 mongod.conf 의 설정을 다루고 있다. 이를 통해 데이터베이스 서비스를 동작시키고, 인증한 사용자로서 클라이언트 프로그램으로 접속하기 위한 기본 인증방식을 구성하는 것을 정리하고 있다.
이 문서는 Arm64 기반 CPU를 사용하는 Raspberry Pi, Odroid, PINE64, OrangePi 등 SBC 지원 보드 계열 위에서 Ubuntu/Debian 에서 설치 및 사용 가능한 MongoDB Community Edition 4.2 버전을 설치하고 구성하는 과정을 정리하고 있다.
W: GPG error: https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 4B7C549A058F8B6B
1 2 3 4 5
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 3B4FE6ACC0B21F32 7C549A058F8B6B gpg: key 4B7C549A058F8B6B: public key "MongoDB 4.2 Release Signing Key <packaging@mongodb.com>" imported gpg: Total number processed: 1 gpg: imported: 1
명령으로 mongod 로 실행이 가능한 MongoDB Server는 기본적으로 보안 모델이 없이 실행된다. 따라서 별도의 인증 절차를 가지고 있지 않습니다. 이 때문에 2017년 1월에는 이런 약점을 노린 랜섬웨어가 발생하기도 했습니다. MongoDB는 되도록이면 외부로부터의 신뢰되지 않은 접속을 허용하지 않는, 보안에 문제가 되지 않는 환경에서 보안 모델 없이 실행하는 것을 지향하고 있으나, 어쨌든 MongoDB도 ID와 비밀번호로 접근하는 기본적인 보안 모델을 가지고 있으니 이를 통해 MongoDB Server에 인증 과정을 추가해 보도록 합시다.
비인증 모드에서 관리자 계정 생성
인증 접속
1. 비인증 관리자 계정 생성하기
mongod로 별도의 보안 모델이 없는 MongoDB Server를 실행하고, MongoDB Shell에 접속합니다.
1 2 3 4
> mongo MongoDB shell version v3.6.3 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.6.3
MongoDB에는 admin이라는 데이터베이스가 존재하며, 해당 데이터베이스에 사용자를 추가합니다.
db.createUser()는 현재 사용하고 있는 데이터베이스(여기서는 admin)에 사용자를 추가합니다. 여기에는 사용자 이름, 비밀번호와 함께 권한(roles)을 array로 정의합니다. MongoDB에서 빌트인으로 제공하고 있는 권한은 MongoDB Built-In Roles에서 확인할 수 있습니다.
위에서 정의한 userAdminAnyDatabase는 어느 데이터베이스든 사용자를 생성하고 제거할 수 있다는 것을 의미합니다. 모든 권한을 가지게 하려면 root를 사용하면 되고, MongoDB 2.4 이하의 경우 db.addUser()를 통해 사용자를 추가합니다.
mongod 인증하기
만약 mongod 명령으로 실행하면 MongoDB Server를 실행하도록 한다.
1
> mongod --auth
MongoDB Server 재시작하기
Ubuntu와 같은 리눅스 시스템에서 service mongod start처럼 service를 이용할 경우, config 파일을 통해 실행됩니다. 이 경우 /etc/mongod.conf를 다음처럼 수정하고 재시작(service mongod restart)하면 됩니다.
mongodb 4.x
인증을 활성화 하려면
1 2
security: authorization: enabled
mongodb 3.x
mongod.conf 를 사용하면 다음 옵션을 true 로 구성한다.
1
auth = true
그리고 서비스를 재시작한다.
1 2
$ sudo systemctl restart mongod.service
2. 인증 접속
mongo 쉘에 접속하여 db.auth()를 사용하는 것입니다.
1 2 3 4 5
$ mongo MongoDB shell version v4.2.1 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("177716fe-5b3c-41f6-bdae-d2584819abff") } MongoDB server version: 4.2.1
쉘에서 db.auth() 를 사용해 인증에 성공하면 1이 나오면 성공이다.
1 2 3 4 5
> use admin switched to db admin > db.auth('admin', '!23456789'); 1 >
인증 접속이 되면 로그에 아래 같은 로그를 확인할 수 있다.
1
2019-12-02T09:49:24.392+0000 I ACCESS [conn3] Successfully authenticated as principal admin on admin from client 127.0.0.1:52370
명령행에서 접근
인증과 함께 admin 데이터베이스로 접근하려면 아래 같이 명령어에 아이디와 비밀번호를 명시만 해 주면 된다.
이 문서는 Ubuntu/Debian 계열 정규 배포본에 3.x 버전을 지원하지 않는 플랫폼에 MongoDB Community Edition 3.6 버전을 설치하는 과정을 정리하고 있다. 내용의 기초는 MongoDB Community Edition 3.6 버전을 Amd64, Arm64 지원하는 64bit OS에 설치해 사용하기 위해서 Install MongoDB Community Edition, on-ubuntu를 따라서 진행하고 경험상 필요한 부분을 추가로 정리했다.
MongoDB 설치후 데이터베이스 위치, 로그, 인증 등에 관련한 서버 구성과 설정을 정리한다.
MongoDB 2.6 과 MongoDB Community Edition 3.x 버전을 사용했다.
mongoDB 접근제어
mongoDB 는 설치과정 중에 인증과 관련해 설정하는 부분이 없어서 설치 후 누구나 DB에 접속 할 수 있다. 인증을 추가해 데이터베이스 관리자와 데이터베이스 사용자로 구분해서 이용하고, 각 데이터베이스의 사용자는 허가된 역할(Role)을 가지고 데이터베이스에 접근 가능하도록 구성한다.
mysql >createuser foo@localhost identified by'password'; mysql >createuser'foo'@'%' identified by'password';
혹은
1
insert into user (host, user, password) values ('localhost', 'hiru', 'password('hirururu'));
사용자 제거 mysql > drop user ‘hiru’; mysql > delete from user where user =’hiru’
사용자 생성시 다음같이 1396 에러는 CREATE USER/GRANT 명령으로 사용자와 권한을 추가/관리해야 하는데 mysql.db, mysql.user 테이블을 직접 조작하다가 일관성이 깨졌기 때문
1 2
mysql> create user 'shopuser'@'localhost' identified by ')12345'; ERROR 1396 (HY000): Operation CREATE USER failed for 'shopuser'@'localhost'
제대로 사용자를 삭제하고
drop user shopuser@localhost
flush privileges; 로 갱신해 준다.
권한 주기
권한을 추가하고 삭제하기 위해서, GRANT와 REVOKE의 명령을 사용한다. GRANT 명령 등으로 데이터베이스 사용자가 데이터베이스 자원에 접근하는 권한을 만들 수 있다.
GRANT ALL privileges ON DB_NAME.TABLE TO USER_ID@[HOST] IDENTIFIED BY ‘PASSWORD’ GRANT [SELECT,DELETE,INSERT,UPDATE,] ON DB_NAME.TABLE TO USER_ID@[HOST] IDENTIFIED BY ‘PASSWORD’
현재 머신에서만 접속할 수 있는 사용자 계정, 외부, 원격에서 접속할 수 있는 사용자 계정을 추가해 준다.
1 2 3
mysql> use mysql; # mysql system db mysql>GRANTALL privileges ON mydb.*TO foo@localhost IDENTIFIED BY'*****'; mysql>GRANTALL privileges ON mydb.*TO foo@'%' IDENTIFIED BY'*****';
혹은
1 2
grant select, insert, update, delete on mydb.* to foo@host identified by 'password'; mysql > grant select, insert, update, delete on dbname.table to userid@'192.168.%' identified by 'password';
권한을 확인하는 방법
1 2
mysql >show grants for foo@localhost mysql >show grants for'foo'@'%';
변경된 권한을 적용하기
1
mysql > flush privileges;
권한을 삭제하는 방법
1
mysql > revoke all on dbname.table from username@host
추가한 사용자는 SELECT로 확인할 수 있다.
1
mysql> select host,authentication_string from user where user='foo';
studnets.txt 파일을 읽어들이는 것은 스크립트 파일을 작성하거나 mysql에서 직접 실행할 수 있다. 먼저 스크립트 파일 students.sql은 다음과 같다.
1 2 3
use mydb; load data local infile "student.txt" intotable student fields terminated by',' ;
이제 mysql 클라이언트에서 데이터를 읽어 들인다.
1 2
mysql>source students.sql;
데이터 조회
SELECT [DISTINCT] select _expr essi on FROM table_list WHERE where_definition ORDER BY col_name [ASC|DESC] GROUP BY col _name_list LIMIT [offset ], rows
예제-1) 전체 교수 리스트를 출력하는 SQL 검색 문을 작성하라. mysql > sel ect * fromprof;
예제-2) 전체 교수 리스트를 이름순서로 출력하는 검색 문을 작성하라. mysql > sel ect * fromprof order by pname;
예제-5) 전체 교수 리스트를 이름 역순으로 출력하는 검색 문을 작성하라. mysql > sel ect * fromprof order by pname desc;
전체 교수 리스트를 학과별로 출력하는 검색 문을 작성하라. mysql > sel ect * fromprof order by pdept, pname;
예제-4) 국문학과 교수 리스트를 이름순서로 출력하는 검색 문을 작성하라. mysql> select * from professor where pdept =’국문학과’;
JOIN
“FROM 테이블명 AS 별명” 구문은 SQL 문장에서 별명으로 테이블을 참조하 는 역할은 한다.
예제-6) MySQL 과목을 강의하는 교수님의 이름, 전화번호와 강의실을 검색 하는 문장을 작성하라. mysql> select p.pname, p.pphone, c.croom from professor p, course c, lecture l where c.cname=’MySQL’ and c.ccode=l.lccode and l.lpcode=p.pcode;
예제-7) ‘김구’ 교수님이 강의하는 과목명, 강의 시수와 강의실을 검색하는 문장을 작성하라.
1 2 3 4
select c.cname, c.ctime, c.croom from professor as p, course as c, lecture as l where p.pname ='김 구'and p.pcode = l.lpcode and l.lccode = c.ccode;
예제-8) 각 학생이 수강 신청한 과목에 대해서 학생이름, 전화번호, 과목명, 강의실, 강의 시수를 검색하는 문장을 작성하라.
1 2 3 4
select s.sname, s.sphone, c.cname, c.ctime, c.croom from student as s , course as c, register as r where s.scode = r.rscode and r.rccode = c.ccode orderby s.sname, c.cname;
sub-query
예제-9) 각 학생이 신청한 총 학점을 구하는 검색식을 작성하라.
1 2 3 4
select s.sname, s.sdept, s.sphone, sum(c.ctime) from student as s , course as c, register as r where s.scode = r.rscode and r.rccode = c.ccode groupby s.sname;
WHERE 조건절에 해당하는 결과를 GROUP BY 구절에 명시된 s.sname 필드에 따라 그룹으로 결과를 분류하고 난 후, SELECT 필드에 SUM(c.cti me) 함수를 사용해서 c.cti me 필드에 대한 합을 구함으로써 각 학 생이 신청한 총 학점를 구할 수 있다.
예제-10) 각 학과별 교수님은 몇 분인지 구하는 검색식을 작성하라.
1 2 3
select pdept, count(*) from professor groupby pdept;
LIMIT 구절
예제-11) 페이지 크기가 2 일 때, (예제-8)의 결과에서 두 번째 페이지를 검색하는 SQL문장은 작성하라. select s.sname, s.sphone, c.cname, c.ctime, c.croom fromstudent as s , course as c, regi ster as r where s.scode = r.rscode and r.rccode = c.ccode order by s.sname, c.cname limit 2, 2;
마지막 행의 limit 2, 2구절에서, 첫 번째 인자는 오프셋(offset)으로 검 색 결과 레코드들의 순번을 의미한다. 오프셋 값은 0 부터 지정하기 때문에 오프셋값2는전체레코드중에서세번째레코드를가리킨다. 두번째는 인자는 출력하는 레코드 수(rows)를 의미한다. 따라서, 레코드 수 2 는 2 개 의 레코드를 출력하라는 의미가 된다.
예제-12) 교수테이블에서 ‘김 구’ 선생님의 이름을 ‘하은용’ 교수님으로 변 경하는 문장을 작성하라. update prof set pname =’하은용’ where pname =’김구’;
예제-13) 지도 테이블의 교수코드가 ‘P007’ 인 레코드들을 모두 ‘P005’ 로 변경하라. update advise set apcode =’P005’ where apcode =’P007’;
예제-14) 강의 시수가 2인 과목들의 강의 시수를 하나 증가 시키고, 강의실 을 Lab1로 변경하라. update course set ctime=ctime + 1, croom=’Lab1’ where ctime=2;
Delete
DELETE FROM tbl_name [WHERE where_definition] [LIMIT rows]
예제-15 ) 국문학과 학생 레코드를 삭제하는 문장을 작성하라. delete fromstudent where sdept =’국문학과’;
PyMySQL 튜토리얼
PyMySQL 설치
1
$ pip install PyMySQL
만약 pip 로 설치가 안되면 다음 같이 setup.py를 이용해 직접 설치 할 수 있다. $ # X.X is the desired PyMySQL version (e.g. 0.5 or 0.6). $ curl -L https://github.com/PyMySQL/PyMySQL/tarball/pymysql-X.X | tar xz $ cd PyMySQL* $ python setup.py install $ # The folder PyMySQL* can be safely removed now.