IBM Support

Installing NodeJS as a Source Dependency

How To


Summary

This tutorial will outline how you can install NodeJS as a source dependency for your app; alongside replacing the default Flask webserver with a NodeJS Express server.

Steps

Prerequisites

  • QRadar App SDK v2
  • Docker
  • NodeJS and NPM installed

Create the App

Create a new folder for your app:


mkdir NodeJSApp && cd NodeJSApp

Use the QRadar App SDK to initialise the app code:

qapp create

Add the NodeJS and NPM RPMs

Make a new folder for storing the NodeJS and NPM RPMs that will be installed called container/rpm.

mkdir container/rpm

Download the latest NodeJS and NPM RPMs for RHEL UBI 8 using Docker:

docker run                                                    \
    -v $(pwd)/container/rpm:/rpm                              \
    registry.access.redhat.com/ubi8/ubi                       \
    yum download nodejs-10.21.0 npm-6.14.4 --downloaddir=/rpm

This will use the RHEL UBI 8 OS running inside Docker to download the NodeJS and NPM RPMs which can be used by QRadar to install them into the app.

Make a new file called container/rpm/ordering.txt which will tell QRadar where to find the RPMs to install:

nodejs-10.21.0-3.module+el8.2.0+7071+d2377ea3.x86_64.rpm
npm-6.14.4-1.10.21.0.3.module+el8.2.0+7071+d2377ea3.x86_64.rpm

These file paths should match the file names of the RPMs you have downloaded.

Write the Manifest

Open the manifest.json file to edit some values to make it more relevant to the app, making it look like this

{
  "name": "NodeJSApp",
  "description": "App that uses NodeJS and an Express server",
  "version": "1.0.0",
  "image": "qradar-app-base:2.0.0",
  "load_flask": "false",
  "areas": [
    {
      "description": "Dummy tab that displays text from the node app",
      "id": "NodeJSHelloWorld",
      "named_service": "nodeservice",
      "required_capabilities": [],
      "text": "NodeHelloWorld",
      "url": "/index"
    }
  ],
  "services": [
    {
      "command": "node /opt/app-root/app/server.js",
      "directory": "/opt/app-root/app",
      "endpoints": [
        {
          "name": "appindexpage",
          "path": "/index",
          "http_method": "GET"
        }
      ],
      "name": "nodeservice",
      "path": "/index",
      "port": 5000,
      "version": "1",
      "stdout_logfile": "/opt/app-root/store/log/node_out.log",
      "stderr_logfile": "/opt/app-root/store/log/node_err.log"
    }
  ],
  "uuid": "<your unique app UUID>"
}

This manifest defines a lot, first the Flask webserver is overridden and QRadar is informed it should not be loaded with:

"load_flask": "false",

The manifest then defines an 'area' in the QRadar UI to display the app, called NodeJSHelloWorld that is populated by calling the /index endpoint in the named service called nodeservice:

"areas": [
  {
    "description": "Dummy tab that displays text from the node app",
    "id": "NodeJSHelloWorld",
    "named_service": "nodeservice",
    "required_capabilities": [],
    "text": "NodeHelloWorld",
    "url": "/index"
  }
],

Finally the manifest describes and defines a named service which is a custom command that will run our NodeJS Express server, exposing the path /index. This named service also includes a command to run the NodeJS server, alongside paths to output logs to:

"services": [
  {
    "command": "node /opt/app-root/app/server.js",
    "directory": "/opt/app-root/app",
    "endpoints": [
    {
        "name": "appindexpage",
        "path": "/index",
        "http_method": "GET"
    }
    ],
    "name": "nodeservice",
    "path": "/index",
    "port": 5000,
    "version": "1",
    "stdout_logfile": "/opt/app-root/store/log/node_out.log",
    "stderr_logfile": "/opt/app-root/store/log/node_err.log"
  }
],

These elements combined define how our NodeJS Express erver will be called and displayed as part of the QRadar UI.

Set up NPM to Manage Dependencies

Remove the app/ folder, and recreate it as an empty folder:

rm -r app/ && mkdir app/ && cd app/

Now use NPM to create a package.json file for managing your app's NodeJS dependencies.

npm init

Answer the questions prompted, and it will generate you a package.json file which will look something like this:

{
  "name": "nodejs_app",
  "version": "1.0.0",
  "description": "App that uses NodeJS and an Express server",
  "main": "server.js",
  "author": "IBM",
  "license": "<your license>"
}

Next we will install express as a dependency, we simply run the command:

npm install --save-dev express

We now have express as a dependency, and a new app/node_modules/ folder generated which will store our dependencies. It is a good idea to exclude this folder from version control.

Write the NodeJS Server

Finally we will write our JavaScript server side code, which will set up some HTTP endpoints that will respond with a simple message when accessed; create a new file called app/server.js:

const express = require('express')

const app = express()

app.get('/index', (req, res) => res.send('Hello World!'))

app.get('/debug', (req, res) => res.send('Pong!'))

app.listen(5000, () => console.log('Server running on port 5000!'))

Run the App/Package the App

Before running/packaging your app, make sure you pull your app's NPM dependencies down into the app/node_modules folder - this is vital to ensure the app can be installed and run without internet access:

cd app && npm install && cd ..

The app can then be run locally from the project root with:

qapp run

Or packaged and deployed from the project root with:

qapp package -p <app zip name>

qapp deploy -p <app zip name> -q <qradar console> -u <qradar user>

Document Location

Worldwide

[{"Line of Business":{"code":"LOB24","label":"Security Software"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SSBQAC","label":"IBM Security QRadar SIEM"},"ARM Category":[{"code":"a8m0z000000cwt3AAA","label":"QRadar Apps"}],"ARM Case Number":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"All Version(s)"}]

Document Information

Modified date:
30 March 2021

UID

ibm16437451