Overview

This guide provides instructions for deploying NMIS Suite with NMIS 9 and commercial Modules with optional Apache reverse proxy configuration. The solution can be deployed either with a containerized MongoDB instance or configured to use an external MongoDB server.

Prerequisites

Minimum Resource Requirements

*please note these are a bare minimum, and resource requirements for production environments will depend upon the number of nodes being monitored

Additional Requirements for Full Stack (Docker Compose)

Deployment Steps

General Docker Setup (Debian 11)

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-compose

Docker Compose

  1. Create a directory for custom configurations e.g. /persistent. Change the bind volume paths in the docker-compose.yaml to point your custom configurations to the correct path inside the container.

    mkdir -p /{path}/persistent
    cd /{path}/persistent
    sudo cp /path/to/Config.nmis .
    sudo cp /path/to/opCommon.json .
    sudo cp /path/to/opLicense.json .
    sudo cp /path/to/mongod.conf .
    ...


    For development purposes, you can also mount the whole directory where your custom configurations are, to allow you to move extra files/folders between the host and the container easily e.g. importing nodes configurations

    e.g. Bind mounts for configurations go in the volumes section of each service in the docker-compose.yaml

    /persistent/mongod.conf:/etc/mongod.conf
    /persistent/Config.nmis:/usr/local/nmis9/conf/Config.nmis
    /persistent/opCommon.json:/usr/local/omk/conf/opCommon.json
    /persistent/opLicense.json:/usr/local/omk/conf/opLicense.json (optional)
    /persistent:/persistent (optional)
    /persistent/snmpd.conf:/etc/snmp/snmpd.conf (optional)


    NOTE
    Don’t change the volume mounts. It will cause loss of important data.

    e.g. bind mount, managed by User
    /persistent:/persistent

e.g. volume mount, managed by Docker
log_data:/usr/local/nmis9/logs

Example docker-compose.yaml

version: '3.4'
services:
  mongo:
    image: mongo:6.0
    restart: always
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongo mongo:27017/test --quiet
      interval: 60s
      timeout: 60s
      retries: 5
      start_period: 60s
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example
    volumes:
      - /persistent/mongod.conf:/etc/mongod.conf
      - mongo_data:/data/mongodb
    ports:
      - "27017:27017"
    networks:
      - nmis_net
  nmis:
    image: public.ecr.aws/n2x4v8j4/firstwave/nmis9_omk:v1.7
    restart: always
    environment:
      NMIS_DB_USERNAME: root
      NMIS_DB_PASSWORD: example
      NMIS_DB_SERVER: 192.168.xx.xxx
      NMIS_SERVER_NAME: xxx.opmantek.net
    depends_on:
      mongo:
        condition: service_healthy
    volumes:
      - log_data:/usr/local/nmis9/logs
      - var_data:/usr/local/nmis9/var
      - conf_data:/usr/local/nmis9/conf
      - database_data:/usr/local/nmis9/database
      # You can mount your own config files into volumes in the container but 
      # you must ensure that the db config details match whats in this compose file
      # - ./default-config/Config.nmis:/usr/local/nmis9/conf/Config.nmis
      # - ./default-config/opCommon.json:/usr/local/omk/conf/opCommon.json
      - /persistent/Config.nmis:/usr/local/nmis9/conf/Config.nmis
      - /persistent/opCommon.json:/usr/local/omk/conf/opCommon.json
      - omk_log_data:/usr/local/omk/log
      - omk_var_data:/usr/local/omk/var
      - omk_conf_data:/usr/local/omk/conf
      # - ./persistent:/persistent
      # - ./app_conf/opLicense.json:/usr/local/omk/conf/opLicense.json
    ports:
      - "8080:8080"
      - "8042:8042"
      - "2055:2055/udp"
      - "161:161/udp"
      - "25:25"
    networks:
      - nmis_net
networks:
  nmis_net:
volumes:
  log_data:
  var_data:
  conf_data:
  database_data:
  omk_log_data:
  omk_var_data:
  omk_conf_data:
  mongo_data:

  1. Make sure your configuration files have the correct database information. Your Config.nmis and opCommon.json files need have the same database username, password, server name and server IP as the environment variables in your docker-compose.yaml.

    MONGO_INITDB_ROOT_USERNAME: root
    MONGO_INITDB_ROOT_PASSWORD: example
    
    NMIS_DB_USERNAME: root
    NMIS_DB_PASSWORD: example
    NMIS_DB_SERVER: 192.168.xx.xxx
    NMIS_SERVER_NAME: xxx.opmantek.net

  2. Start the services:

docker compose up --file docker-compose.yaml

  1. Monitor deployment:

docker compose ps
docker compose logs -f

Connecting to the application

