2016-10-06 134 views
5

語境

在我目前的Web應用程序項目,我設置了MongoDB數據庫,包括服務器管理員和項目的用戶,通過一些JavaScript文件與該MongoDB的shell中執行的手段。的MongoDB:如何存儲憑據安全?

我似乎無法找到一種方法來處理在一個安全的方式root或用戶密碼:

問題1:創建用戶

這是我用它來創建一個超級用戶發明實施例一JavaScript文件和一個項目的用戶:

use admin 

db.createUser(
{ 
    user: "root", 
    pwd: "abc123", 
    roles: [ 
    { 
     role: "root", 
     db: "admin" 
    }] 
}) 

use project_db 

db.createUser(
{ 
    user: "project_admin", 
    pwd: "def456", 
    roles: [ 
    { 
     role: "dbOwner", 
     db: "project_db" 
    }] 
}) 

顯然,這個文件是版本控制之下。我該如何去存儲明文密碼在那裏?!?所述db.createUser(...) docs明確地陳述明文口令必須被傳遞(使用外部用戶數據庫時除外)。

真的嗎?!?

問題2:使用憑證

我發現三種方式訪問​​數據庫時(到例如運行數據庫安裝腳本)來傳遞憑證;其中沒有令人滿意地工作:

認證所述命令行上

mongo可執行採取相應參數:

mongo --username project_admin   \ 
     --password def456     \ 
     --authenticationDatabase project_db \ 
    < "${path_to_db_build_script}" 

問題:密碼在例如是可見輸出爲ps。不能接受的。
傳遞--username project_admin只有失敗,Error: Missing expected field "pwd"
傳遞--username project_admin --password使得mongo查詢密碼交互,這顯然阻止自動執行腳本 - 和自動就是爲什麼這是擺在首位的腳本...

使用~/.mongorc.js

認證從this blog post摘自:

db = connect("localhost:27017/project_db"); 
db.getSiblingDB("project_db").auth("project_admin", "def456"); 

這是行不通的,但似乎沒有提供一種方式來處理多個用戶。有可能是一種方法用一個.js文件工作每用戶和/或.js文件模板,但一旦有涉及任何有複雜性,這些文件應該是版本控制之下 - 這使我們回到了同樣的問題,作爲創建用戶。

使用代碼

理論上驗證,它也應該可以使用db.auth(...)在腳本中進行驗證。
在實踐中,這似乎只是一個史詩般的失敗對我說:

這工作,但在代碼存儲的憑據:

db.auth("project_admin", "def456") 

這個工程使用JSON文檔;還存儲在代碼證書:

db.auth({ user: "project_admin", pwd: "def456" }) 

db.auth(...)確實有digestPassword參數,主要是無證的,但顧名思義是指以表明在某些加密/散列/醃製/任何方式傳遞密碼。

這將允許將.js腳本存儲在帶有非明文密碼的版本控制中;不理想,但絕對比明文更好。然而,這只是不起作用,即失敗,Error: Authentication failed.

