Connect Drupal-7.x (Linux) with SQL Server 2008R2 via NodeJS (Windows) Part 2 of 3

Part 2: Installation & Configuration of SSL for NodeJS.
Table of Content:
  1. Part 1: Installation & Configuration of SQL Server Driver for NodeJS.
  2. Concept
  3. Note
  4. Requirement
  5. Create Certificates
  6. Deploy NodeJS test server
  7. PHP Curl script example
  8. Part 3
Concept

In order to communicate securely, we need to encrypt the connection between our client (PHP) and server (NodeJS) via SSL protocol.

Note

For this article, we assume that our NodeJS server IP is: 125.0.0.1 and the PHP (XAMPP) server IP is: 192.168.0.1

LET’S BEGIN…

Requirement
  1. OpenSSL. I suggest using Linux box version.

First we create self-signed certificate for our CA, server and client. The server (NodeJS) will be using the ca.crt, server.crt and server.key. The client (PHP) will be using ca.crt, client.crt and client.key.

Create Certificates
  1. Create the self-signed CA Key and Certificate for signing Client Certs:
    openssl genrsa -des3 -out ca.key 4096
    openssl req -new -x509 -days 365 -key ca.key -out ca.crt
  2. Create the Server Key, CSR, and Certificate:
    <TODAY> is in the format: YYMMDDHHMM
    Make sure you enter 125.0.0.1 for the hostname field.

    openssl genrsa -des3 -out server.key 1024
    openssl rsa -in server.key -out server.key
    openssl req -new -key server.key -out server.csr
    openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial <TODAY> -out server.crt
  3. Create the Client Key, CSR, and Certificate:
    Make sure you enter 125.0.0.1 for the hostname field.

    openssl genrsa -des3 -out client.key 1024
    openssl rsa -in client.key -out client.key
    openssl req -new -key client.key -out client.csr
    openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial <TODAY> -out client.crt

If you decide to use the real CA (VeriSign, GeoHost, etc), you can send your CSR files to them.

Deploy NodeJS test server

Now we ready for the server. Create folder ssl and inside it create folder cert. Copy files ca.crt, server.key and server.crt to folder ssl/cert. Here’s the server NodeJS code:

var https = require('https'),      // module for https
    fs    = require('fs');         // required to read certs and keys

var options = {
  key:    fs.readFileSync('cert/server.key'),
  cert:   fs.readFileSync('cert/server.crt'),
  ca:     fs.readFileSync('cert/ca.crt'),
  requestCert:        true,
  rejectUnauthorized: false
};

https.createServer(options, function (req, res) {
  if (req.client.authorized) {
    res.writeHead(200, {"Content-Type": "application/json"});
    res.end('{"status":"approved"}');
    console.log("approved");
  } else {
    res.writeHead(401, {"Content-Type": "application/json"});
    res.end('{"status":"denied"}');
    console.log("denied");
  }
}).listen(443,'125.0.0.1');

Save it with name ssl.js, and start the server with command node ssl.js

PHP Curl script example

Now copy your ca.crt, client.key and client.crt somewhere (I use XAMPP htdocs/ssl/cert folder). Create index.php inside htdocs/ssl with this simple code to test the server:

$tuCurl = curl_init();
curl_setopt($tuCurl, CURLOPT_URL, "https://125.0.0.1/");
curl_setopt($tuCurl, CURLOPT_PORT , 443);
curl_setopt($tuCurl, CURLOPT_VERBOSE, 0);
curl_setopt($tuCurl, CURLOPT_HEADER, 0);
curl_setopt($tuCurl, CURLOPT_SSLVERSION, 3);
curl_setopt($tuCurl, CURLOPT_SSLCERT, getcwd() . "/ssl/client.crt");
curl_setopt($tuCurl, CURLOPT_SSLKEY, getcwd() . "/ssl/client.key");
curl_setopt($tuCurl, CURLOPT_CAINFO, getcwd() . "/ssl/ca.crt");
curl_setopt($tuCurl, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, 1);

$tuData = curl_exec($tuCurl);
if(!curl_errno($tuCurl)){
  $info = curl_getinfo($tuCurl);
  echo 'Took ' . $info['total_time'] . ' seconds to send a request to ' . $info['url'];
} else {
  echo 'Curl error: ' . curl_error($tuCurl);
}

curl_close($tuCurl);
echo $tuData;

Now open the URL http://192.168.0.1/ssl and you should see approved message which is sent by NodeJS server. Try to change the curl SSL and you should see denied message instead.

to be continued in Part 3…

Credits:
  1. Drupal Meetup Jakarta, Friday November 30th 2012.
  2. http://blog.nategood.com/client-side-certificate-authentication-in-ngi
  3. http://blog.nategood.com/nodejs-ssl-client-cert-auth-api-rest
  4. http://php.net/manual/en/book.curl.php

Leave a comment