http://docs.mongodb.org/manual/tutorial/deploy-replica-set-with-auth/
http://docs.mongodb.org/manual/reference/configuration-options/
MongoDB is a document-oriented database.
Features:
- replication (replica sets) that is pretty easy to setup and maintain
- sharding (with multiple replica sets accessed from mongos)
- aggregation framework; I don't use it, but it's there
- plug-in engine architecture, two engines are currently included: MMAPv1 and WiredTiger
Resources:
- Production Notes
- Production Checklist
- Security Checklist
- Configure
mongod
andmongos
for TLS/SSL - Deploy Replica Set and Configure Authentication and Authorization
- MongoDB, TLS, and x.509 Authentication Deep Dive (allanbank.com)
Following notes are for Debian Jessie and MongoDB version 3.0 (current at this time).
Follow this: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-debian/
- add
deb
record to/etc/apt/sources.list.d/mongodb-org-3.0.list
sudo aptitude update
sudo aptitude install mongodb-org
Communication will be encrypted using SSL. Setup SSL CA, for example as it is described in OpenSSL.md.
MongoDB distinguishes two kinds of SSL (x.509) certificates:
- Member certificates
- Client certificates
(MongoDB docs: Use x.509 Certificate for Membership Authentication)
The member certificate, used for internal authentication to verify membership to the sharded cluster or a replica set, must have the following properties:
-
A single Certificate Authority (CA) must issue all the x.509 member certificates
-
The Distinguished Name (DN), found in the member certificate’s subject, must specify a non-empty value for at least one of the following attributes:
- Organization (
O
), - the Organizational Unit (
OU
) or - the Domain Component (
DC
).
- Organization (
-
O
,OU
andDC
must match those from the certificates for the other cluster members -
Either the Common Name (
CN
) or one of the Subject Alternative Name (SAN
) entries must match the hostname of the server, used by the other members of the cluster.
For example, the certificates for a cluster could have the following subjects:
subject= CN=<myhostname1>,OU=Dept1,O=MongoDB,ST=NY,C=US
subject= CN=<myhostname2>,OU=Dept1,O=MongoDB,ST=NY,C=US
subject= CN=<myhostname3>,OU=Dept1,O=MongoDB,ST=NY,C=US
If you use Extended Key Usage (EKU) attributes:
- The certificate that you specify for the
PEMKeyFile
option requires theserverAuth
attribute, - the certificate you specify to
clusterFile
requires theclientAuth
attribute.
If you omit clusterFile
, mongod will use the certificate specified to PEMKeyFile for member authentication,
which can be a problem if it doesn't have the clientAuth
attribute.
(MongoDB docs: Use x.509 Certificates to Authenticate Clients)
The client certificate must have the following properties:
-
A single Certificate Authority (CA) must issue the certificates for both the client and the server.
-
Client certificates must contain the following fields:
keyUsage = digitalSignature extendedKeyUsage = clientAuth
-
Each unique MongoDB user must have a unique certificate.
-
A client x.509 certificate’s subject, which contains the Distinguished Name (DN), must differ from that of a Member x.509 Certificate, with regards to at least one of the following attributes:
- Organization (
O
), - the Organizational Unit (
OU
) or - the Domain Component (
DC
).
If a client x.509 certificate’s subject has the same O, OU, and DC combination as the Member x.509 Certificate, the client will be identified as a cluster member and granted full permission on the system.
- Organization (
TBD (maybe).
Have a look at my OpenSSL tips how to create your own private CA, generate keys and sign certificates.
Create directory /etc/mongo-ssl
.
Configuration file /etc/mongodb.conf
:
TODO
Start MongoDB:
sudo /etc/init.d/mongod restart
See /var/log/mongodb/mongod.log
Run mongo
and check replica set status.
> rs.status()
{
"info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "no replset config has been received",
"code" : 94
That's OK.
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "exampleserver.example.com:27017",
"ok" : 1
}
Check status again:
lhprod1:PRIMARY> rs.status()
{
"set" : "lhprod1",
"date" : ISODate("2015-06-09T13:49:36.869Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "exampleserver.example.com:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 215,
"optime" : Timestamp(1433857746, 1),
"optimeDate" : ISODate("2015-06-09T13:49:06Z"),
"electionTime" : Timestamp(1433857746, 2),
"electionDate" : ISODate("2015-06-09T13:49:06Z"),
"configVersion" : 1,
"self" : true
}
],
"ok" : 1
}
Check replica set configuration:
lhprod1:PRIMARY> rs.conf()
2015-06-09T13:51:19.786+0000 E QUERY Error: Could not retrieve replica set config: {
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { replSetGetConfig: 1.0 }",
"code" : 13
}
at Function.rs.conf (src/mongo/shell/utils.js:1017:11)
at (shell):1:4 at src/mongo/shell/utils.js:1017
We need to create admin user.
lhprod1:PRIMARY> use admin
switched to db admin
lhprod1:PRIMARY> db.createUser({user: 'admin', pwd: 'topsecret', roles: [
{role: "userAdminAnyDatabase", db: "admin"},
{role: "root", db: "admin"}]})
Successfully added user: {
"user" : "admin",
"roles" : ...
}
rs.add('node2.example.com:27017')
Salt state:
/usr/local/sbin/disable-transparent-hugepages:
file.managed:
- mode: 755
- contents: |
#!/bin/bash
set -e
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
{% if grains.get('systemd') %}
/etc/systemd/system/disable-transparent-hugepages.service:
file.managed:
- contents: |
[Unit]
Description=Disable transparent hugepages
[Service]
ExecStart=/usr/local/sbin/disable-transparent-hugepages
Restart=never
[Install]
WantedBy=multi-user.target
service_disable_thp:
service.running:
- name: disable-transparent-hugepages
- enable: true
{% endif %}