Showing posts with label openssl. Show all posts
Showing posts with label openssl. Show all posts

Saturday, October 24, 2015

Study MongoDB security by setup and configure server and client on secure line

It's been a while since my last learning on MongoDB. The last learning on MongoDB was on administration. Today, we will learn another topic of mongoDB; MongoDB security. As a general for MongoDB security context, it means

Maintaining a secure MongoDB deployment requires administrators to implement controls to ensure that users and applications have access to only the data that they require. MongoDB provides features that allow administrators to implement these controls and restrictions for any MongoDB deployment.

This article is reference the official documentation which can be found here. As the security context is pretty huge, in this short article, we will focus how to setup mongdb server to use on ssl and how client will access the database resource securely.

First, make sure you have install the server and client package. If you are on deb package linux distribution, it is as easy as sudo apt-get install mongodb-clients mongodb-server. Once both packages are install, you can check in the log file at /var/log/mongodb/mongodb.log similar such as the following. So our mongodb version is 2.6.3 and it has support using openssl library.

 2015-09-27T16:04:48.849+0800 [initandlisten] db version v2.6.3  
 2015-09-27T16:04:48.849+0800 [initandlisten] git version: nogitversion  
 2015-09-27T16:04:48.849+0800 [initandlisten] OpenSSL version: OpenSSL 1.0.1f 6 Jan 2014  

Next, let's generate a public and private key and a self sign certifcate.

 user@localhost:~/test1$ openssl req -newkey rsa:2048 -new -x509 -days 365 -nodes -out mongodb-cert.crt -keyout mongodb-cert.key  
 Generating a 2048 bit RSA private key  
 .............................+++  
 ..................................................................................................................................................................................................................+++  
 writing new private key to 'mongodb-cert.key'  
 -----  
 You are about to be asked to enter information that will be incorporated  
 into your certificate request.  
 What you are about to enter is what is called a Distinguished Name or a DN.  
 There are quite a few fields but you can leave some blank  
 For some fields there will be a default value,  
 If you enter '.', the field will be left blank.  
 -----  
 Country Name (2 letter code) [AU]:MY  
 State or Province Name (full name) [Some-State]:KL  
 Locality Name (eg, city) []:Kuala Lumpur  
 Organization Name (eg, company) [Internet Widgits Pty Ltd]:example.com  
 Organizational Unit Name (eg, section) []:Engineering  
 Common Name (e.g. server FQDN or YOUR name) []:Jason Wee  
 Email Address []:jason@example.com  
 user@localhost:~/test1$ ls  
 mongodb-cert.crt mongodb-cert.key  

Now put everything into a file with extension .pem.

 user@localhost:~/test1$ cat mongodb-cert.key mongodb-cert.crt > mongodb.pem  

Now, stop mongodb instance if it is running. As we will now configured the server to use the certificate we generated previously.

 user@localhost:~/test1$ sudo systemctl status mongodb  
 ● mongodb.service - An object/document-oriented database  
   Loaded: loaded (/lib/systemd/system/mongodb.service; enabled; vendor preset: enabled)  
   Active: inactive (dead) since Sun 2015-09-27 16:13:34 MYT; 23min ago  
    Docs: man:mongod(1)  
  Main PID: 15343 (code=exited, status=0/SUCCESS)  
   
 Sep 27 16:04:48 localhost systemd[1]: Started An object/document-oriented database.  
 Sep 27 16:04:48 localhost systemd[1]: Starting An object/document-oriented database...  
 Sep 27 16:13:33 localhost systemd[1]: Stopping An object/document-oriented database...  
 Sep 27 16:13:34 localhost systemd[1]: Stopped An object/document-oriented database.  
 Sep 27 16:36:30 localhost systemd[1]: Stopped An object/document-oriented database.  
 user@localhost:~/test1$ sudo tail -10 /etc/mongodb.conf   
 # Size limit for in-memory storage of op ids.  
 #opIdMem = <bytes>  
   
 # SSL options  
 # Enable SSL on normal ports  
 sslOnNormalPorts = true  
 # SSL Key file and password  
 #sslPEMKeyFile = /etc/ssl/mongodb.pem  
 sslPEMKeyFile = /home/user/test1/mongodb.pem  
 #sslPEMKeyPassword = pass  
 user@localhost:~/test1$   

