Skip to content

Setup and Installation

The na-user service is built to run natively in a Docker container. While a standalone binary build is avalilable on demand with an Enterprise license, the asumption is that na-user will be run as part of a Docker Compose or Kubernetes environment. Accordingly many design and setup choices are aimed to support such deployments.

Prerequisites

In order to use na-user you need the following:

  1. A valid na-user license
  2. A na-user MySQL (version 5.7 or later) database and a user who can access the database. (PostgreSQL support can be made available on request).
  3. An encryption secret
  4. A Docker container run environment, e.g. Kubernetes or Docker 1
  5. The na-user Docker image

Obtaining a License

Contact nulladmin.com to obtain a license at contact@nulladmin.com

na-user licenses come in three flavors: Free, Standard, and Enterprise.

The license is a string which you will insert into a configuration file or environment variable when starting the na-user container.

Config Type Example
Configuration file license: "FH7YCAYBAEFGY2..."
Environment variable NA_USER_LICENSE="FH7YCAYBAEFGY2..."

MySQL Database and User

na-user requires MySQL 5.7 or higher to store user data. (PostgreSQL support can be made available on request)

It is recommended that you configure your MySQL database to support TLS connections from clients. na-user supports TLS connections.

Once your MySQL instance is set up you need to create a database to contain your user data and a user to access that database. See Configuring MySQL to Use Encrypted Connections for instructions on how to do this.

To create an example database called na_user_users and an admin user called na_user_admin who can acces the database from any host, log into MySQL and execute the following commands. Obviously replace secret_password by your chosen password.

$ mysql -u root -p
mysql> CREATE DATABASE na_user_users;
Query OK, 1 row affected (0.00 sec)

mysql> CREATE USER 'na_user_admin' IDENTIFIED BY 'secret_password';

mysql> GRANT ALL ON na_user_users.* TO 'na_user_admin'@'%';
Query OK, 1 row affected (0.00 sec)

Encryption Secret

na-user uses an encrypt_secret for encrypting various security sensitive features such as GUI cookies and paging tokens (a.k.a. continuation tokens). The secret is read from the configuration file or environment variable when starting the na-user container.

IMPORTANT

If running multiple na-user containers all must share the same encryption secret. Make sure all containers have the same configured encryption secret. If this is not done some features (e.g. paging through user listings) will not work as expected.

For example, to generate an encryption secret on Linux you can run the following bash command:

$ cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 32 | head -n 1
hSr9FOMrIOkYGQNTqpsFQeqhLXEJTUL7

You can now specify this string either in the configuration file or environment variable on startup:

Config Type Example
Configuration file encrypt_secret: "hSr9FOMrIOkYGQNTqpsFQeqhLXEJTUL7"
Environment variable NA_USER_ENCRYPT_SECRET="hSr9FOMrIOkYGQNTqpsFQeqhLXEJTUL7"

The na-user Docker Image

The na-user docker image is available on Docker Hub at https://hub.docker.com/r/nulladmin/na-user

You can obtain the latest na-user Docker image and install it in your environment using the docker pull command:

docker pull nulladmin/na-user:latest

You are now ready to configure and run your na-user service.


Configuring na-user

Assuming you have met all the Prerequisites you are now ready to configure your na-user instance.

Basic Configuration File

The simplest way to configure na-user is to feed it a YAML configuration file when starting the Docker container. Here is a minimal valid configuration file. Replace the values in brackets <..> with your own strings.

license: "<YOUR_LICENSE_STRING>"

api_auth:
    type: "basic"
    basic:
        admin_password: "<SECRET_API_PASSWORD>"

encrypt_secret: "<SECRET_ENCRYPT_STRING>"

database:
    db_driver: "mysql"
    mysql:
        db_host: "mysql.example.com"
        db_port: 3306
        db_database: "na_user_users"
        db_userid: "na_user_admin"
        db_password: "<SECRET_DATABASE_PASSWORD>"

http_server:
    port: 8080

See Configuration Options Reference for the full list of configuration options.

Let's quickly go through the options in this minimal config file:

The license is your software license string, covered in Prerequisites.

The encrypt_secret is used to encrypt sensitive value, covered in Prerequisites

The database section contains your MySQL connection details also covered in Prerequisites. Adjust the database.mysql.db_host value to the correct MySQL server name or IP address.

The http_server section covers the port on which the server will listen within the Docker container. You can map this to your host port when you start the container.

The api_auth section covers the basic authentication clients will use to talk to the na-user API. When na-user first starts up it creates an admin user with the given api_auth.basic.admin_password. Whenever a client wants to access the API it can do so using a basic HTTP authentication URL like this http://admin:secret_admin_password@hostname/users/list. Using curl:

curl -u admin:secret_admin_password http://hostname/users/list

Setting Configuration Values with Environment Variables

In addition to reading configuration values from a file, na-user supports configuration using environment variables. This is useful for injecting secrets or deploy time values into the container.

All configuration variables in the configuration file can be overridden by environment variables prefixed with NA_USER_ and converted to upper case. Subkeys are separated by underscores.

Consider the following snippet of the YAML configuration file:

database:
    mysql:
        db_database: "na_user_users"
        db_userid: "na_user_admin"
        db_password: "database access secret password"

encrypt_secret: "your secret encrypt string"

http_server:
    port: 8080

The same settings can be injected at startup by specifying the following environment variables:

NA_USER_DATABASE_MYSQL_DB_DATABASE="na_user_users"
NA_USER_DATABASE_MYSQL_DB_USERID="na_user_admin"
NA_USER_DATABASE_MYSQL_DB_PASSWORD="database access secret password"
NA_USER_ENCRYPT_SECRET="your secret encrypt string"
NA_USER_HTTP_SERVER_PORT="8080"

