Contents


Connect your Docker container to enterprise services with the IBM Cloud Secure Gateway

Comments

The IBM Cloud Secure Gateway can be leveraged to create secure connections to backend enterprise services. This tutorial shows you how to configure the service in IBM Cloud, how to configure a Docker container to connect to the service from your local machine, and then how to use the service in your IBM Cloud application to securely tunnel through the Docker container to a service available from your local machine.

What you'll need to build your application

You need an IBM Cloud account.

You also need, already set up and running on a local machine, the following:

  • An Ubuntu virtual machine with 2GB RAM (I use version v14.04.3)
  • A Docker container
  • A CouchDB v1.6.1 instance

The example described here demonstrates how to connect to the CouchDB from a Node.js IBM Cloud application using the Secure Gateway server.

Step 1. Add Secure Gateway to your application

  1. Create a sample application in IBM Cloud, selecting the SDK for Node.js Runtime. This runtime provides an easy way to get an application up and running quickly. I have named my app "DLJGatewayDemo1."
  2. After the application is staged, browse to the app's Overview page and click ADD GIT at the upper right of the screen.
  3. Select CREATE GIT REPOSITORY, making sure you opt to populate the repository with the starter application.
  4. From the app's Overview page, click ADD A SERVICE OR API.
  5. Scroll down to the Integration services and select the Secure Gateway service. To find it quickly, use the Services filter on the left and select Integration.
  6. Click CREATE to add the service, then restage the application.

Step 2. Configure the Secure Gateway

  1. From the app's Overview page, click on the Secure Gateway service to open the Secure Gateway dashboard.
  2. Click on Add Gateway to create a new Gateway. Provide a name for it, such as "DemoDB."
  3. Click Add Destinations. Create Gateway
    Create Gateway
  4. A single gateway can be used to support multiple destinations. This means that you can set up one gateway on your local machine and use it to connect to different local destinations. The destination is the endpoint that your local machine will be exposing through the Secure Gateway. In this case, I'm exposing CouchDB, so I provide the IP address and port for my instance of CouchDB that is accessible from the local machine running the Docker container. Screenshot showing create destinations
    Screenshot showing create destinations
  5. Next, decide the security to use. If you choose TCP or HTTP, no additional security from the client is required. While this is great for development, to ensure that this really is a "secure gateway," security needs to be added. I choose TLS: Mutual Auth, which requires that the IBM Cloud application that uses my local machine CouchDB provide a certificate in order to connect. I click Advanced and then select Mutual Auth under TLS options.
  6. Make sure to check Auto generate cert and private key, otherwise you will need to generate it later. Optionally, you can upload your own certificates. Once you have completed entering your destination information, click the plus icon at the end of the destination row to add the destination. Then click I'M DONE.Create Destination
    Create Destination

Step 3. View the configuration details

  1. From the app's Overview page, click on the Secure Gateway service to open the Secure Gateway dashboard.
  2. Select the info icon on the CouchDB destination. The following information about the gateway is displayed:
    • Cloud Host:Port
    • Destination Host:Port
    • Destination ID

The Cloud Host:Port value is used by your IBM Cloud application to connect to the local CouchDB. The Destination Host:Port setting specifies the host:port that is accessible from the Docker container running on your local machine.

Configuration Details
Configuration Details

Step 4. Install Docker on local machine

You need to have already set up an Ubuntu virtual machine to run Docker on. I use an Ubuntu v14.04.3 virtual machine. For Docker installation instructions for the various Ubuntu versions, visit the Docker website.

Step 5. Download certificates for use by the Docker container

  1. Browse to the app's Overview page and click on the Secure Gateway service to open the Secure Gateway dashboard.
  2. Click on the destination—in this case, CouchDB—to open the dashboard.
  3. Click on the options gear icon for the destination and select Download Keys. This downloads a zip file that contains the certificates. Download Keys
    Download Keys