In the above output, as an example, I have set the file mongodb.pem to the configuration sslPEMKeyFile and also set sslOnNormalPorts to true. Now if you start mongodb instance.

 user@localhost:~/test1$ sudo systemctl start mongodb  
 user@localhost:~/test1$   

In the log file, noticed that ssl is enabled and no ssl related error.

 2015-09-27T16:46:41.648+0800 [initandlisten] options: { config: "/etc/mongodb.conf", net: { bindIp: "127.0.0.1", ssl: { PEMKeyFile: "/home/user/test1/mongodb.pem", mode: "requireSSL" } }, storage: { dbPath: "/var/lib/mongodb", journal: { enabled: true } }, systemLog: { destination: "file", logAppend: true, path: "/var/log/mongodb/mongodb.log" } }  
 2015-09-27T16:46:41.788+0800 [initandlisten] journal dir=/var/lib/mongodb/journal  
 2015-09-27T16:46:41.797+0800 [initandlisten] recover : no journal files present, no recovery needed  
 2015-09-27T16:46:42.162+0800 [initandlisten] waiting for connections on port 27017 ssl  

On the server configuration and setup, it is now done. Now, we will focus on the mongdb client. If you connect to mongodb using its client, you will get error.

 user@localhost:~/test1$ mongo foo  
 MongoDB shell version: 2.6.3  
 connecting to: foo  
 2015-09-27T17:22:54.300+0800 DBClientCursor::init call() failed  
 2015-09-27T17:22:54.302+0800 Error: DBClientBase::findN: transport error: 127.0.0.1:27017 ns: admin.$cmd query: { whatsmyuri: 1 } at src/mongo/shell/mongo.js:146  
 exception: connect failed  
 user@localhost:~/test1$ mongo --ssl --sslPEMKeyFile mongodb.pem  
 MongoDB shell version: 2.6.3  
 connecting to: test  
 Server has startup warnings:   
 2015-09-27T16:46:41.647+0800 [initandlisten]   
 2015-09-27T16:46:41.647+0800 [initandlisten] ** NOTE: This is a 32 bit MongoDB binary.  
 2015-09-27T16:46:41.647+0800 [initandlisten] **    32 bit builds are limited to less than 2GB of data (or less with --journal).  
 2015-09-27T16:46:41.647+0800 [initandlisten] **    See http://dochub.mongodb.org/core/32bit  
 2015-09-27T16:46:41.647+0800 [initandlisten]   
 > show dbs  
 admin (empty)  
 local 0.078GB  
 >   

As you can read above, you need to specify parameter ssl and the pem file. That's it for this article, if you want to go the distance, try using tcpdump to listen to this port traffic. Good luck!

Saturday, November 15, 2014

Implementing DNSSEC and DANE for email - Step by step

Note, this article is written and contributed by a good friend gryphius, so all credit goes to him. I'm just copy and paste his awesome work here. :-)

After various breaches at the certificate authorities it has become clear that we need a way to authenticate a server certificate without the need to trust a third party. “DNS-based Authentication of Named Entities“ (DANE) makes this possible by publishing the certificate in the DNS. Find more information about DANE here.

In this tutorial we show an example implementation of DANE for email delivery.

What you need

  • a DNSSEC capable nameserver (in this example: powerdns)
  • a DNSSEC capable registrar  (in this example: gandi.net)
  • a mail server with TLS Support (in this example: postfix )
  • to test the secured email delivery: a second mailserver with DANE support ( postfix >=2.11, DNSSEC capable resolver )
We start off with a postfix server already configured to accept mail for our domain, but no TLS support so far. Let’s add this now by generating a self-signed certificate:
in this state, a sending server can encrypt the transmission, but it can not verify the self-signed server certificate, so it  will treat the TLS connection as anonymous:
postfix/smtp[13330]: Anonymous TLS connection established to mail.example.com[...]:25: TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)
In order to enable DANE support, our domain’s DNS zone must be secured with DNSSEC. Our example domain is hosted on a powerdns authoritative server securing a zone on a current powerdns is pretty easy:

The key from the last command must be copied to the registrar. At gandi.net the form to add a DNSSEC key looks like this:

dnssec-gandinet

Once the key is added and synchronized on the registry’s DNS servers, you can test DNSSEC funconality at http://dnssec-debugger.verisignlabs.com/

Now, back on the mailserver hosting our domain we have to create a hash of the SSL-certificate:

Using this value  we can add the DANE TLSA record for our mailserver in the DNS zone:

In powerdns, add a record:
Name_25._tcp.mail.example.com (replace mail.example.com with your real mx hostname)
TypeTLSA
Content3 0 1 02059728e52f9a58a235584e1ed70bd2b51a44024452ec2ba0166e8fb1d1d32b

the “3 0 1” means: “we took a full domain-issued certificate, and created a sha256 hash of it”. For other possible values see RFC6698 section 7.2 – 7.4.

Now we can test the new DANE TLSA records at https://www.tlsa.info

And finally, let’s test it from another postfix box. For this to work, the sending server must use a DNSSEC resolver (for example unbound) and postfix >=2.11 with DANE enabled:

and voilĂ , our connection is now verified even though we’re using a self-signed certificate:

postfix/smtp[17787]: Verified TLS connection established to mail.example.com[...]:25: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)

References:

Sunday, September 14, 2014

How to convert java keystore to format apache httpd understand

If you received a java keystore file from a Certificate Authority and want to use this cert to setup in apache httpd ssl, you will meet failure, at least I did. So today, I will share my finding on how to convert java keystore file into PEM format which is understand by apache httpd.

So how do you know if a certificate signed by CA is of type java keystore? Simple, just check the content using keytool. Keytool is an app come together when you install java environment.
$ keytool -list -keystore abc.jks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

ABC_Certificate, Aug 19, 2013, PrivateKeyEntry,
Certificate fingerprint (MD5): 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00

As you can read above, this is a valid java keystore file and we will now convert to a intermittent format, pkcs12 first. We will use keytool again to do the conversion.
$ keytool -importkeystore -srckeystore abc.jks -destkeystore abc.p12 -srcalias ABC_Certificate -srcstoretype jks -deststoretype pkcs12
Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
$

the output abc.p12 is the certificate in pkcs12 and now we are ready to convert to pem format. We will use openssl to do this conversion.
$ openssl pkcs12 -in myapp.p12 -out myapp.pem
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
$

You can basically use myapp.pem for the field in SSLCertificateFile and SSLCertificateKeyFile but unfortunately when apache httpd is restarted, it will ask for the private key passphrase. With the following steps, we will remove the passphrase from the private key.

Removed passphrase so when apache httpd instance is restarted, it will not ask for password.
$ openssl rsa -in abc.pem -out abc_private_key.pem
Enter pass phrase for abc.pem:
writing RSA key
$ openssl x509 -in abc.pem >>abc_cert.pem

As you noticed, right now you end up with the certificate private key and the certificate. Now move these two files, abc_private_key.pem and abc_cert.pem to a directory in the apache httpd server and change the ssl configuration in apache httpd.
SSLCertificateFile    /path/to/the/directory/contain/abc_cert.pem
SSLCertificateKeyFile /path/to/the/directory/contain/abc_private_key.pem

That's it, I hope it works for you too.