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:
sudo useradd --system --home-dir /var/lib/nardb --shell /usr/sbin/nologin nardb
sudo install -d -o nardb -g nardb -m 700 /var/lib/nardbEncryption: -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:
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:
sudo -u nardb env NARDB_HOME=/var/lib/nardb nardb create glabs -e passphraseThe 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:
sudo install -d -m 755 /etc/nardb
sudo install -m 600 /dev/null /etc/nardb/nardb.env
sudoedit /etc/nardb/nardb.envNARDB_PASSPHRASE=encryption-passphrase
# for password_hash({pepper: 'env:PASSWORD_PEPPER'}) fields
PASSWORD_PEPPER=value-from-openssl-rand-base64-32Root 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:
[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.targetsudo systemctl daemon-reload
sudo systemctl enable --now nardb
journalctl -u nardb -n 20On 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:
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:7070Each 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:
sudo install -m 644 /var/lib/nardb/certs/ca.crt /etc/nardb/ca.crtca.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:
# $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.