Building BastionGuard with systemd, OpenRC, SysVinit, and Dinit

BastionGuard can be built for multiple Linux init systems through the BASTIONGUARD_INIT_SYSTEM CMake option.

Supported values:

AUTO
SYSTEMD
OPENRC
SYSVINIT
DINIT

Important: the correct name is SysVinit, and the correct CMake value is SYSVINIT. Do not use SYSINIT.



CMake syntax correction

A backslash used for shell line continuation must be the final character on the line.

Incorrect:

-DBASTIONGUARD_INIT_SYSTEM=AUTO \ -DENABLE_CEF=OFF

Correct:

-DBASTIONGUARD_INIT_SYSTEM=AUTO \
-DENABLE_CEF=OFF \

Use a separate build directory for each init system

CMake stores configuration values in its cache. Do not reuse the same build directory when changing init systems.

build-auto
build-systemd
build-openrc
build-sysvinit
build-dinit

Examples:

cmake -S . -B build-systemd \
    -DBASTIONGUARD_INIT_SYSTEM=SYSTEMD

cmake -S . -B build-openrc \
    -DBASTIONGUARD_INIT_SYSTEM=OPENRC

To reuse a directory, remove it first:

rm -rf build

On recent CMake versions:

cmake --fresh -S . -B build

Automatic init-system detection

For local builds, BastionGuard can attempt to detect the active init system automatically.

cmake -S . -B build-auto \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    -DBG_PACKAGING=ON \
    -DBG_DEBIAN_NO_INSTALL_CODE=ON \
    -DENABLE_SYSTEMD_SERVICES=OFF \
    -DENABLE_USER_AGENT_AUTO=OFF \
    -DINSTALL_NGINX_DEFAULTS=OFF \
    -DBASTIONGUARD_INIT_SYSTEM=AUTO \
    -DENABLE_CEF=OFF \
    -DENABLE_EMBEDDED_CEF=ON \
    -DENABLE_CEF_DAEMON=OFF \
    -DENABLE_SYSTEM_CA_INSTALL=OFF

CMake should report one of these values:

BastionGuard init system: SYSTEMD
BastionGuard init system: OPENRC
BastionGuard init system: SYSVINIT
BastionGuard init system: DINIT

When not to use AUTO

Do not normally use AUTO when creating distribution packages. In containers, chroots, CI runners, or package-building environments, the init system detected on the build host may not match the target machine.

For reproducible packages, specify the backend explicitly:

-DBASTIONGUARD_INIT_SYSTEM=SYSTEMD
-DBASTIONGUARD_INIT_SYSTEM=OPENRC
-DBASTIONGUARD_INIT_SYSTEM=SYSVINIT
-DBASTIONGUARD_INIT_SYSTEM=DINIT

Building for systemd

Configure

cmake -S . -B build-systemd \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    -DBG_PACKAGING=ON \
    -DBG_DEBIAN_NO_INSTALL_CODE=ON \
    -DENABLE_SYSTEMD_SERVICES=OFF \
    -DENABLE_USER_AGENT_AUTO=OFF \
    -DINSTALL_NGINX_DEFAULTS=OFF \
    -DBASTIONGUARD_INIT_SYSTEM=SYSTEMD \
    -DENABLE_CEF=OFF \
    -DENABLE_EMBEDDED_CEF=ON \
    -DENABLE_CEF_DAEMON=OFF \
    -DENABLE_SYSTEM_CA_INSTALL=OFF

Compile

cmake --build build-systemd --parallel "$(nproc)"

Install into a staging directory

rm -rf pkg-systemd

DESTDIR="$PWD/pkg-systemd" \
    cmake --install build-systemd

Install on the current system

sudo cmake --install build-systemd

Reload systemd

sudo systemctl daemon-reload

Enable and start the main services

sudo systemctl enable --now BastionGuard-phishing-scanner.service
sudo systemctl enable --now BastionGuard-ransomware-realtime.service
sudo systemctl enable --now BastionGuard-usbd.service
sudo systemctl enable --now bsc-daemon.service

Enable periodic update timers

sudo systemctl enable --now BastionGuard-phishing-updater.timer
sudo systemctl enable --now bastionguard-sanesecurity.timer

Check service status

systemctl status BastionGuard-phishing-scanner.service
systemctl status BastionGuard-ransomware-realtime.service
systemctl status BastionGuard-usbd.service
systemctl status bsc-daemon.service

View logs

journalctl -u bsc-daemon.service
journalctl -u BastionGuard-ransomware-realtime.service
journalctl -f -u bsc-daemon.service

