Skip to content
NarDBv0.2.0-dev

Production setup

nardb serve on a Linux server — systemd unit, a separate system user, the encryption passphrase, the pepper and sharing ca.crt.

This page sets NarDB up as a permanent service on a Linux server. The application (for example a LexerLang site) runs on the same machine and connects through 127.0.0.1:7070.

Location
Program/usr/local/bin/nardb
Data, certificates, audit log/var/lib/nardb (NARDB_HOME), readable by the nardb user only
Secrets/etc/nardb/nardb.env, readable by root only
Authority the application sees/etc/nardb/ca.crt

There is no distribution package yet. Build the binary in the nardb_shell directory: GOOS=linux GOARCH=amd64 go build -o nardb .

System user#

NarDB runs as its own user; the application's user cannot read the data files:

Terminal
sudo useradd --system --home-dir /var/lib/nardb --shell /usr/sbin/nologin nardb
sudo install -d -o nardb -g nardb -m 700 /var/lib/nardb

Encryption: -e passphrase on Linux#

By default nardb create keeps the key in the system keychain. A Linux server without a desktop usually has no keychain (Secret Service), and the command fails with:

Text
nardb: ... (no system keychain here? use -e passphrase)

NarDB does not silently create an unencrypted database instead. On a server, use passphrase encryption. Give the passphrase as the nardb user, in a terminal:

Terminal
sudo -u nardb env NARDB_HOME=/var/lib/nardb nardb create glabs -e passphrase

The command asks for the root password, then twice for the encryption passphrase (at least 12 characters). If the passphrase is lost, the data cannot be recovered; keep it in a password manager.

Secrets#

The service reads the encryption passphrase, and the pepper if there is one, from an environment file:

Terminal
sudo install -d -m 755 /etc/nardb
sudo install -m 600 /dev/null /etc/nardb/nardb.env
sudoedit /etc/nardb/nardb.env
.env
NARDB_PASSPHRASE=encryption-passphrase
# for password_hash({pepper: 'env:PASSWORD_PEPPER'}) fields
PASSWORD_PEPPER=value-from-openssl-rand-base64-32

Root reads the file; systemd passes the values when it starts the service. The pepper must be in the process that hashes passwords. In server mode that is nardb serve, not the application (Validation).

systemd unit#

/etc/systemd/system/nardb.service:

.env
[Unit]
Description=NarDB server (127.0.0.1:7070)
After=network.target

[Service]
User=nardb
Group=nardb
Environment=NARDB_HOME=/var/lib/nardb
EnvironmentFile=/etc/nardb/nardb.env
ExecStart=/usr/local/bin/nardb serve -listen 127.0.0.1:7070
Restart=on-failure
RestartSec=3
UMask=0077

StateDirectory=nardb
StateDirectoryMode=0700

NoNewPrivileges=true
CapabilityBoundingSet=
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictNamespaces=true
LockPersonality=true
MemoryDenyWriteExecute=true
SystemCallArchitectures=native
SystemCallFilter=@system-service

[Install]
WantedBy=multi-user.target
Terminal
sudo systemctl daemon-reload
sudo systemctl enable --now nardb
journalctl -u nardb -n 20

On the first start the certificates are created in /var/lib/nardb/certs (localhost, 127.0.0.1, ::1; 10 years).

Schemas and users#

The service holds the database open, so commands go through the server (Command line). Run as the nardb user, the client finds the server's ca.crt by itself:

Terminal
alias nardbctl='sudo -u nardb env NARDB_HOME=/var/lib/nardb nardb'

nardbctl exec glabs --remote 127.0.0.1:7070 -f schema.nqf
nardbctl user add glabs app --remote 127.0.0.1:7070
nardbctl grant glabs app system_users write --remote 127.0.0.1:7070
nardbctl user list glabs --remote 127.0.0.1:7070

Each command asks for root's password; a script passes it with NARDB_PASS. Give the application its own user (app) with only the grants it needs, not root.

Connecting the application#

The application runs as another user and cannot read /var/lib/nardb. It only needs the authority's certificate to verify the server; copy it to a readable place:

Terminal
sudo install -m 644 /var/lib/nardb/certs/ca.crt /etc/nardb/ca.crt

ca.crt is a public certificate and safe to share. ca.key and server.key in the same directory are never copied: ca.key can sign new client certificates.

In LexerLang:

LexerLang
# $app_password: from the application's own secret settings (not in the source)
$db = nardb.connect('nardb://app@127.0.0.1:7070/glabs?ca=/etc/nardb/ca.crt').credentials({pass: $app_password})

Object form: nardb.connect({host: '127.0.0.1', port: 7070, db: 'glabs', user: 'app', pass: $app_password, ca: '/etc/nardb/ca.crt'}).

Checklist#

  • Keep -listen 127.0.0.1:7070. If other machines connect, they need a client certificate (Server), and a firewall goes in front.
  • Do not put a proxy (nginx) in front of the server on the same machine; every connection through it looks local.
  • The audit log is /var/lib/nardb/audit.log. Query text, values and passwords are never written.
  • Take regular backups and keep them off the server.
  • Time fields are stored and returned in UTC; the application converts to local time. There is no time zone setting yet.