Improve warnings.

This commit is contained in:
Adam Outler
2025-10-17 16:36:48 -04:00
parent dc444117b6
commit d11c9d7c4a
9 changed files with 111 additions and 37 deletions

View File

@@ -137,8 +137,10 @@ COPY --from=builder --chown=20212:20212 ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# although it may be quicker to do it before the copy, it keeps the image
# layers smaller to do it after.
RUN apk add libcap && \
setcap cap_net_raw+ep /bin/busybox && \
setcap cap_net_raw,cap_net_admin+eip /usr/bin/nmap && \
setcap cap_net_raw,cap_net_admin+eip /usr/bin/arp-scan && \
setcap cap_net_raw,cap_net_admin,cap_net_bind_service+eip /usr/bin/nbtscan && \
setcap cap_net_raw,cap_net_admin+eip /usr/bin/traceroute && \
setcap cap_net_raw,cap_net_admin+eip ${VIRTUAL_ENV_BIN}/scapy && \
/bin/sh /build/init-nginx.sh && \

View File

@@ -12,8 +12,8 @@ services:
cap_add: # Add only the necessary capabilities
- NET_ADMIN # Required for ARP scanning
- NET_RAW # Required for raw socket operations
security_opt: # Security options for the container
- no-new-privileges:true # Prevent privilege escalation
- NET_BIND_SERVICE # Required to bind to privileged ports (nbtscan)
volumes:
- type: volume
source: netalertx_config

View File

@@ -12,6 +12,7 @@ echo '
set -u
bash /services/check-root.sh
bash /services/check-cap.sh
bash /services/check-ramdisk.sh
bash /services/check-first-run-config.sh

View File

@@ -2,6 +2,6 @@
# app-check.sh - Ensures /app/api/table_settings.json exists
if [ ! -f /app/api/table_settings.json ]; then
mkdir -p /app/api
echo -ne '{}' > /app/api/table_settings.json
# mkdir -p /app/api
# echo -ne '{}' > /app/api/table_settings.json
fi

View File

@@ -6,20 +6,26 @@
ERROR_OUTPUT=$(nmap --privileged -sS -p 20211 127.0.0.1 2>&1 >/dev/null)
EXIT_CODE=$?
# If the exit code is exactly 126 AND the error message contains a known permission error...
if [ "$EXIT_CODE" -eq 126 ] && \
echo "$ERROR_OUTPUT" | grep -q -e "Operation not permitted" -e "requires root privileges"
# Flag common capability errors regardless of exact exit code.
if [ "$EXIT_CODE" -ne 0 ] && \
echo "$ERROR_OUTPUT" | grep -q -e "Operation not permitted" -e "requires root privileges"
then
# ...then print the detailed warning.
echo "⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️" >&2
echo " ATTENTION: This container is running without elevated" >&2
echo " network privileges (NET_RAW/NET_ADMIN)." >&2
echo "" >&2
echo " Advanced network tools that require raw socket access," >&2
echo " like 'nmap -sS', will fail." >&2
echo "" >&2
echo " To fix this, restart the container with the following flags:" >&2
echo " --cap-add=NET_RAW --cap-add=NET_ADMIN" >&2
echo "⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️" >&2
YELLOW=$(printf '\033[1;33m')
RESET=$(printf '\033[0m')
>&2 printf "%s" "${YELLOW}"
>&2 cat <<'EOF'
══════════════════════════════════════════════════════════════════════════════
⚠️ ATTENTION: Raw network capabilities are missing.
Tools that rely on NET_RAW/NET_ADMIN/NET_BIND_SERVICE (e.g. nmap -sS,
arp-scan, nbtscan) will not function. Restart the container with:
--cap-add=NET_RAW --cap-add=NET_ADMIN --cap-add=NET_BIND_SERVICE
Without those caps, NetAlertX cannot inspect your network. Fix it before
trusting any results.
══════════════════════════════════════════════════════════════════════════════
EOF
>&2 printf "%s" "${RESET}"
exit 1
fi

View File

@@ -5,6 +5,17 @@
if [ ! -f /app/config/app.conf ]; then
mkdir -p /app/config
cp /app/back/app.conf /app/config/app.conf
echo "🆕 First run detected: Default configuration initialized." >&2
CYAN='\033[1;36m'
RESET='\033[0m'
>&2 printf "%s" "${CYAN}"
>&2 cat <<'EOF'
══════════════════════════════════════════════════════════════════════════════
🆕 First run detected. Default configuration written to /app/config/app.conf.
Review your settings in the UI or edit the file directly before trusting
this instance in production.
══════════════════════════════════════════════════════════════════════════════
EOF
>&2 printf "%s" "${RESET}"
fi

