diff --git a/README.md b/README.md index d422946..cc5ef59 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,10 @@ In your Package Manager settings add the following package source for developmen cappedCollectionSize="Long" cappedCollectionMaxItems="Long" databaseName="String" - includeDefaults="Boolean"> + includeDefaults="Boolean" + useTls="Boolean" + clientCertificate="String" + clientCertificatePassword="String"> @@ -65,6 +68,12 @@ _connectionString_ - Connection string. When provided, it overrides the values s _databaseName_ - The name of the database, overrides connection string database. +_useTls_ - If a Tls connection should be established. + +_clientCertificate_ - The certificate to use when establishing a Tls connection. + +_clientCertificatePassword- - The certificate's password. + ### Collection Options _collectionName_ - The name of the MongoDB collection to write logs to. diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..573dc04 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,12 @@ +version: '3.1' + +services: + + mongo: + image: mongo + restart: always + volumes: + - ./tls/:/etc/tls + ports: + - "27017" + command: --tlsMode requireTLS --tlsCertificateKeyFile /etc/tls/mongodb.pem diff --git a/src/NLog.Mongo/MongoTarget.cs b/src/NLog.Mongo/MongoTarget.cs index 554fe50..46f192e 100644 --- a/src/NLog.Mongo/MongoTarget.cs +++ b/src/NLog.Mongo/MongoTarget.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; using System.Reflection; using System.Runtime.InteropServices; using MongoDB.Bson; @@ -161,6 +163,26 @@ public string CollectionName /// public bool IncludeEventProperties { get; set; } + /// + /// Gets or sets if TLS should be used when connecting to MongoDB + /// + public bool UseTls { get; set; } + + /// + /// Gets or sets the client certificate to use when connecting to MongoDB + /// + public string ClientCertificate { get; set; } + + /// + /// Gets or sets the client certificate password to use when connecting to MongoDB + /// + public string ClientCertificatePassword { get; set; } + + /// + /// Gets or sets the Check Certificate Revocation when connecting to MongoDB + /// + public bool? CheckCertificateRevocation { get; set; } + /// /// Initializes the target. Can be used by inheriting classes /// to initialize logging. @@ -404,8 +426,26 @@ private IMongoCollection GetCollection() databaseName = !string.IsNullOrEmpty(databaseName) ? databaseName : (mongoUrl.DatabaseName ?? "NLog"); collectionName = !string.IsNullOrEmpty(collectionName) ? collectionName : "Log"; InternalLogger.Info("Connecting to MongoDB collection {0} in database {1}", collectionName, databaseName); + + var settings = MongoClientSettings.FromUrl(mongoUrl); + + if (UseTls) + { + var cert = new X509Certificate2(ClientCertificate, ClientCertificatePassword); + + if (cert == null) + { + throw new InvalidOperationException("Unable to load certificate"); + } + + settings.SslSettings = new SslSettings + { + ClientCertificates = new[] { cert }, + }; + UseTls = true; + } - var client = new MongoClient(mongoUrl); + var client = new MongoClient(settings); // Database name overrides connection string var database = client.GetDatabase(databaseName); diff --git a/test/NLog.Mongo.ConsoleTest/NLog.config b/test/NLog.Mongo.ConsoleTest/NLog.config index e9abc6c..8ab66a5 100644 --- a/test/NLog.Mongo.ConsoleTest/NLog.config +++ b/test/NLog.Mongo.ConsoleTest/NLog.config @@ -13,7 +13,10 @@ + cappedCollectionSize="26214400" + useTls="true" + clientCertificate="/home/administrator/src/github/NLog.Mongo/src/tls/mongodb.pem" + clientCertificatePassword="mongo"> @@ -27,21 +30,27 @@ connectionString="mongodb://localhost" databaseName="CustomLogging" collectionName="DefaultLog" - cappedCollectionSize="26214400"> + cappedCollectionSize="26214400" + useTls="true" + clientCertificate="/home/administrator/src/github/NLog.Mongo/src/tls/mongodb.pem" + clientCertificatePassword="mongo"> - + + cappedCollectionSize="26214400" + useTls="true" + clientCertificate="/home/administrator/src/github/NLog.Mongo/src/tls/mongodb.pem" + clientCertificatePassword="mongo"> diff --git a/tls/create-cert.md b/tls/create-cert.md new file mode 100644 index 0000000..cc912f7 --- /dev/null +++ b/tls/create-cert.md @@ -0,0 +1,17 @@ +# https://medium.com/@rajanmaharjan/secure-your-mongodb-connections-ssl-tls-92e2addb3c89 + +# root ca +openssl genrsa -out rootCA.key 2048 +openssl genrsa -des3 -out rootCA.key 2048 # password is mongo +openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem + +# per device +openssl genrsa -out mongodb.key 2048 +# Whatever you see in the address field in your browser when you go to your device +# must be what you put under common name, even if it’s an IP address. +openssl req -new -key mongodb.key -out mongodb.csr # answer Common Name (eg, YOUR name) []: localhost + +openssl x509 -req -in mongodb.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out mongodb.crt -days 500 -sha256 +cat mongodb.key mongodb.crt > mongodb.pem + +# run mongo using docker-compose or the following command: mongod --tlsMode requireTLS --tlsCertificateKeyFile tls/mongodb.pem \ No newline at end of file