Sometimes, it might be useful to authenticate to MongoDB using a keyfile. (This requires it to be configured to use a keyfile, mostly for replicaset / sharding internal authentication)
Use cases for this include:
- Password resets
- Authenticating on shards from a config server with the same credentials for all shards (e.g. for keyhole, which assumes that that is an option, which results in errors if shards use different passwords)
- Auto-detected credentials for scripts that need to run (as root) on multiple nodes
- Automation of operations on the database (e.g. Creating a user using Ansible, without knowing if a user already exists)
Keyfile authentication uses SCRAM (the exact variant depends on the MongoDB version), in the same way that user authentication uses it. (After stripping all whitespace)
Knowing this, I decided to search around for references of "SCRAM-SHA-1" and "keyfile" and then came across info indicating that the username used is "__system". I found hints at this in the last diff on this change in the MongoDB source code.
In order to log in to the local mongodb instance using the keyfile /etc/mongo.keygile (as root that it can be read), the following command can be used:
mongo -u __system -p "$(tr -d '[:space:]' < /etc/mongo.keyfile)" --authenticationDatabase admin
If the connection string is used instead, the password needs the be URL encoded: (This version uses Perl for URL encoding, which might not be available everywhere)
mongo "mongodb://__system:$(tr -d '[:space:]' < /etc/mongo.keyfile | perl -ple 's/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg')@localhost:27017/?authSource=admin"
Note: This will not work on a YAML keyfile, as supported in MongoDB 4.2 or later. (The password for the system user should still be possible to extract using other methods though)