Building for OpenRC

Configure

cmake -S . -B build-openrc \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    -DBG_PACKAGING=ON \
    -DBG_DEBIAN_NO_INSTALL_CODE=ON \
    -DENABLE_SYSTEMD_SERVICES=OFF \
    -DENABLE_USER_AGENT_AUTO=OFF \
    -DINSTALL_NGINX_DEFAULTS=OFF \
    -DBASTIONGUARD_INIT_SYSTEM=OPENRC \
    -DENABLE_CEF=OFF \
    -DENABLE_EMBEDDED_CEF=ON \
    -DENABLE_CEF_DAEMON=OFF \
    -DENABLE_SYSTEM_CA_INSTALL=OFF

Compile

cmake --build build-openrc --parallel "$(nproc)"

Install into a staging directory

rm -rf pkg-openrc

DESTDIR="$PWD/pkg-openrc" \
    cmake --install build-openrc

Install on the current system

sudo cmake --install build-openrc

OpenRC service scripts are normally installed in /etc/init.d.

Add services to the default runlevel

sudo rc-update add BastionGuard-phishing-scanner default
sudo rc-update add BastionGuard-ransomware-realtime default
sudo rc-update add BastionGuard-usbd default
sudo rc-update add bsc-daemon default

Start services

sudo rc-service BastionGuard-phishing-scanner start
sudo rc-service BastionGuard-ransomware-realtime start
sudo rc-service BastionGuard-usbd start
sudo rc-service bsc-daemon start

Check status

rc-service BastionGuard-phishing-scanner status
rc-service BastionGuard-ransomware-realtime status
rc-service BastionGuard-usbd status
rc-service bsc-daemon status

Restart Secure Connection

sudo rc-service bsc-daemon restart

Show enabled services

rc-update show default

Building for SysVinit

Configure

cmake -S . -B build-sysvinit \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    -DBG_PACKAGING=ON \
    -DBG_DEBIAN_NO_INSTALL_CODE=ON \
    -DENABLE_SYSTEMD_SERVICES=OFF \
    -DENABLE_USER_AGENT_AUTO=OFF \
    -DINSTALL_NGINX_DEFAULTS=OFF \
    -DBASTIONGUARD_INIT_SYSTEM=SYSVINIT \
    -DENABLE_CEF=OFF \
    -DENABLE_EMBEDDED_CEF=ON \
    -DENABLE_CEF_DAEMON=OFF \
    -DENABLE_SYSTEM_CA_INSTALL=OFF

Compile

cmake --build build-sysvinit --parallel "$(nproc)"

Install into a staging directory

rm -rf pkg-sysvinit

DESTDIR="$PWD/pkg-sysvinit" \
    cmake --install build-sysvinit

Install on the current system

sudo cmake --install build-sysvinit

SysVinit scripts are normally installed in /etc/init.d.

Enable services with update-rc.d

sudo update-rc.d BastionGuard-phishing-scanner defaults
sudo update-rc.d BastionGuard-ransomware-realtime defaults
sudo update-rc.d BastionGuard-usbd defaults
sudo update-rc.d bsc-daemon defaults

Enable services with chkconfig

sudo chkconfig --add BastionGuard-phishing-scanner
sudo chkconfig --add BastionGuard-ransomware-realtime
sudo chkconfig --add BastionGuard-usbd
sudo chkconfig --add bsc-daemon

sudo chkconfig BastionGuard-phishing-scanner on
sudo chkconfig BastionGuard-ransomware-realtime on
sudo chkconfig BastionGuard-usbd on
sudo chkconfig bsc-daemon on

Start services

sudo service BastionGuard-phishing-scanner start
sudo service BastionGuard-ransomware-realtime start
sudo service BastionGuard-usbd start
sudo service bsc-daemon start

Check status

service BastionGuard-phishing-scanner status
service BastionGuard-ransomware-realtime status
service BastionGuard-usbd status
service bsc-daemon status

Restart Secure Connection

sudo service bsc-daemon restart

Building for Dinit

Configure

cmake -S . -B build-dinit \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    -DBG_PACKAGING=ON \
    -DBG_DEBIAN_NO_INSTALL_CODE=ON \
    -DENABLE_SYSTEMD_SERVICES=OFF \
    -DENABLE_USER_AGENT_AUTO=OFF \
    -DINSTALL_NGINX_DEFAULTS=OFF \
    -DBASTIONGUARD_INIT_SYSTEM=DINIT \
    -DENABLE_CEF=OFF \
    -DENABLE_EMBEDDED_CEF=ON \
    -DENABLE_CEF_DAEMON=OFF \
    -DENABLE_SYSTEM_CA_INSTALL=OFF

