Graylog2 / graylog2-server

Free and open log management
https://www.graylog.org
Other
7.38k stars 1.06k forks source link

add certificate authentication to mongod #4472

Open jalogisch opened 6 years ago

jalogisch commented 6 years ago

Context

You should be able to secure your Mongo Cluster with SSL certificates and certificate validation. If you run a Cluster with certificate validation, activated with the following configuration:

net:
   ssl:
      mode: requireSSL
      PEMKeyFile: /etc/ssl/mongodb.pem
      CAFile: /etc/ssl/ca.pem

The Cluster/Server expect that every client provide a client certificate. With the given configuration options in Graylog ( http://api.mongodb.com/java/current/com/mongodb/MongoClientURI.html ) providing this configuration is not possible.

Graylog is only able to connect to a Mongo Cluster/Server that has SSL enabled with the given string.

mongodb_uri = mongodb://localhost/graylog?ssl=true

This works only if you have added your (internal) CA to the java keystore that is used by Graylog.

feature request

Add the configuration (and client) option to include certificates for authentication

Additional information

Your Environment

joschi commented 6 years ago

With the given configuration options in Graylog […] providing this configuration is not possible.

Why not? IMHO all necessary parts are there (although not too user-friendly and as always under-documented):

isodude commented 2 years ago

In most software one can specify which certificate to use, this could be one of many reasons to most obvious being security.

I want to use LoadCredential= in systemd where the certificate, which is rotated quite often. The certificate is copied to a path only readable by the user running the service.

This works great with graylog-server with the listening side of things. It thus make sense that this should be the case for the client side as well.

If there's a need to create a keystore, why can't graylog-server handle that on startup?

The endgame here is to allow a simple restart on the service to refresh the client certificates. Sure it's possible to generate keystores etc, but it does not make sense that it should be that much extra effort to make it work. TLS should be very easy to set up so that more people use it.

vikshith-s commented 9 months ago

Overcame same issue by defining trust store and cacert. Would be nice to have an option to directly define certificate paths within configs.

isodude commented 8 months ago

This is actually a limit with the mongod driver. Reading the "docs" in the driver test reveals this nugget:

openssl pkcs12 -CAfile ${DRIVERS_TOOLS}/.evergreen/x509gen/ca.pem -export -in ${DRIVERS_TOOLS}/.evergreen/x509gen/client.pem -out client.pkc -password pass:bithere

If you specify that file (client.pkc) as keyStore to graylog-server, it actually connects to mongodb with and presents a client certificate. This should at least be well documented.

isodude commented 8 months ago

What would make things simpler here, given that you would need to write a hook for e.g. letsencrypt, is to add certificates to the keystore via the configuration.

certificates:
  keyStore:
  - /etc/ssl/mongod.pem
  trustStore:
  - /etc/ssl/ca.pem

And internally just add them to the store as you see fit.

For what it's worth, here's a small write up. The mongosh part was especially troublesome since the tool did not provide any info that I needed --tlsAllowInvalidHostnames and that you should escape / with %2F to be able to connect to a socket.

Would that suffice to document @jalogisch?

net:
   tls:
      mode: requireTLS
      PEMKeyFile: /etc/ssl/mongodb.pem
      CAFile: /etc/ssl/ca.pem
security:
  clusterAuthMode: x509

Add to graylog config

mongodb_uri = mongodb://localhost/graylog?ssl=true

I ended up adding &authMechanism=MONGODB-X509 to the mongodb_uri, but it should suffice as above as the client chooses the best auth mechanism by itself.

Add to /etc/default/graylog-server

GRAYLOG_SERVER_JAVA_OPTS="$GRAYLOG_SERVER_JAVA_OPTS -Djavax.net.ssl.keyStore=/etc/graylog/graylog.keystore -Djavax.net.ssl.keyStorePassword=changeme"

Generate the password store

openssl pkcs12 -CAfile /etc/ssl/ca.pem -export -in /etc/ssl/mongodb.pem -out /etc/graylog/graylog.keystore -password pass:changeme

Create the user with mongosh

use $external
db.createUser({
    user: 'CN=<hostname>',
    roles: [
      { role: 'readWrite', db: 'graylog' },
      { role: 'userAdminAnyDatabase', db: 'admin' }
    ]
  })

A simple way to connect to mongodb through the socket

mongosh --shell --tls --tlsAllowInvalidHostnames --tlsCAFile /etc/ssl/ca.pem  --tlsCertificateKeyFile /etc/ssl/mongodb.pem mongodb://admin:pass@%2Ftmp%2Fmongodb-27017.sock