對於初學者來說,我會假設設置digestPasswordfalse明文傳送密碼時爲宜;然而,這種失敗(BUG#1):

db.auth({ user: "project_admin", pwd: "def456", digestPassword: fails }) 

,而這個工程(WTF?!?):

db.auth({ user: "project_admin", pwd: "def456", digestPassword: true }) 

設置mechanismPLAIN失敗Error: Missing expected field "mechanism",儘管該領域顯然是有(?BUG#2),不管是digestPasswordtruefalse

db.auth({ user: "project_admin", pwd: "def456", digestPassword: true, mechanism: "PLAIN" }) 

設置mechanism到默認SCRAM-SHA-1似乎暴露與上面相同的錯誤;此失敗:

db.auth({ user: "project_admin", pwd: "def456", digestPassword: fails, mechanism: "SCRAM-SHA-1" }) 

而工作的:

db.auth({ user: "project_admin", pwd: "def456", digestPassword: true, mechanism: "SCRAM-SHA-1" }) 

加密/散列/消化/不管密碼可以通過啓動mongo殼作爲root獲得,例如

mongo admin -u root -p abc123 

和運行db.system.users.find()返回是這樣的:從輸出的密碼與digestPasswordtruefalse失敗

... 
{ 
    "_id": "project_db.project_admin", 
    "user": "project_admin", 
    "db": "project_db", 
    "credentials": 
    { 
     "SCRAM-SHA-1": 
     { 
      "iterationCount": 10000, 
      "salt": "WnKFmGs3BTbmkbUWi0RPnA==", 
      "storedKey": "EEIMqBEMUUOpoR3i3pgKz0iRumI=", 
      "serverKey": "HsSOxujNODlKcRiEdi1zkj83MRo=" 
     } 
    }, 
    "roles": [ 
    { 
     "role": "dbOwner", 
     "db": "project_db" 
    }] 
} 
    ... 

使用上述三種哈希(?)。不考慮消息來源,我只能假設上面有sha1(password + salt)credentials的關係,但似乎沒有任何文檔,我迄今爲止所嘗試的錯誤並不完全鼓勵進一步追求這一點。

定製方法

有可能是在~/.mongorc.js,是以當前用戶名(來自哪裏?),並從外部源中查找密碼運行JavaScript的方式。但爲什麼我必須爲所謂的數據庫解決方案實施憑證管理?

問題:

  1. 用MongoDB的工作時,人們如何處理憑證?
  2. 到目前爲止,我對MongoDB的經驗非常糟糕,考慮到MongoDB正在出售用於生產目的,首先尋找我的原因似乎是明智之舉。我在做一些根本性錯誤?我的期望是不合理的嗎? MongoDB用戶不關心密碼安全嗎?

如果有人能分享他們的方法和經驗,我將不勝感激。

回答

-2

我假設你正在使用Node.js的

所以基本的方法是做一個應用程序端加密即加密在您的應用程序代碼中的字段,如將其保存到MongoDB的前密碼。

你是怎麼做到的?

您可以使用名爲bcrypt的node.js包。

要安裝bcrypt使用以下命令:npm install bcrypt –save-dev.

然後,你可以寫上保存操作的功能,將它們保存到MongoDatabase之前加密你想要的字段。

var mongoose = require('mongoose'); 
var bcrypt = require('bcrypt'); 
var SALT_WORK_FACTOR = 10; 
mongoose.connect('mongodb://localhost/project_db'); 

var db = mongoose.connection; 

db.on('error', function(err){ 
    console.log('connection error', err); 
}); 

db.once('open', function(){ 
    console.log('Connection to DB successful'); 
}); 

var Schema = mongoose.Schema; 
var userSchema= new Schema({ 
    name:String, 
    password:String 
}); 

var User = mongoose.model('User', userSchema); 

userSchema.pre('save', function(next){ 
    var user = this; 
    if (!user.isModified('password')) return next(); 

    bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt){ 
     if(err) return next(err); 

     bcrypt.hash(user.password, salt, function(err, hash){ 
      if(err) return next(err); 

      user.password = hash; 
      next(); 
     }); 
    }); 
}); 

var testSample = new User({ 
    name: "admin", 
    password: "password1234" 
}); 

testSample.save(function(err, data){ 
    if(err) console.log(err); 
    else console.log ('Sucess:' , data); 
}); 

您擁有的其他選項是在數據庫級別本身配置某些安全性。那麼這是巨大的,所以我不能在這裏總結它。

希望這種聯繫將有助於您:https://docs.mongodb.com/manual/security/

+0

我真的不明白你在做什麼,但我不能幫助,但得到的印象,你已經從根本上誤解了我的問題:首先,我沒有使用node.js.此外,我不是在談論應用程序用戶,而是數據庫用戶。另外,通過ORM管理數據庫等服務的用戶並不適合我。最後同樣重要的是,你的方法並沒有解決實際問題,因爲你仍然在代碼中存儲憑證。不管怎麼說,還是要謝謝你。 – ssc

+0

這並沒有解決如何建立數據庫連接和保護「靜止」和cmdline的憑證。 –