Compile

cmake --build build-dinit --parallel "$(nproc)"

Install into a staging directory

rm -rf pkg-dinit

DESTDIR="$PWD/pkg-dinit" \
    cmake --install build-dinit

Install on the current system

sudo cmake --install build-dinit

System-level Dinit descriptions are normally installed in /etc/dinit.d.

User-level Dinit descriptions are normally installed in /usr/lib/dinit.d/user.

Reload service descriptions

sudo dinitctl reload

Enable the main services

sudo dinitctl enable BastionGuard-phishing-scanner
sudo dinitctl enable BastionGuard-ransomware-realtime
sudo dinitctl enable BastionGuard-usbd
sudo dinitctl enable bsc-daemon

Start the services

sudo dinitctl start BastionGuard-phishing-scanner
sudo dinitctl start BastionGuard-ransomware-realtime
sudo dinitctl start BastionGuard-usbd
sudo dinitctl start bsc-daemon

Where supported:

sudo dinitctl enable --now bsc-daemon

Check status

dinitctl status BastionGuard-phishing-scanner
dinitctl status BastionGuard-ransomware-realtime
dinitctl status BastionGuard-usbd
dinitctl status bsc-daemon

Restart Secure Connection

sudo dinitctl restart bsc-daemon

User-level Dinit services

dinitctl --user reload
dinitctl --user enable BastionGuard-useragent
dinitctl --user start BastionGuard-useragent
dinitctl --user status BastionGuard-useragent

Generic packaging build

INIT_SYSTEM=OPENRC
BUILD_DIR="build-${INIT_SYSTEM,,}"
PACKAGE_DIR="$PWD/pkg-${INIT_SYSTEM,,}"

cmake -S . -B "$BUILD_DIR" \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    -DBG_PACKAGING=ON \
    -DBG_DEBIAN_NO_INSTALL_CODE=ON \
    -DENABLE_SYSTEMD_SERVICES=OFF \
    -DENABLE_USER_AGENT_AUTO=OFF \
    -DINSTALL_NGINX_DEFAULTS=OFF \
    -DBASTIONGUARD_INIT_SYSTEM="$INIT_SYSTEM" \
    -DENABLE_CEF=OFF \
    -DENABLE_EMBEDDED_CEF=ON \
    -DENABLE_CEF_DAEMON=OFF \
    -DENABLE_SYSTEM_CA_INSTALL=OFF

cmake --build "$BUILD_DIR" --parallel "$(nproc)"

rm -rf "$PACKAGE_DIR"

DESTDIR="$PACKAGE_DIR" \
    cmake --install "$BUILD_DIR"

Change the backend as required:

INIT_SYSTEM=SYSTEMD
INIT_SYSTEM=OPENRC
INIT_SYSTEM=SYSVINIT
INIT_SYSTEM=DINIT

Build all init-system variants

#!/usr/bin/env bash

set -euo pipefail

for init_system in SYSTEMD OPENRC SYSVINIT DINIT; do
    init_lower="$(printf '%s' "$init_system" | tr '[:upper:]' '[:lower:]')"
    build_dir="build-${init_lower}"
    package_dir="$PWD/pkg-${init_lower}"

    echo
    echo "=========================================="
    echo "Configuring BastionGuard for ${init_system}"
    echo "=========================================="

    rm -rf "$build_dir" "$package_dir"

    cmake -S . -B "$build_dir" \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=/usr \
        -DCMAKE_INSTALL_SYSCONFDIR=/etc \
        -DBG_PACKAGING=ON \
        -DBG_DEBIAN_NO_INSTALL_CODE=ON \
        -DENABLE_SYSTEMD_SERVICES=OFF \
        -DENABLE_USER_AGENT_AUTO=OFF \
        -DINSTALL_NGINX_DEFAULTS=OFF \
        -DBASTIONGUARD_INIT_SYSTEM="$init_system" \
        -DENABLE_CEF=OFF \
        -DENABLE_EMBEDDED_CEF=ON \
        -DENABLE_CEF_DAEMON=OFF \
        -DENABLE_SYSTEM_CA_INSTALL=OFF

    cmake --build "$build_dir" --parallel "$(nproc)"

    DESTDIR="$package_dir" \
        cmake --install "$build_dir"

    echo "Completed backend: ${init_system}"
    echo "Build directory:   ${build_dir}"
    echo "Staging directory: ${package_dir}"
done

Save, enable, and run:

chmod +x build-all-init.sh
./build-all-init.sh

Distribution-specific CEF options

Mageia, openSUSE, and OpenMandriva

-DENABLE_CEF=OFF \
-DENABLE_EMBEDDED_CEF=ON \
-DENABLE_CEF_DAEMON=OFF \
-DENABLE_SYSTEM_CA_INSTALL=OFF

Fedora

-DENABLE_CEF=ON \
-DENABLE_CEF_DAEMON=OFF \
-DENABLE_SYSTEM_CA_INSTALL=OFF

Do not pass ENABLE_EMBEDDED_CEF when the Fedora CMake file does not define it.

Arch Linux

When the Arch configuration does not define separate CEF options, omit them:

cmake -S . -B build-openrc \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    -DBG_PACKAGING=ON \
    -DBG_DEBIAN_NO_INSTALL_CODE=ON \
    -DENABLE_SYSTEMD_SERVICES=OFF \
    -DENABLE_USER_AGENT_AUTO=OFF \
    -DINSTALL_NGINX_DEFAULTS=OFF \
    -DBASTIONGUARD_INIT_SYSTEM=OPENRC

Verifying staged installations

systemd

find pkg-systemd/usr/lib/systemd -type f | sort

OpenRC

find pkg-openrc/etc/init.d -type f | sort

SysVinit

find pkg-sysvinit/etc/init.d -type f | sort

Dinit

find pkg-dinit/etc/dinit.d -type f | sort
find pkg-dinit/usr/lib/dinit.d -type f | sort

Compare all staged packages

find pkg-systemd pkg-openrc pkg-sysvinit pkg-dinit \
    -type f \
    | sort

Inspecting the CMake cache

grep BASTIONGUARD_INIT_SYSTEM build-openrc/CMakeCache.txt

Expected:

BASTIONGUARD_INIT_SYSTEM:STRING=OPENRC

Inspect related options:

cmake -LAH -N build-openrc \
    | grep -E 'BASTIONGUARD|BG_|ENABLE_|INSTALL_NGINX'

-DBG_PACKAGING=ON \
-DBG_DEBIAN_NO_INSTALL_CODE=ON \
-DENABLE_SYSTEMD_SERVICES=OFF \
-DENABLE_USER_AGENT_AUTO=OFF \
-DINSTALL_NGINX_DEFAULTS=OFF

These options prevent the build process from starting services, enabling services automatically, restarting Nginx, modifying user sessions, or writing outside the staging directory.


Common errors

Invalid line continuation

Incorrect:

-DBASTIONGUARD_INIT_SYSTEM=AUTO \ -DENABLE_CEF=OFF

Correct:

-DBASTIONGUARD_INIT_SYSTEM=AUTO \
-DENABLE_CEF=OFF \

Reusing the same build directory

Use separate directories for different backends.

Using AUTO for a distribution package

Choose the intended explicit backend instead.

Installing directly during package creation

Do not use:

sudo cmake --install build

Use:

DESTDIR="$pkgdir" \
    cmake --install build

For Mageia, openSUSE, and OpenMandriva:

INIT_SYSTEM=OPENRC

cmake -S . -B "build-${INIT_SYSTEM,,}" \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr \
    -DCMAKE_INSTALL_SYSCONFDIR=/etc \
    -DBG_PACKAGING=ON \
    -DBG_DEBIAN_NO_INSTALL_CODE=ON \
    -DENABLE_SYSTEMD_SERVICES=OFF \
    -DENABLE_USER_AGENT_AUTO=OFF \
    -DINSTALL_NGINX_DEFAULTS=OFF \
    -DBASTIONGUARD_INIT_SYSTEM="$INIT_SYSTEM" \
    -DENABLE_CEF=OFF \
    -DENABLE_EMBEDDED_CEF=ON \
    -DENABLE_CEF_DAEMON=OFF \
    -DENABLE_SYSTEM_CA_INSTALL=OFF

cmake --build "build-${INIT_SYSTEM,,}" \
    --parallel "$(nproc)"

DESTDIR="$PWD/pkg-${INIT_SYSTEM,,}" \
    cmake --install "build-${INIT_SYSTEM,,}"

Replace OPENRC with:

SYSTEMD
SYSVINIT
DINIT

For local testing:

INIT_SYSTEM=AUTO

For RPM, DEB, PKGBUILD, or any other reproducible package, always select the target init system explicitly.