Skip to content

Latest commit

 

History

History
264 lines (176 loc) · 8.1 KB

MongoDB - production setup.md

File metadata and controls

264 lines (176 loc) · 8.1 KB

http://docs.mongodb.org/manual/tutorial/deploy-replica-set-with-auth/

http://docs.mongodb.org/manual/reference/configuration-options/

MongoDB

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

Production setup

Resources:

Following notes are for Debian Jessie and MongoDB version 3.0 (current at this time).

Installation

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

A few notes about SSL

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

Member 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).
  • O, OU and DC 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 the serverAuth attribute,
  • the certificate you specify to clusterFile requires the clientAuth 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.

Client certificates

(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.

SSL CA setup

TBD (maybe).

Have a look at my OpenSSL tips how to create your own private CA, generate keys and sign certificates.

Configuration

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

Initiate replica set

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.

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" : ...
}

Add another member to replica set

rs.add('node2.example.com:27017')

Disable transparent hugepages

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 %}

Links