# immudb

# Contents

# Latest binaries

Get the latest builds

If you run macOS you can also use Homebrew:

brew install immudb

# Build

clone the immudb repository locally

'git clone https://github.com/codenotary/immudb.git'

# Linux

GOOS=linux GOARCH=amd64 make immudb-static

# MacOS

GOOS=darwin GOARCH=amd64 make immudb-static

# Windows

GOOS=windows GOARCH=amd64 make immudb-static

# Docker

# build your own Docker container image

docker build -t myown/immudb:latest -f Dockerfile .

# run immugw in a container

Make sure to point to the immudb system using the environment variable IMMUGW_IMMUDB-ADDRESS

docker run -it -d -p 3322:3322 -p 9497:9497 --name immudb codenotary/immugw:latest

or listen on all interfaces

docker run -it -d -p 3322:3322 -p 9497:9497 --name immudb -e IMMUDB_ADDRESS="0.0.0.0" codenotary/immudb

listen on all interfaces, persistent data

docker volume create immudb-data
docker run -it -d -p 3322:3322 -p 9497:9497 -v immudb-data:/var/lib/immudb --name immudb -e IMMUDB_ADDRESS="0.0.0.0" codenotary/immudb

# Run immudb

# run immudb in the foreground
./immudb

# run immudb in the background
./immudb -d

# Configuration

immudb can be configured using environment variables, flags or a config file.

  • immudb --help shows you all available flags and environment variables.
  • /etc/immudb/immudb.toml is used as a default configuration file

# Environment variables

The environment variables are the most popular way to configure Docker container:

  IMMUDB_DIR=.
  IMMUDB_NETWORK=tcp
  IMMUDB_ADDRESS=0.0.0.0
  IMMUDB_PORT=3322
  IMMUDB_DBNAME=immudb
  IMMUDB_PIDFILE=
  IMMUDB_LOGFILE=
  IMMUDB_MTLS=false
  IMMUDB_AUTH=true
  IMMUDB_DETACHED=false
  IMMUDB_CONSISTENCY_CHECK=true
  IMMUDB_PKEY=./tools/mtls/3_application/private/localhost.key.pem
  IMMUDB_CERTIFICATE=./tools/mtls/3_application/certs/localhost.cert.pem
  IMMUDB_CLIENTCAS=./tools/mtls/2_intermediate/certs/ca-chain.cert.pem
  IMMUDB_DEVMODE=true
  IMMUDB_MAINTENANCE=false
  IMMUDB_ADMIN_PASSWORD=immudb

# immuadmin

immuadmin can be used to install and manage the immudb service for Windows and Linux

# Linux

GOOS=linux GOARCH=amd64 make immuadmin-static 

# Windows (by component)

GOOS=windows GOARCH=amd64 make immuadmin-static

# immudb service

Please make sure to build or download the immudb and immuadmin component and save them in the same work directory when installing the service.

# install immudb service
./immuadmin service immudb install

# check current immudb service status
./immuadmin service immudb status

# stop immudb service
./immuadmin service immudb stop

# start immudb service
./immuadmin service immudb start

The linux service is using the following defaults:

File or configuration location
all configuration files /etc/immudb
all data files /var/lib/immudb
pid file /var/lib/immudb/immudb.pid
log files /var/log/immudb

# Authentication

immudb supports multiple user accounts that can have admin, read-only or read-write permission. All permissions are stored in a different database and each gRPC call has an associated minimum permissions.

To enable authentication you need to change the configuration file /etc/immudb/immudb.toml

Example:

dir = "/var/lib/immudb"
network = "tcp"
address = "0.0.0.0"
port = 3322
dbname = "data"
pidfile = "/var/lib/immudb/immudb.pid"
logfile = "/var/log/immudb/immudb.log"
mtls = false
detached = false
auth = true
pkey = "/etc/immudb/mtls/3_application/private/localhost.key.pem"
certificate = "/etc/immudb/mtls/3_application/certs/localhost.cert.pem"
clientcas = "/etc/immudb/mtls/2_intermediate/certs/ca-chain.cert.pem"

The important lines to change are auth = true and address = "0.0.0.0" to enable authentication and listening on all interfaces.

Then restart/start immudb.

# Get the admin credentials

You need to run immuadmin locally on the same system as immudb (for security reasons) and connect to immudb:

immuadmin login immudb

You^ll receive the following message:

Using config file: /etc/immudb/immudb.toml
===============
This looks like the very first admin login attempt, hence the following credentials have been generated:
---
username: immu
password: yourpassword
---
IMPORTANT: This is the only time they are shown, so make sure you remember them.
NOTE: You have not been automatically logged in. To login please run the command 'immuadmin login immu' with the above-mentioned password. You can change your password at any time with one of your liking using the command 'immuadmin user change-password immu'
===============

make sure to note that the password for the immu user as its your master password

# User management

To manage user, run immuadmin user after you logged in immuadmin login immudb

Please specify a user action.
Usage: immuadmin user list|create|change-password|set-permission|deactivate [username] [read|readwrite]
Help : immuadmin user -h

# List user

To get a list of all existing user including their permissions, run immuadmin user list

# Add user

Let's create a read-only user, called ro immuadmin user create <username> read

immuadmin user create ro read
NOTE: password must have between 8 and 32 letters, digits and special characters of which at least 1 uppercase letter, 1 digit and 1 special character.
Choose a password for ro:
Confirm password:
User ro created

and a read-write user, called rw immuadmin user create rw readwrite

# Change user permission

To change the ro user permission from read-only to read-write, run immuadmin user set-permission ro readwrite Check the change, using immuadmin user list