The Configuration Options Reference section includes the environment variable name of every configuration variable.

Handling Secrets

na-user supports the use of both Kubernetes and Docker secrets. In particular the following configuration variables should be injected as secrets in production:

license
encrypt_secret
database.mysql.db_password
database.mysql.ssl_key
http_server.key_file

The Docker and Kubernetes deployment examples below show how this is done.

Deploy to Docker

Assuming you have met all the prerequisites and have a na-user configuration file, the process of deploying na-user to a Docker container consists of the following steps:

  1. Create Configuration File
  2. Start the na-user docker container

Create Configuration File

Assume you have the following minimal configuration file called na-user-cofig.yaml.

Note that we don't include any secrets (e.g. license, encrypt_secret, and so on). Best practice is to inject those sensitive values using environment variables.

api_auth:
    type: "basic"

database:
    db_driver: "mysql"
    mysql:
        db_host: "mysql.example.com"
        db_port: 3306
        db_database: "nauser_users"
        db_userid: "nauser_admin"

http_server:
    port: 8080

Start the na-user docker container

To start the na-user container run the following command.

docker run --rm  \
    -p 8080:8080  \
    --name=na-user  \
    -e NA_USER_LICENSE='<YOUR_LICENSE_STRING>' \
    -e NA_USER_ENCRYPT_SECRET='<YOUR_ENCRYPT_STRING>' \
    -e NA_USER_DATABASE_MYSQL_DB_PASSWORD='<YOUR_DATABASE_PASSWORD>' \
    -e NA_USER_API_AUTH_BASIC_ADMIN_PASSWORD='<YOUR_API_PASSWORD>' \
    -v na-user-config.yaml:/etc/na-user/na-user-config.yaml  \
    na-user:latest

This will start the container with the API available on port 8080. Check the na-user log (on stdout or in a log file, depending on your configuration) to make sure the connection to MySQL was successful.

Deploy to Kubernetes

Assuming you have met all the prerequisites and have a na-user configuration file, the process of deploying na-user to Kubernetes consists of the following steps:

  1. Create secrets
  2. Create a configMap
  3. Write a deployment YAML file
  4. Run the deployment on your Kubernetes cluster

Create Secrets

First we must create several secrets.

  • na-user-license is your software license string
  • na-user-encrypt-secret is used to encrypt sensitive API values. Generate with cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 32 | head -n 1
  • na-user-database-password is used by the service to acces your database
  • na-user-api-password is used by clients to access the na-user API using HTTP basic authentication.

The following commands will create the secrets in Kubernetes.

kubectl create secret generic na-user-license --from-literal=license="<YOUR_LICENSE_STRING>"
kubectl create secret generic na-user-encrypt-secret --from-literal=encrypt_secret="<SECRET_ENCRYPT_STRING>"
kubectl create secret generic na-user-database-password --from-literal=database.mysql.db_password="<SECRET_DATABASE_PASSWORD>"
kubectl create secret generic na-user-api-password --from-literal=api_auth.basic.admin_password="<SECRET_API_PASSWORD>"

Create a configMap

The simplest way to configure na-user for Kubernetes is to create a configMap from a configuration file.

Assume you have the following minimal configuration file called na-user-cofig.yaml. Note that we don't include any secrets (e.g. license, encrypt_secret, and so on). We will inject those sensitive values via Kubernetes secrets.

api_auth:
    type: "basic"

database:
    db_driver: "mysql"
    mysql:
        db_host: "mysql.example.com"
        db_port: 3306
        db_database: "na_user_users"
        db_userid: "na_user_admin"

http_server:
    port: 8080

Now create a configMap from this file:

kubectl create configmap na-user-config --from-file=na-user-config.yaml

Create a deployment file

We are now ready to create a deployment YAML file na-user-deployment.yaml for our na-user Kubernetes service.

We inject our secrets as environment variables to the na-user container.

The configuration file path will be seen by the container as the file /etc/na-user/na-user-config.yaml

apiVersion: v1
kind: Service
metadata:
  name: na-user
spec:
  ports:
  - port: 8080
  selector:
    app: na-user
  clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: na-user
spec:
  selector:
    matchLabels:
      app: na-user
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: na-user
    spec:
      containers:
      - image: na-user:latest
        name: na-user
        command: ["./na-user"]
        args: ["--config", "/etc/na-user/na-user-config.yaml"]
        env:
        - name: NA_USER_LICENSE
          valueFrom:
            secretKeyRef:
              name: na-user-license
              key: license
        - name: NA_USER_ENCRYPT_SECRET
          valueFrom:
            secretKeyRef:
              name: na-user-encrypt-secret
              key: encrypt_secret
        - name: NA_USER_DATABASE_MYSQL_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: na-user-database-password
              key: database.mysql.db_password
        - name: NA_USER_API_AUTH_BASIC_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: na-user-api-password
              key: api_auth.basic.admin_password
        volumeMounts:
        - name: config-volume
          mountPath: /etc/na-user
        ports:
        - containerPort: 8080
          name: na-user
        resources:
          requests:
            memory: 512M
          limits:
            memory: 1024M
      volumes:
        - name: config-volume
          configMap:
            name: na-user-config

Run the deployment

We now use the deployment file we created in the previous step to deploy the service to the Kubernetes cluster:

kubectl create -f na-user-deployment.yaml

Verify that the service is deployed:

kubectl describe deployment na-user

Delete the deployment

To delete the service:

kubectl delete deployment,svc na-user
kubectl delete configmap na-user-config
kubectl delete secret na-user-license
kubectl delete secret na-user-encrypt-secret
kubectl delete secret na-user-database-password
kubectl delete secret na-user-api-password

  1. A non-docker binary can also be made available on request for Enterprise licensees.