1. MongoDB Authentication Mechanism
MongoDB 는 Login 시에 authentication mechanism 을 사용하게 되어있다.
여러 Mechanism 들이 사용 가능하지만, 사용되는 방식은 "MONGODB-CR / SCRAM-SHA-1" 크게 두가지이다.
2.x 버전에서는 "MONGODB-CR" 이라는 Mechanism 이 사용되다가, 3.0 version 부터 "SCRAM-SHA-1" 이라는 새로운 Mechanism 이 차용되었다.
MongoDB 3.6 version 까지는 "MONGODB-CR" 방식과 "SCRAM-SHA-1" 방식이 모두 사용 가능하지만, MongoDB 4.0 version 부터는 "SCRAM-SHA- 256" 방식이 생기면서 동시에 "MONGODB-CR" 방식이 없어진다.
문제는 "MONGODB-CR" 방식을 사용하던 서버에서 MongoDB 의 버전을 업그레이드를 진행하더라도,
Authentication Mechanism 을 업그레이드하지않는 한 그대로 "MONGODB-CR" 방식을 사용하게 된다는 점이다.
이는 MongoDB 4.0 version 으로 업그레이드 시 문제가 될 소지가 있어 최소한 MongoDB 3.6 version 에서는 authentication mechanism 을 업그레이드 해야 한다.
2. Authentication Mechanism Downgrade / Upgrade
서버의 admin DB 의 system.version collection 을 확인해보면 해당 서버의 authSchema version 을 확인할 수 있다.
uzi01:PRIMARY (admin) 15:09:01> db.system.version.find()
...
{ "_id" : "authSchema", "currentVersion" : 5 }
...
Authentication Mechanism Upgrade 를 진행하기위해, currentVersion 의 수치를 낮춰보자. ※ 참고로 해당 설정은 "__sytem" 이라는 role 이 필요하다.
uzi01:PRIMARY (admin) 15:12:25> db.grantRolesToUser("dba", [{"role":"__system", "db":" admin"}])
uzi01:PRIMARY (admin) 15:13:48> use admin
switched to db adminuzi01:PRIMARY (admin) 15:14:08> v1 = db.system.version.findOne
({"_id":"authSchema"}) { "_id" : "authSchema", "currentVersion" : 5 }uzi01:PRIMARY (admin) 15:14:27> v1.currentVersion=3
3uzi01:PRIMARY (admin) 15:14:34> db.system.version.save(v1)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })uzi01:PRIMARY (admin) 15:14:43> db.system.version.find({"_id":"authSchema"})
{ "_id" : "authSchema", "currentVersion" : 3 }
"MONGODB-CR" 을 사용하는 계정을 생성한다. currentVersion 을 "3" 으로 낮추었기때문에, 계정 생성 시 "MONGODB-CR" 을 사용하도록 만들어질 것이다.
uzi01:PRIMARY (admin) 15:19:48> db.createUser({user:"u1", pwd:"p1", roles:[{role:"readWrite", db:"d1"}]})
Successfully added user: {"user":"u1",
"roles":[{
"role":"readWrite",
"db":"d1"}
]
}
uzi01:PRIMARY (admin) 15:19:49> db.system.users.find().pretty()
{
"_id":"admin.dba",
"user":"dba",
"db":"admin",
"credentials":{
"SCRAM-SHA-1":{
"iterationCount":10000,
"salt":"NxULcugEmfPhwGCE6+U0eg==",
"storedKey":"IOqrdo2DKO27FaW1y48WHbouUKw=",
"serverKey":"s2qFxWFMbTBEIKvFRZRuKChw7CY="
}
},
"roles":[
{
"role":"readWrite",
"db":"local"
},
{
"role":"__system",
"db":"admin"
},
{
"db":"admin"
}
]
}{
"_id":"admin.u1",
"user":"u1",
"db":"admin",
"credentials":{
"MONGODB-CR":"49062bb3a44c80ba399ce1534aa845b1"
},
"roles":[
{
"role":"readWrite",
"db":"d1"
}
]
}
currentVersion 이 "5" 였을 때 생성된 계정을 보면, credentials 의 필드가 "SCRAM-SHA-1" 으로 설정된 것을 볼 수 있다.
반면 currentVersion 을 "3" 으로 다운그레이드 후에 생성된 u1 계정을 보면, credentials 의 필드가 "MONGODB-CR" 로 생성되었다.
Upgrade 는 아래와 같은 커맨드로 실행이 가능하다.
uzi01:PRIMARY (admin) 15:20:12> db.adminCommand({authSchemaUpgrade:1})
{
"done":true,
"ok":1,
"operationTime":Timestamp(1563258607,
2),
"$gleStats":{
"lastOpTime":{
"ts":Timestamp(1563258607,
2),
"t":NumberLong(1)
},
"electionId":ObjectId( "7fffffff0000000000000001" )
},
"$configServerState":{
"opTime":{
"ts":Timestamp(1563258606,
3),
"t":NumberLong(1)
}
},
"$clusterTime":{
"clusterTime":Timestamp(1563258607,
2),
"signature":{
"hash":BinData(0,
"AAAAAAAAAAAAAAAAAAAAAAAAAAA=" ),
"keyId":NumberLong(0)
}
}
}
uzi01:PRIMARY (admin) 15:30:07> db.system.users.find().pretty()
{
"_id" : "admin.dba",
"user" : "dba",
"db" : "admin",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "NxULcugEmfPhwGCE6+U0eg==",
"storedKey" : "IOqrdo2DKO27FaW1y48WHbouUKw=", "serverKey" : "s2qFxWFMbTBEIKvFRZRuKChw7CY="
}
},
"roles" : [
{
"role" : "readWrite",
"db" : "local"
},
{
"role" : "__system", "db" : "admin"
"db" : "admin"
}
]
}
{
"_id": "admin.u1",
"user": "u1",
"db": "admin",
"credentials": {
"SCRAM-SHA-1": {
"iterationCount": 10000,
"salt": "aPT6rPu+jl1LMwC49fDE3A==",
"storedKey": "r/PHFRoh4+miaz0+9LUbv3qTeJ8=",
"serverKey": "LgHi8FB4zNUo/7QLYifDc3Hj1w4="
}
},
"roles": [
{
"role": "readWrite",
"db": "d1"
}
]
}
업그레이드 후 "u1" 계정의 credentials 필드가 "SCRAM-SHA-1" 으로 변경된 것을 볼 수 있다.
3. Authentication Mechanism 에 따른 접속 가능 여부 테스트
"ROBO 3T" 라는 GUI Client Tool 에서는 접속 시에 mechanism 을 설정할 수 있다.
case 1. credentials 이 "MONGODB-CR" 일 경우
1) Auth Mechanism = MONGODB-CR
2) Auth Mechanism = SCRAM-SHA-1
credentials 의 필드가 "MONGODB-CR" 인 설정된 경우, Auth Mechanism 이 "MONGODB-CR", "SCRAM-SHA-1" 인 두 경우 모두 접속이 가능하다.
case 2. credentials 이 SCRAM-SHA-1 인 경우
1) Auth Mechanism = MONGODB-CR
2) Auth Mechanism = SCRAM-SHA-1
credentials 의 필드가 "SCRAM-SHA-1" 인 설정된 경우, Auth Mechanism 을 "MONGODB-CR" 으로 설정 시에는 인증에 실패하게 된다.
4. 결론
MongoDB 4.0 에서 "MONGODB-CR" 방식이 deprecated 됨에 따라,
최소 4.0 이전 버전 중 마지막 버전인 3.6 version 에서는 MONGODB-CR 방식을 제거하고 가야한다.
authSchema 의 version upgrade 는 어렵지않게 커맨드 한줄로 실행이 가능하다.
하지만 개발팀에서 auth mechanism 을 "MONGODB-CR" 로 설정해두고 사용하는 경우에는 서비스 장애가 불가피하다.
경험 상 보통은 해당 값을 null 로 사용해서 크게 문제가 될 것이라고 생각하지는 않지만, 확인해보는 것이 좋을 것 같다.
'MongoDB > R&D' 카테고리의 다른 글
MongoDB Replica Set Protocol Version (PV) (0) | 2020.02.12 |
---|---|
MongoDB Plan Cache (3) | 2020.01.29 |
MongoDB Query Execution Plan (1) | 2020.01.29 |