immuadmin user list
Using config file: /etc/immudb/immudb.toml
3 user(s):
-  --------  ----    -----------
#  Username  Role    Permissions
-  --------  ----    -----------
1  immu      admin   admin
2  ro        client  readwrite
3  rw        client  readwrite
-  --------  ----    -----------

# Deactivate user

To deactivate an existing user, run immuadmin user deactivate ro

# Reactivate user

To reactivate a deactivated user account, you can simply set user permission again. Run immuadmin user set-permission ro readwrite

# Backup and Restore

work in progress

# Clients

Starting version 0.6.0 of immudb, you can use immugw (REST API), immuclient (interactive) or GoLang as immudb database clients. Depending on the user settings and permissions, you can have read-only and read-write clients.

APIs and interfaces - API reference and code examples

More driver libraries are coming soon (Java, Node.js, Python, .net aso.)

# Auditors

Auditors make sure that the data consistency is guaranteed inside immudb. They do a random key value verification and a interval-based Merkle-tree consistency check (5 minutes default). The immugw and the immuclient provide auditor functionality that runs as a daemon process. It is recommended to run immugw and immuclient on different machines than immudb, so any tampering on the immudb server is automatically detected.

The results of the auditors are provided by a Prometheus end point.

# immugw auditor

Start interactive: immugw --audit

Service configuration: To enable auditor, you need to edit /etc/immudb/immugw.toml and add the following section:

audit = true # false is default
audit-interval = "5m" # suffixes: "s", "m", "h", examples: 10s, 5m 1h
audit-username = "" # when immudb authentication is enabled, use read-only user credentials here
audit-password = "" # and the password

Restart the immugw service afterwards - immuadmin service immugw restart

immugw Port: 9476 - http://immugw-auditor:9476/metrics

example output:

# HELP immugw_audit_curr_root_per_server Current root index used for the latest audit.
# TYPE immugw_audit_curr_root_per_server gauge
immugw_audit_curr_root_per_server{server_address="127.0.0.1:3322",server_id="br8eugq036tfln0ct6o0"} 2
# HELP immugw_audit_prev_root_per_server Previous root index used for the latest audit.
# TYPE immugw_audit_prev_root_per_server gauge
immugw_audit_prev_root_per_server{server_address="127.0.0.1:3322",server_id="br8eugq036tfln0ct6o0"} 2
# HELP immugw_audit_result_per_server Latest audit result (1 = ok, 0 = tampered).
# TYPE immugw_audit_result_per_server gauge
immugw_audit_result_per_server{server_address="127.0.0.1:3322",server_id="br8eugq036tfln0ct6o0"} 1
# HELP immugw_audit_run_at_per_server Timestamp in unix seconds at which latest audit run.
# TYPE immugw_audit_run_at_per_server gauge
immugw_audit_run_at_per_server{server_address="127.0.0.1:3322",server_id="br8eugq036tfln0ct6o0"} 1.590757033502689e+09

# immuclient auditor

Start interactive: immuclient audit-mode

Install service: immuclient audit-mode install

**immuclient Port: 9477 - http://immuclient-auditor:9477/metrics **

example output:

# HELP immuclient_audit_curr_root_per_server Current root index used for the latest audit.
# TYPE immuclient_audit_curr_root_per_server gauge
immuclient_audit_curr_root_per_server{server_address="127.0.0.1:3322",server_id="br8eugq036tfln0ct6o0"} 2
# HELP immuclient_audit_prev_root_per_server Previous root index used for the latest audit.
# TYPE immuclient_audit_prev_root_per_server gauge
immuclient_audit_prev_root_per_server{server_address="127.0.0.1:3322",server_id="br8eugq036tfln0ct6o0"} -1
# HELP immuclient_audit_result_per_server Latest audit result (1 = ok, 0 = tampered).
# TYPE immuclient_audit_result_per_server gauge
immuclient_audit_result_per_server{server_address="127.0.0.1:3322",server_id="br8eugq036tfln0ct6o0"} -1
# HELP immuclient_audit_run_at_per_server Timestamp in unix seconds at which latest audit run.
# TYPE immuclient_audit_run_at_per_server gauge
immuclient_audit_run_at_per_server{server_address="127.0.0.1:3322",server_id="br8eugq036tfln0ct6o0"} 1.5907565337454605e+09

# Architecture

The different components of immudb are communicating as follows: immudb component overview

Please check How it works, to learn more about the data structure and the Merkle-tree:

How it works

# Consistency checker

# How do you run it?

It is part of immudb, enabled by default and runs as a thread of immudb. The routine can be disabled as follows:

./immudb --consistency-check=false

# What does it check?

Consistency checker runs in a loop and continuously checks if the elements stored inside the immudb Merkle-tree are also physically stored correctly on the disk (the digest of the disk elements is the same digest stored in the related Merkle-tree leaf)

# How does it run its check?

Steps:

  1. reading the last root and last index stored in immudb
  2. generate a range between 0 and the length of the Merkle-tree level 0 (total number of elements stored)
  3. shuffles the range to get a random scan list (to be unpredictable)
  4. check if every element is correctly inserted in the Merkle-tree and if the Merkle-tree leaves correctly represent the elements stored on hard disk
  5. after completing the loop, the process sleeps ten seconds and restarts from scratch with a new root and index
  6. in case an element does not pass the check correctly, immudb is immediately stopped and prints out a log message

In order to produce a corrupted entry that is only on disk and not in the Merkle-tree, stop the immudb process and use the nimmu command:

go build tools/nimmu/nimmu.go 
./nimmu rawset key1 tamper

Then restart immudb and you should see the consistency check printing an error.

# License

immudb is Apache v2.0 License.