View File

@@ -5,7 +5,18 @@
# if the db exists, exit
test -f "${NETALERTX_DB_FILE}" && exit 0
echo "First run detected, creating initial database schema in ${NETALERTX_DB_FILE}"
CYAN='\033[1;36m'
RESET='\033[0m'
>&2 printf "%s" "${CYAN}"
>&2 cat <<EOF
══════════════════════════════════════════════════════════════════════════════
🆕 First run detected. Building initial database schema in ${NETALERTX_DB_FILE}.
Do not interrupt this step. Once complete, consider backing up the fresh
database before onboarding sensitive networks.
══════════════════════════════════════════════════════════════════════════════
EOF
>&2 printf "%s" "${RESET}"
# Write all text to db file until we see "end-of-database-schema"
cat << end-of-database-schema > ${NETALERTX_DB_FILE}

View File

@@ -1,31 +1,43 @@
#!/bin/sh
# ramdisk-check.sh - Verify critical paths are backed by ramdisk and warn on fallback storage.
# storage-check.sh - Verify critical paths use dedicated mounts.
warn_if_not_ramdisk() {
warn_if_not_dedicated_mount() {
path="$1"
if cat /proc/mounts| grep ${path} | grep -qE 'tmpfs|ramfs'; then
if awk -v target="${path}" '$5 == target {found=1} END {exit found ? 0 : 1}' /proc/self/mountinfo; then
return 0
fi
cat >&2 <<EOF
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
ATTENTION: ${path} is not on a ramdisk.
Mount this folder inside the container as tmpfs or ramfs.
failures=1
YELLOW=$(printf '\033[1;33m')
RESET=$(printf '\033[0m')
>&2 printf "%s" "${YELLOW}"
>&2 cat <<EOF
══════════════════════════════════════════════════════════════════════════════
⚠️ ATTENTION: ${path} is not mounted separately inside this container.
NetAlertX expects this location to live in memory for fast reads and writes.
Running it on disk will severely degrade performance for every user.
NetAlertX runs as a single unprivileged process and pounds this directory
with writes. Leaving it on the container overlay will thrash storage and
slow the stack.
Fix: Please mount ${path} as tmpfs/ramfs.
eg. --mount type=tmpfs,destination=${path}
Restart the container after adding the ramdisk mount.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
Fix: mount ${path} explicitly — tmpfs for ephemeral data, or bind/volume if
you want to preserve history:
--mount type=tmpfs,destination=${path}
# or
--mount type=bind,src=/path/on/host,dst=${path}
Apply the mount and restart the container.
══════════════════════════════════════════════════════════════════════════════
EOF
exit 1
>&2 printf "%s" "${RESET}"
}
warn_if_not_ramdisk "${NETALERTX_API}"
warn_if_not_ramdisk "${NETALERTX_LOG}"
failures=0
warn_if_not_dedicated_mount "${NETALERTX_API}"
warn_if_not_dedicated_mount "${NETALERTX_LOG}"
if [ "${failures}" -ne 0 ]; then
exit 1
fi
if [ ! -f "${SYSTEM_NGINIX_CONFIG}/conf.active" ]; then
echo "Note: Using default listen address ${LISTEN_ADDR}:${PORT} (no ${SYSTEM_NGINIX_CONFIG}/conf.active override)."

View File

@@ -0,0 +1,31 @@
#!/bin/sh
# check-root.sh - ensure the container is not running as root.
CURRENT_UID="$(id -u)"
if [ "${CURRENT_UID}" -eq 0 ]; then
YELLOW=$(printf '\033[1;33m')
RESET=$(printf '\033[0m')
>&2 printf "%s" "${YELLOW}"
>&2 cat <<'EOF'
══════════════════════════════════════════════════════════════════════════════
⚠️ ATTENTION: NetAlertX is running as root (UID 0).
This defeats every hardening safeguard built into the image. You just
handed a high-value network monitoring appliance full control over your
host. If an attacker compromises NetAlertX now, the entire machine goes
with it.
Run the container as the dedicated 'netalertx' user instead:
* Keep the default USER in the image (20211:20211), or
* In docker-compose.yml, remove any 'user:' override that sets UID 0.
Bottom line: never run security tooling as root unless you are actively
trying to get pwned.
══════════════════════════════════════════════════════════════════════════════
EOF
>&2 printf "%s" "${RESET}"
exit 1
fi
exit 0