On a fresh MongoDB 3.0.3 installation, with authentication enabled, a user needed to connect with a third party tool to his Mongo database. The connection itself worked, but the authentication didn't. The following error message appeared in the MongoDB log (/var/log/mongodb/mongod.log):
2015-05-20T11:32:28.797+0200 I NETWORK [initandlisten] connection accepted from remote.example.com:58977 #70 (5 connections now open)
2015-05-20T11:32:28.803+0200 I ACCESS [conn70] authenticate db: LOG { authenticate: 1, nonce: "xxx", user: "dbuser", key: "xxx" }
2015-05-20T11:32:28.804+0200 I ACCESS [conn70] Failed to authenticate dbuser@LOG with mechanism MONGODB-CR: AuthenticationFailed MONGODB-CR credentials missing in the user document
2015-05-20T11:32:28.805+0200 I NETWORK [conn70] end connection remote.example.com:58977 (4 connections now open)
It seems that since MongoDB 3.0 there is a new authentication mechanism: SCRAM-SHA-1:
MongoDB’s default authentication method is a challenge and response mechanism (SCRAM-SHA-1).
Previously, MongoDB used MongoDB Challenge and Response (MONGODB-CR) as the default.
So this explains the log entries that MONGODB-CR credentials are missing.
Unfortunately the third party tool from the user did not support another authentication mechanism than MONGODB-CR, so it was required to change the mechanism back to the defaults of pre MongoDB 3.x.
This problem did not only occur to me, a MongoDB issue was recently (March 2015) opened (SERVER-17459: Users can't authenticate with authenticationMechanisms=MONGODB-CR) and proves that third party tools are not aware (yet) of a change of the authentication mechanism.
To my big surprise there seems to be lack of downward compatiblity, however if this would have been an older MongoDB 2.x server and it was upgraded to MongoDB 3.x, the db user would have been compatible to both mechanisms. Yet on a new and fresh install only SCRAM-SHA-1 works. Great... >.<
OK, back to solving the issue. The goal was to change the authentication mechanism from SCRAM-SHA-1 to MONGODB-CR.
Funnily the authentication mechanism (called authSchema in MongoDB) cannot be changed while authentication is active, the following error appeared when I tried:
"errmsg" : "not authorized on admin to execute command { update: \"system.version\", updates: [ { q: { _id: \"authSchema\" }, u: { _id: \"authSchema\", currentVersion: 3 }, multi: false, upsert: true } ], ordered: true }"
So I first disabled the authentication, restarted MongoDB server and then changed the authSchema value to 3 (which stands for MONGODB-CR or better said was the "old default"):
grep auth /etc/mongod.conf
#noauth = true
#auth = true
# path to a key file storing authentication info for connections
/etc/init.d/mongod restart
mongo
MongoDB shell version: 3.0.2
connecting to: test
> use admin
switched to db admin
> var schema = db.system.version.findOne({"_id" : "authSchema"})
> schema.currentVersion = 3
3
> db.system.version.save(schema)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> exit
bye
Now enabled authentication in /etc/mongod.conf and restart again:
sed -i "s/#auth/auth/" /etc/mongod.conf
grep auth /etc/mongod.conf
#noauth = true
auth = true
# path to a key file storing authentication info for connections
/etc/init.d/mongod restart
I actually thought this was it - but yet again the authentication failed:
2015-05-20T11:57:58.755+0200 I ACCESS [conn7] Failed to authenticate dbuser@LOG with mechanism MONGODB-CR: AuthenticationFailed MONGODB-CR credentials missing in the user document
Back in MongoDB I verified if there was still some wrong reference to the SCRAM-SHA-1 mechanism, and indeed I found it:
> use admin
switched to db admin
> db.system.users.find()
[...]
{ "_id" : "LOG.dbuser", "user" : "dbuser", "db" : "LOG", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "XXXXXXXXXXXXXXXXXXXXXXXX", "storedKey" : "XXXXXXXXXXXXXXXXXXXXXXXXXXX", "serverKey" : "XXXXXXXXXXXXXXXXXXXXXXXXXXX" } }, "roles" : [ { "role" : "readWrite", "db" : "LOG" }, { "role" : "dbAdmin", "db" : "LOG" }, { "role" : "dbOwner", "db" : "LOG" } ] }
Because the default authentication mechanism is now set to MONGODB-CR, I decided to drop the user and recreate it:
> use LOG
switched to db LOG
> db.dropUser("dbuser")
true
> db.createUser ( { user: "dbuser", pwd: "XXXXXXXX", roles: [ "readWrite", "dbAdmin", "dbOwner" ] } )
Successfully added user: { "user" : "dbuser", "roles" : [ "readWrite", "dbAdmin", "dbOwner" ] }
The system user entry in the admin db looked a bit different now and contained the credentials with the MONGODB-CR schema:
> use admin
switched to db admin
> db.system.users.find()
[...]
{ "_id" : "LOG.dbuser", "user" : "dbuser", "db" : "LOG", "credentials" : { "MONGODB-CR" : "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }, "roles" : [ { "role" : "readWrite", "db" : "LOG" }, { "role" : "dbAdmin", "db" : "LOG" }, { "role" : "dbOwner", "db" : "LOG" } ] }
> exit
After this change, the user was finally able to log in with the third party tool:
2015-05-20T12:57:22.219+0200 I NETWORK [initandlisten] connection accepted from remote.example.com:63726 #9 (1 connection now open)
2015-05-20T12:57:22.226+0200 I ACCESS [conn9] authenticate db: LOG { authenticate: 1, nonce: "xxx", user: "dbuser", key: "xxx" }
2015-05-20T12:57:22.228+0200 I NETWORK [conn9] end connection remote.example.com:63726 (0 connections now open)
Once again: Too bad MongoDB didn't supply a backward compatibility to support both authentication methods in Mongo 3.x.
Now I had to set the default to a lower security standard to guarantee compatibility with the user's third party tools.
Ian from Earth wrote on Oct 2nd, 2017:
Thanks this post has helped me solve a problem I was stuck for two days!
Kudos reflected in my Stackoverflow question here
https://stackoverflow.com/a/46532504/55640
Pepe from Málaga wrote on May 8th, 2016:
Thanks for your post. Peopole like you make great Internet.
Kai from U.S. wrote on Apr 4th, 2016:
Very nice, step by step. Worked for me (3.2).
nag from Bangalore wrote on Nov 2nd, 2015:
This could have saved my day.I had problems in loging in to the DB.This is the exact solution I was looking for.But I had looked at the jira ticket-https://jira.mongodb.org/browse/SERVER-17459 and got it working,(by adding a new admin user to the db). Anywasy your solution is good fix.Thanks for this post.
Sascha from DE wrote on Sep 10th, 2015:
Perfect, thank you!
Rubens from Brazil wrote on Jun 21st, 2015:
Works perfectly! Thanks a lot.
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder