I am deploying my first little app with MongoDB
and Mongoid
as a driver.
What is the right secure way to use MongoDB in production?
I mean in the development I have just started mongod
and that's it - no username or password needed and that looks unsecure.
Also Mongoid sets default configurations
production:
host: <%= ENV['MONGOID_HOST'] %>
port: <%= ENV['MONGOID_PORT'] %>
username: <%= ENV['MONGOID_USERNAME'] %>
password: <%= ENV['MONGOID_PASSWORD'] %>
database: <%= ENV['MONGOID_DATABASE'] %>
How should I configure this options and entire MongoDB on my production server?
To create a production environment where you need to use a username and password to connect:
In the mongo console:
// Add an Admin User (to the admin db)
use admin
db.addUser("theadmin", "anadminpassword")
// Use your database
use supercool
// Add a user (to your database)
db.addUser("joe", "passwordForJoe")
// show all users:
db.system.users.find()
// add readonly user (kinda cool)
db.addUser("readonly", "passwordForJoe", true)
Now, all connections to your mongodb will require authentication -- http://www.mongodb.org/display/DOCS/Security+and+Authentication
Also: you can consider using your linux firewall to only allow 27017 from your web server(s).
MongoDB by default doesn't support authentication. This is by design and is expected to be handled by individual applications. But it is not too hard to enable authenticated access to MongoDB. I will describe the steps I took for my typical rails, mongoid, git, capistrano based setup.
First add a user to the admin database. Without which none of the below steps work.
use admin
db.addUser("heisenberg", "knock-knock")
Create a user to the db your application will use. In MongoDB authentication works on a per db level
use breaking_bad
db.addUser("gus", "fring")
Better yet, create a user for just read-only purposes for security and performance benefits
use breaking_bad
db.addUser("walter", "white", true)
Enable the auth flag for mongodb to respect all your authentication related hardwork. This can be done either through a --auth flag to the mongodb command. Or better uncomment this line in the /etc/mongodb.conf
auth = true #Uncomment me
Now restart your mongodb process to pickup the new changes.
service mongodb restart
Check if you are on the right track by ensuring that your CRUD application now fails! It lost access to read/write from your mongodb afterall. Now add the username: and password: attributes to your mongoid.yml under the default group.
production:
sessions:
default:
database: breaking_bad
hosts:
- albuquerque.com:27017
username: gus
password: fring
For bonus points, remove the mongoid.yml file from the git repository as this file now has security credentials
git rm mongoid.yml
Add capistrano tasks that copy the mongoid.yml file from your dev machine to your server and add appropriate symlinks. Run cap deploy
after this
namespace :mongoid do
desc "Copy mongoid config"
task :copy do
upload "config/mongoid.yml", "#{shared_path}/mongoid.yml", :via => :scp
end
desc "Link the mongoid config in the release_path"
task :symlink do
run "test -f #{release_path}/config/mongoid.yml || ln -s #{shared_path}/mongoid.yml #{release_path}/config/mongoid.yml"
end
end
Use the bind_ip setting in your /etc/mongodb.conf to tell MongoDB to only accept connections from your webserver
Use iptables to setup firewall settings to further secure your setup. Or use it within a VPN.
Further reading:
http://docs.mongodb.org/manual/tutorial/control-access-to-mongodb-with-authentication/
http://docs.mongodb.org/manual/administration/security/