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:
- A valid
na-user
license - 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). - An encryption secret
- A Docker container run environment, e.g. Kubernetes or Docker 1
- 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:
- Create Configuration File
- 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:
- Create secrets
- Create a configMap
- Write a deployment YAML file
- Run the deployment on your Kubernetes cluster
Create Secrets
First we must create several secrets.
na-user-license
is your software license stringna-user-encrypt-secret
is used to encrypt sensitive API values. Generate withcat /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 databasena-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
-
A non-docker binary can also be made available on request for Enterprise licensees. ↩