Once the container is running, go to http://your.ip.or.localhost:8080/cgi-nmis9/nmiscgi.pl to reach the NMIS application

To reach the rest of the modules, go to http://your.ip.or.localhost:8042/omk

To connect when using a reverse proxy see below.

Using your own configuration

The container already persists the <nmis>/conf directory and the three files below.

The easiest way to use your own configuartion with docker is to mount in your own. The items you will mainly want to mount in will be:

Config.nmis

opCommon.json

and opLicense.json

But you can extend this to any file you want which is used by the nmis system, to do this:

  1. create a directory named app_conf (if you didn’t before) in the same directory you created the compose file in:

mkdir -p appconf
cd appconf
sudo cp /path/to/Config.nmis .
sudo cp /path/to/opCommon.json .
sudo cp /path/to/opLicense.json .
  1. uncomment out the app_conf volume mounts in the compose file

  2. Restart the the containers

If you wish to use the default configs that work out of the box with the containers, and modify them, you can copy them from the containers to your local machine.

  1. make the appconf directory to store them in, where you will mount them from later

  2. exec into your container and copy the configuration files to a directory on your host machine:

docker exec -it <container_name> bash -c "mkdir -p /tmp/configs && cp /usr/local/nmis9/conf/Config.nmis /usr/local/omk/conf/opCommon.json /usr/local/omk/conf/opLicense.json /tmp/configs/"
docker cp <container_name>:/tmp/configs/. <path/to/appconf/>

Replace <container_name> with your actual container name (likely "nmis" based on your compose file).

The command:

  1. Creates a temporary directory inside the container

  2. Copies all three config files to that directory

  3. Uses docker cp to copy the files from the container to your host at <Path/to/appconf/>

If you need to find your container name first, you can run:

docker ps | grep nmis

  1. once you have the default configs in the appconf dir - uncomment out the appconf volume mounts in the compose file and restart the container stack

Apache Reverse Proxy Configuration (Optional)

  1. Prerequisites

    1. Apache2 with required modules (if using reverse proxy):

      • mod_ssl

      • mod_proxy

      • mod_proxy_http

      • mod_headers

    2. SSL certificates (if using HTTPS)

  2. Enable required Apache modules:

sudo a2enmod ssl proxy proxy_http headers
sudo systemctl restart apache2
  1. Create virtual host configuration, using the following template, substituting your domain name for nmis.example.com:

# /etc/apache2/sites-available/nmis.conf
<VirtualHost *:80>
    ServerName nmis.example.com
    Redirect permanent / <https://nmis.example.com/>
</VirtualHost>

<VirtualHost *:443>
    ServerName nmis.example.com
    
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/nmis.crt
    SSLCertificateKeyFile /etc/ssl/private/nmis.key
    
    # Security headers
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-XSS-Protection "1; mode=block"
    Header always set X-Content-Type-Options "nosniff"
    
    # Logging configuration
    ErrorLog ${APACHE_LOG_DIR}/nmis_error.log
    CustomLog ${APACHE_LOG_DIR}/nmis_access.log combined
    
    ProxyPreserveHost On
    
    # NMIS Web Interface
    ProxyPass / <http://localhost:8080/>
    ProxyPassReverse / <http://localhost:8080/>
    
    # OMK Interface
    ProxyPass /omk/ <http://localhost:8042/>
    ProxyPassReverse /omk/ <http://localhost:8042/>
</VirtualHost>
  1. Enable virtual host:

sudo a2ensite nmis.conf
sudo systemctl reload apache2
  1. To connect to the the application:
    Once the container is running, go to https://nmis.example.com/omk to reach the NMIS application

    To reach the rest of the modules, go to https://nmis.example.com/omk

Common Issues and Troubleshooting

MongoDB Connection Issues:

Apache Proxy Issues:

Security Considerations

  1. Change default passwords:

**Important - to change the mongo password - please change it in the mongo database before changing any configurations or environment variables

docker exec -it container_name mongo -u root -p example

use admin
db.changeUserPassword("root", "new_password")
exit

  1. SSL/TLS Configuration:

  1. Network Security:

Maintenance

Backup Strategy:

# Backup MongoDB data
docker compose exec mongo mongodump --out /backup

# Backup configuration files
tar -czf nmis_config_backup.tar.gz app_conf/

Updates:

# Pull latest images
docker compose pull

# Restart services
docker compose down
docker compose up -d

Advanced Configuration

External MongoDB

To use an external MongoDB instance:

  1. Remove the mongo service from docker-compose.yaml

  2. Update NMIS environment variables with external MongoDB details

  3. Ensure proper network connectivity and authentication

Custom Networking

For enhanced security:

  1. Use custom network ranges

  2. Implement network segmentation

  3. Add additional security layers (WAF, IDS)

Support and Resources