MongoDB預設並不允許遠端裝置的連線,而為了要能夠讓它允許遠端連線,就必須要進行一些額外的設定。
執行以下指令,可以查看目前MongoDB所監聽的連接埠。
ss
指令可以顯示出Socket相關的資訊。-l
參數可以只顯示正在監聽中的連線。若使用ss
指令時都沒給任何參數的話,會忽略掉監聽中的連線。-t
參數可以只顯示TCP連線。-n
參數可以讓連接埠數字直接被輸出,而不是用一個名稱代替。-p
參數可以顯示佔用連線的行程。
如上圖,可以看到MongoDB目前只有監聽127.0.0.1
也就是「loopback」這個網路介面。所以目前的MongoDB是無法直接透過遠端的方式連入的。
讓MongoDB監聽其它網路介面
在MongoDB的設定檔/etc/mongod.conf
內,位於net
欄位下的bindIp
欄位所設定的IP,即為MongoDB所監聽的網路介面。
我們可以使用逗號,
來連接更多網路介面的IP。例如:
net: port: 27017 bindIp: 127.0.0.1, 192.168.56.103
如果要綁定所有網路介面,那就把bindIp
欄位值設成0.0.0.0
吧!
設定完成之後,使用以下指令重新執行MongoDB的服務,新設定就會套用了。
當然,防火牆也記得要設定才行。MongoDB預設的連接埠是27017
,iptables規則可以這樣設定:
以上指令會對所有網路介面允許連接埠27017的TCP連入,如果要限定網路介面的話,可以再加上-i
參數,後面接上要限定的網路介面名稱。
另外還可以參考這篇文章來永久保存iptables的設定。
讓MongoDB能使用帳號密碼來登入
如果讓MongoDB監聽能連到外網的網路介面,一定要替MongoDB增設授權機制。預設的MongoDB是不啟用任何的授權機制的,任何人都可以隨意連入存取資料庫。
在啟用授權機制之前,我們先替MongoDB添加管理者帳號吧!
利用以下指令連入本地端的MongoDB。
接著會進入MongoDB的shell。輸入以下指令切換目前的資料庫為admin
資料庫,因為我們要在這個資料庫下新增使用者。admin
這個名稱是MongoDB預設的授權資料庫(Authentication Database)。
輸入以下指令來建立擁有管理所有使用者權限的使用者。指令執行之後才會設定該使用者的密碼(因為使用了passwordPrompt
函數)。
db.createUser( { user: "admin", pwd: passwordPrompt(), roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ] } )
此處的使用者名稱為admin
,可以改成別的,避免被暴力破解。userAdminAnyDatabase
表示這個位於admin
資料庫的使用者是可用來管理所有資料庫的使用者的角色,readWriteAnyDatabase
表示這個使用者可以對任意資料庫進行讀取與寫入(不需再另外指定資料庫)。
接著在MongoDB的設定檔/etc/mongod.conf
內,添加security
欄位(預設應該會有,但被加上#
註解掉了),並在其下再添加authorization
欄位,將authorization
欄位值改成enabled
表示要啟用授權機制(disabled
表示要關閉授權機制)。如下:
security: authorization: "enabled"
設定完成之後,使用以下指令重新執行MongoDB的服務,新設定就會套用了。
之後要替不同資料庫新增使用者的話,可利用以下指令連入本地端的MongoDB。
以上指令執行後才會需要輸入admin
使用者的密碼。
輸入以下指令切換目前的資料庫為要新增使用者的資料庫,在此的資料庫名稱以blog
為例。不過事實上,用來存取資料庫的使用者不一定要被建在該資料庫之內,我們可以透過roles
欄位來設定一個使用者在多個資料庫下的不同角色。
輸入以下指令來建立擁有讀寫目前這個資料庫權限的使用者,使用者名稱為blogger
。指令執行之後才會設定該使用者的密碼(因為使用了passwordPrompt
函數)。
db.createUser( { user: "blogger", pwd: passwordPrompt(), roles: [ { role: "readWrite", db: "blog" } ] } )
如此一來在遠端,要使用URI存取這個在192.168.56.103
主機上的blog
資料庫時,若blogger
使用者的密碼為{2/cH^BBS4n2
,則URI可以寫作:
注意這邊的密碼因為寫在URI裡面,所以需要跳脫處理。