When installing Vikunja on a systemd-based system, the service may be configured to run as root
. It is generally a good idea to run services with the least amount of privileges they need. This guide shows how to run Vikunja as its own dedicated user and how to optionally add extra security restrictions using systemd.
Create a dedicated user #
Create a system account for Vikunja that will not be able to log in interactively and will only be used to run the service:
sudo useradd --system --home /var/lib/vikunja --shell /usr/sbin/nologin vikunja
Next, ensure Vikunja has its own directories for data and configuration, and that the new user owns them:
sudo mkdir -p /var/lib/vikunja
sudo chown -R vikunja:vikunja /var/lib/vikunja
sudo chmod -R o+r /etc/vikunja
If you are logging to files, create a log directory and update the paths in your config.yml
under the log section.
sudo mkdir -p /var/log/vikunja
sudo chown -R vikunja:vikunja /var/log/vikunja
Modify the systemd service unit #
The package already provides a service unit (/lib/systemd/system/vikunja.service). Modify it using:
sudo systemctl edit vikunja.service
Apply the following changes:
- Run Vikunja as the dedicated vikunja user
- Use
/var/lib/vikunja
as the working directory - Explicitly specify the config file when starting the binary
- Add basic systemd sandboxing options to limit host access
[Service]
User=vikunja
Group=vikunja
WorkingDirectory=/var/lib/vikunja
ExecStart=/usr/local/bin/vikunja
Environment=VIKUNJA_CONFIG=/etc/vikunja/config.yml
Restart=always
RestartSec=3
LimitNOFILE=65536
NoNewPrivileges=true
ProtectHome=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/lib/vikunja /etc/vikunja
Also include your configured files and log directory in ReadWritePaths
and ensure the vikunja
user has the correct permissions.
Reload systemd and restart Vikunja #
sudo systemctl daemon-reload
sudo systemctl restart vikunja.service
Verify the service #
Check that the service is running under the correct user:
ps -u vikunja -f
Additionally, check the logs for errors:
journalctl -u vikunja.service -e
Extra hardening (optional) #
systemd provides further options to isolate services from the rest of the system. If you want to go beyond the basic setup, add the following in the [Service] section:
CapabilityBoundingSet=
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
PrivateDevices=yes
RestrictSUIDSGID=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
SystemCallArchitectures=native
RestrictNamespaces=yes
SystemCallFilter=@system-service @network-io ~@privileged
ProtectProc=invisible
ProcSubset=pid
This restricts access to kernel interfaces, devices, and system calls, providing a more “jail-like” environment. A detailed documentation is available here.