Step 6. Set up Docker to use TLS security by default

  1. Copy the certificates to a new folder in your home directory named ".docker" on the Ubuntu local machine.
  2. The zip file you downloaded has five files in it. Copy three of them as follows (where xxx is the destination ID):
    • Copy DigiCertCA2.pem to .docker/ca.pem
    • Copy xxx_cert.pem to .docker/cert.pem
    • Copy xxx_key.pem to .docker/key.pem
  3. Set the environment variables DOCKER_HOST and DOCKER_TLS_VERIFY (optionally you can use the -H and –tlsverify flags at runtime):
    $ mkdir -pv ~/.docker
    $ cp DigiCertCA2.pem ~/.docker/ca.pem
    $ cp xxx_cert.pem ~/.docker/cert.pem
    $ cp xxx_key.pem ~/.docker/key.pem
    $ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1

Step 7. Launch the Docker container establishing a secure tunnel

To establish a secure tunnel connection from the Ubuntu local machine, you need to launch the Docker container and point it at the destination ID for the IBM Cloud Secure Gateway. In the example below, I use the -D flag to enable debug, which ensures that any additional debug messages that come from the container are displayed. I also use the --net="host" flag, which allows my container to share the network stack with the local server that the container is running on (the Ubuntu local machine). The first time you run this code, it downloads the image.

$ sudo docker -D run --net="host" -it ibmcom/secure-gateway-client qxWAtZ2JWWM_prod_ng
[sudo] password for bluemix:
IBM Bluemix Secure Gateway Client version 1.0.3
<press enter for the command line>
[YYYY-MM-DD HH:MM:SS:MS][INFO] secure tunnel connected

To see the Docker command (without the flags mentioned above), open the Secure Gateway dashboard by browsing to the app's Overview page and clicking on the Secure Gateway service. Next, click on your destination—CouchDB—to open its dashboard. Finally, click on the CONNECT GATEWAY button to see the connections options, specifically the Docker command line.

Connect to Gateway
Connect to Gateway

Step 8. Test the connection

Open your browser and browse to http://cap-sg-prd-5.integration.ibmcloud.com:15133. (Alternatively, you can use cURL from the command line.)

This should result in one of two possible errors: ERR_CONNECTION_REFUSED or ERR_EMPTY_RESPONSE. This is because you configured the app to use TLS:Mutual Auth, so the client app needs to use TLS when connecting. The next step shows you how to set up an app to pass the certificates in order to allow the connection.

Step 9. Create a Node.js app to establish the secure tunnel

In this step, you create a short Node.js app that sets up the secure tunnel to the gateway and down into the local machine.

  1. First, create a file named securetunnel.js and populate it with the contents below. I'm using the net module to create a network wrapper and the tls module to establish the connection using the certificates. The net module exposes a new endpoint at localHost:8888 that is piped through the secure tunnel created by the tls module.
    var tls = require('tls');
    var fs = require('fs');
    var net = require('net');
    var tunnelPort = process.env.VCAP_APP_PORT || 8888;
    var server;
    var gatewayOptions = {
    	//host local test to bluemix
    		host: 'cap-sg-prd-5.integration.ibmcloud.com',
    		port: '15133',		
    		key: fs.readFileSync('key.pem'),
    		cert: fs.readFileSync('cert.pem'),
    		ca: fs.readFileSync('ca.pem')
    	}
    	
    //create a server end point to use as a network wrapper for the secure gateway	
    server = net.createServer(function (connListener) {
    	console.warn("net server created");
    	connListener.on('end', function() {
    		console.warn('client disconnected')
    	});
    
    	//connect to farside, local/private server
    	connectFarside(connListener, function(err, remoteSocket) {
    		if (err){
    			console.error(err);
    		}
    		console.warn('connection made')
    		remoteSocket.pipe(connListener);
    		console.warn('remote socket connected to local connListener');
    		connListener.pipe(remoteSocket);
    		console.warn('local connListener connected to remote socket');		
    	});
    });
    
    //setup listener for network wrapper on localhost:tunnelPort
    //function called when connection established and ready to tunnel requests
    //when in the function we invoke the callbackRunInTunnel which is where the code
    //runs to communicate to through the bluemix secure gateway
    server.listen(tunnelPort, function(){
    	console.warn('tunnel created at: '+ server.address().address +":"+ server.address().port);
    });
    
    //create a TLS connection to the secure gateway
    function connectFarside(conn, callback) {
        try {
        console.warn("initiating farside connection");
            var socket = tls.connect(gatewayOptions, function() {
                console.warn('tunnel connected to '+ gatewayOptions.host +":"+ gatewayOptions.port);
                callback(null, socket);
            });
            socket.on('error', function(err){
                console.warn('Socket error: ' + JSON.stringify(err));
            });
        } catch(err) {
            console.error(err)
            callback(err);
        }
    };

Step 10. Run the Node.js app

Before running the securetunnel.js app, you need to get the certificate files that were generated by the Secure Gateway service and that have been used for the Docker container. Previously, you downloaded a zip file with five files in it. Copy the following three files as follows:

  • Copy DigiCertCA2.pem to ca.pem
  • Copy xxx_cert.pem to cert.pem
  • Copy xxx_key.pem to key.pem (where xxx is the destination ID)

Place these three files in the same directory that you put your secure-conn.js app. When you run the securetunnel.js app, it will tell you the host name and port the tunnel was created on.

$ node securetunnel.js
tunnel created at: 0.0.0.0:8888

Step 11. Test the connection again

This time you will use the tunnel created by the Node.js app from the previous step. Instead of connecting to http://cap-sg-prd-5.integration.ibmcloud.com:15133, you will connect to http://localhost:8888. As before, use either a browser or cURL. I use cURL below. This time the connection works, because it is routing through the Node.js app, which creates a TLS connection to the IBM Cloud Secure Gateway. In turn, the connection is routed down to the local machine and to the CouchDB instance.

$ curl http://127.0.0.1:8888
{"couchdb":"Welcome","uuid":"b03e6f754ca999e2d7a5c919954dc33e","version":"1.6.1","vendor":{"version":"1.6.1-1","name":"Homebrew"}}

Step 12. Run the Node.js app in IBM Cloud

  1. From the app's Overview page, click on EDIT CODE.
  2. Drag and drop ca.pem, cert.pem, key.pem, and securetunnel.js into the main folder for your application code.
  3. Next, edit the package.json file to tell it to run securetunnel.js instead of app.js. Change the code from
    "scripts": {
    	"start": "node app.js"
    },

    to this:

    "scripts": {
    	"start": "node securetunnel.js"
    },
  4. Save and deploy your code.

Step 13. Test the connection through IBM Cloud

This time you will use the tunnel created by the Node.js app deployed into IBM Cloud. Instead of connecting to http://localhost:8888, you connect to http://yourappname.mybluemix.net. You should get the same results whether you use a browser or cURL. If you add "/_utils/" to the path name (http://yourappname.mybluemix.net/_utils/) and open it in your browser, you can fully interact with CouchDB using the secure tunnel established in IBM Cloud.

$ curl http://yourappname.mybluemix.net:8888
{"couchdb":"Welcome","uuid":"b03e6f754ca999e2d7a5c919954dc33e","version":"1.6.1","vendor":{"version":"1.6.1-1","name":"Homebrew"}}

Summary

Although creating a Secure Gateway in IBM Cloud is so easy that instructions are not really necessary, the tricky part seems to be with how to secure and make use of the connection. The examples and descriptions in this tutorial have explained two nuances of this process: using TLS with Docker and using TLS in your app. Using TLS with Docker is rather straightforward once you know where to put the certificates. Using TLS in your app is a bit more advanced. The sample included is a great way to get started using a TLS-enabled Secure Gateway in your Node.js IBM Cloud apps.

So what did you accomplish? You:

  • Created a Secure Gateway in IBM Cloud
  • Configured Destinations and set up to use TLS: Mutual Auth
  • Configured a Docker container to use TLS
  • Ran the Docker container and connected to the Secure Gateway
  • Created a Node.js wrapper app to connect via TLS and expose the connection to your application
  • Tested the secure connection running your Node.js application locally
  • Tested the secure connection running your Node.js application in IBM Cloud

Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Security, Cloud computing
ArticleID=1016908
ArticleTitle=Connect your Docker container to enterprise services with the IBM Cloud Secure Gateway
publish-date=04042018