mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
Compare commits
74 Commits
a27ee5c2f2
...
pr-1279
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a98bac331d | ||
|
|
9f6086e5cf | ||
|
|
c5a1f19567 | ||
|
|
6d70a8a71d | ||
|
|
4161261c43 | ||
|
|
179821a527 | ||
|
|
2028b1a6e3 | ||
|
|
5b871865db | ||
|
|
76bcec335d | ||
|
|
8483a741b4 | ||
|
|
68c8e16828 | ||
|
|
76150b2ca7 | ||
|
|
5cf8a25bae | ||
|
|
593aa16f17 | ||
|
|
af9793c2ed | ||
|
|
552d2a8286 | ||
|
|
7822b11d51 | ||
|
|
cbe5a4a732 | ||
|
|
58de31d0ea | ||
|
|
5c06dc68c6 | ||
|
|
44d65cca96 | ||
|
|
71e0d13bef | ||
|
|
30269a6a73 | ||
|
|
6374219e05 | ||
|
|
6e745fc6d1 | ||
|
|
85aa04c490 | ||
|
|
1fd8d97d56 | ||
|
|
286d5555d2 | ||
|
|
57096a9258 | ||
|
|
c08eb1dbba | ||
|
|
746f1a8922 | ||
|
|
0845b7f445 | ||
|
|
a6fffe06b7 | ||
|
|
ea8cea16c5 | ||
|
|
5452b7287b | ||
|
|
80d7ef7f24 | ||
|
|
dc4da5b4c9 | ||
|
|
59477e7b38 | ||
|
|
6dd7251c84 | ||
|
|
c52e44f90c | ||
|
|
db18ca76b4 | ||
|
|
288427c939 | ||
|
|
90a07c61eb | ||
|
|
13341e35c9 | ||
|
|
4c92a941a8 | ||
|
|
4cec88aaad | ||
|
|
031d810566 | ||
|
|
b806f84946 | ||
|
|
7c90c2e93c | ||
|
|
cb69990734 | ||
|
|
7037cf1bc6 | ||
|
|
71646e1645 | ||
|
|
dde542c484 | ||
|
|
23a0fac973 | ||
|
|
db5381db14 | ||
|
|
f1fbc47508 | ||
|
|
2a9d352322 | ||
|
|
51aa3d4a2e | ||
|
|
70373b1fbd | ||
|
|
e7ed9e0896 | ||
|
|
79887f0bd7 | ||
|
|
a6bc96d2dd | ||
|
|
8edef9e852 | ||
|
|
1e63cec37c | ||
|
|
ff96d38339 | ||
|
|
b89917ca3e | ||
|
|
daea3a2cd7 | ||
|
|
b86f636b12 | ||
|
|
0b08995223 | ||
|
|
f42186b616 | ||
|
|
bc9fb6bcde | ||
|
|
d29700acf8 | ||
|
|
b89a44d0ec | ||
|
|
8cb1836777 |
@@ -46,14 +46,16 @@ ARG INSTALL_DIR=/app
|
||||
|
||||
# NetAlertX app directories
|
||||
ENV NETALERTX_APP=${INSTALL_DIR}
|
||||
ENV NETALERTX_CONFIG=${NETALERTX_APP}/config
|
||||
ENV NETALERTX_DATA=/data
|
||||
ENV NETALERTX_CONFIG=${NETALERTX_DATA}/config
|
||||
ENV NETALERTX_FRONT=${NETALERTX_APP}/front
|
||||
ENV NETALERTX_PLUGINS=${NETALERTX_FRONT}/plugins
|
||||
ENV NETALERTX_SERVER=${NETALERTX_APP}/server
|
||||
ENV NETALERTX_API=${NETALERTX_APP}/api
|
||||
ENV NETALERTX_DB=${NETALERTX_APP}/db
|
||||
ENV NETALERTX_API=/tmp/api
|
||||
ENV NETALERTX_DB=${NETALERTX_DATA}/db
|
||||
ENV NETALERTX_DB_FILE=${NETALERTX_DB}/app.db
|
||||
ENV NETALERTX_BACK=${NETALERTX_APP}/back
|
||||
ENV NETALERTX_LOG=${NETALERTX_APP}/log
|
||||
ENV NETALERTX_LOG=/tmp/log
|
||||
ENV NETALERTX_PLUGINS_LOG=${NETALERTX_LOG}/plugins
|
||||
ENV NETALERTX_CONFIG_FILE=${NETALERTX_CONFIG}/app.conf
|
||||
|
||||
@@ -70,31 +72,35 @@ ENV LOG_EXECUTION_QUEUE=${NETALERTX_LOG}/execution_queue.log
|
||||
ENV LOG_REPORT_OUTPUT_JSON=${NETALERTX_LOG}/report_output.json
|
||||
ENV LOG_STDOUT=${NETALERTX_LOG}/stdout.log
|
||||
ENV LOG_CROND=${NETALERTX_LOG}/crond.log
|
||||
ENV LOG_NGINX_ERROR=${NETALERTX_LOG}/nginx-error.log
|
||||
|
||||
# System Services configuration files
|
||||
ENV ENTRYPOINT_CHECKS=/entrypoint.d
|
||||
ENV SYSTEM_SERVICES=/services
|
||||
ENV SYSTEM_SERVICES_SCRIPTS=${SYSTEM_SERVICES}/scripts
|
||||
ENV SYSTEM_SERVICES_CONFIG=${SYSTEM_SERVICES}/config
|
||||
ENV SYSTEM_NGINX_CONFIG=${SYSTEM_SERVICES_CONFIG}/nginx
|
||||
ENV SYSTEM_NGINX_CONFIG_FILE=${SYSTEM_NGINX_CONFIG}/nginx.conf
|
||||
ENV SYSTEM_SERVICES_ACTIVE_CONFIG=/tmp/nginx/active-config
|
||||
ENV SYSTEM_SERVICES_PHP_FOLDER=${SYSTEM_SERVICES_CONFIG}/php
|
||||
ENV SYSTEM_SERVICES_PHP_FPM_D=${SYSTEM_SERVICES_PHP_FOLDER}/php-fpm.d
|
||||
ENV SYSTEM_SERVICES_CROND=${SYSTEM_SERVICES_CONFIG}/crond
|
||||
ENV SYSTEM_SERVICES_RUN=${SYSTEM_SERVICES}/run
|
||||
ENV SYSTEM_SERVICES_RUN=/tmp/run
|
||||
ENV SYSTEM_SERVICES_RUN_TMP=${SYSTEM_SERVICES_RUN}/tmp
|
||||
ENV SYSTEM_SERVICES_RUN_LOG=${SYSTEM_SERVICES_RUN}/logs
|
||||
ENV PHP_FPM_CONFIG_FILE=${SYSTEM_SERVICES_PHP_FOLDER}/php-fpm.conf
|
||||
ENV READ_ONLY_FOLDERS="${NETALERTX_BACK} ${NETALERTX_FRONT} ${NETALERTX_SERVER} ${SYSTEM_SERVICES} \
|
||||
${SYSTEM_SERVICES_CONFIG}"
|
||||
ENV READ_WRITE_FOLDERS="${NETALERTX_CONFIG} ${NETALERTX_DB} ${NETALERTX_API} ${NETALERTX_LOG} \
|
||||
${NETALERTX_PLUGINS_LOG} ${SYSTEM_SERVICES_RUN} ${SYSTEM_SERVICES_RUN_TMP} \
|
||||
${SYSTEM_SERVICES_RUN_LOG}"
|
||||
${SYSTEM_SERVICES_CONFIG} ${ENTRYPOINT_CHECKS}"
|
||||
ENV READ_WRITE_FOLDERS="${NETALERTX_DATA} ${NETALERTX_CONFIG} ${NETALERTX_DB} ${NETALERTX_API} \
|
||||
${NETALERTX_LOG} ${NETALERTX_PLUGINS_LOG} ${SYSTEM_SERVICES_RUN} \
|
||||
${SYSTEM_SERVICES_RUN_TMP} ${SYSTEM_SERVICES_RUN_LOG} \
|
||||
${SYSTEM_SERVICES_ACTIVE_CONFIG}"
|
||||
|
||||
#Python environment
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV VIRTUAL_ENV=/opt/venv
|
||||
ENV VIRTUAL_ENV_BIN=/opt/venv/bin
|
||||
ENV PYTHONPATH=${NETALERTX_APP}:${NETALERTX_SERVER}:${VIRTUAL_ENV}/lib/python3.12/site-packages
|
||||
ENV PYTHONPATH=${NETALERTX_APP}:${NETALERTX_SERVER}:${NETALERTX_PLUGINS}:${VIRTUAL_ENV}/lib/python3.12/site-packages
|
||||
ENV PATH="${SYSTEM_SERVICES}:${VIRTUAL_ENV_BIN}:$PATH"
|
||||
|
||||
# App Environment
|
||||
@@ -102,7 +108,7 @@ ENV LISTEN_ADDR=0.0.0.0
|
||||
ENV PORT=20211
|
||||
ENV NETALERTX_DEBUG=0
|
||||
ENV VENDORSPATH=/app/back/ieee-oui.txt
|
||||
ENV VENDORSPATH_NEWEST=/services/run/tmp/ieee-oui.txt
|
||||
ENV VENDORSPATH_NEWEST=${SYSTEM_SERVICES_RUN_TMP}/ieee-oui.txt
|
||||
ENV ENVIRONMENT=alpine
|
||||
ENV READ_ONLY_USER=readonly READ_ONLY_GROUP=readonly
|
||||
ENV NETALERTX_USER=netalertx NETALERTX_GROUP=netalertx
|
||||
@@ -126,8 +132,9 @@ COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} install/production-filesystem/
|
||||
COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} --chmod=755 back ${NETALERTX_BACK}
|
||||
COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} --chmod=755 front ${NETALERTX_FRONT}
|
||||
COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} --chmod=755 server ${NETALERTX_SERVER}
|
||||
RUN install -d -o ${NETALERTX_USER} -g ${NETALERTX_GROUP} -m 755 ${NETALERTX_API} \
|
||||
${NETALERTX_LOG} ${SYSTEM_SERVICES_RUN_TMP} ${SYSTEM_SERVICES_RUN_LOG} && \
|
||||
|
||||
# Create required folders with correct ownership and permissions
|
||||
RUN install -d -o ${NETALERTX_USER} -g ${NETALERTX_GROUP} -m 700 ${READ_WRITE_FOLDERS} && \
|
||||
sh -c "find ${NETALERTX_APP} -type f \( -name '*.sh' -o -name 'speedtest-cli' \) \
|
||||
-exec chmod 750 {} \;"
|
||||
|
||||
@@ -184,7 +191,7 @@ RUN chown -R ${READ_ONLY_USER}:${READ_ONLY_GROUP} ${READ_ONLY_FOLDERS} && \
|
||||
chmod -R 600 ${READ_WRITE_FOLDERS} && \
|
||||
find ${READ_WRITE_FOLDERS} -type d -exec chmod 700 {} + && \
|
||||
chown ${READ_ONLY_USER}:${READ_ONLY_GROUP} /entrypoint.sh /opt /opt/venv && \
|
||||
chmod 005 /entrypoint.sh ${SYSTEM_SERVICES}/*.sh /app /opt /opt/venv && \
|
||||
chmod 005 /entrypoint.sh ${SYSTEM_SERVICES}/*.sh ${SYSTEM_SERVICES_SCRIPTS}/* ${ENTRYPOINT_CHECKS}/* /app /opt /opt/venv && \
|
||||
for dir in ${READ_WRITE_FOLDERS}; do \
|
||||
install -d -o ${NETALERTX_USER} -g ${NETALERTX_GROUP} -m 700 "$dir"; \
|
||||
done && \
|
||||
@@ -209,11 +216,14 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
# .devcontainer/scripts/generate-configs.sh
|
||||
# The generator appends this stage to produce .devcontainer/Dockerfile.
|
||||
# Prefer to place dev-only setup here; use setup.sh only for runtime fixes.
|
||||
# Permissions in devcontainer should be of a brutalist nature. They will be
|
||||
# Open and wide to avoid permission issues during development allowing max
|
||||
# flexibility.
|
||||
|
||||
FROM runner AS netalertx-devcontainer
|
||||
ENV INSTALL_DIR=/app
|
||||
|
||||
ENV PYTHONPATH=/workspaces/NetAlertX/test:/workspaces/NetAlertX/server:/app:/app/server:/opt/venv/lib/python3.12/site-packages:/usr/lib/python3.12/site-packages
|
||||
ENV PYTHONPATH=${PYTHONPATH}:/workspaces/NetAlertX/test:/workspaces/NetAlertX/server:/usr/lib/python3.12/site-packages
|
||||
ENV PATH=/services:${PATH}
|
||||
ENV PHP_INI_SCAN_DIR=/services/config/php/conf.d:/etc/php83/conf.d
|
||||
ENV LISTEN_ADDR=0.0.0.0
|
||||
@@ -224,16 +234,28 @@ COPY .devcontainer/resources/devcontainer-overlay/ /
|
||||
USER root
|
||||
# Install common tools, create user, and set up sudo
|
||||
RUN apk add --no-cache git nano vim jq php83-pecl-xdebug py3-pip nodejs sudo gpgconf pytest \
|
||||
pytest-cov fish shfmt github-cli py3-yaml py3-docker-py docker-cli docker-cli-buildx \
|
||||
pytest-cov zsh alpine-zsh-config shfmt github-cli py3-yaml py3-docker-py docker-cli docker-cli-buildx \
|
||||
docker-cli-compose
|
||||
|
||||
RUN install -d -o netalertx -g netalertx -m 755 /services/php/modules && \
|
||||
cp -a /usr/lib/php83/modules/. /services/php/modules/ && \
|
||||
echo "${NETALERTX_USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
RUN mkdir /workspaces && \
|
||||
install -d -o netalertx -g netalertx -m 777 /services/run/logs && \
|
||||
install -d -o netalertx -g netalertx -m 777 /app/run/tmp/client_body && \
|
||||
sed -i -e 's|:/app:|:/workspaces:|' /etc/passwd && \
|
||||
ENV SHELL=/bin/zsh
|
||||
|
||||
RUN mkdir -p /workspaces && \
|
||||
install -d -m 777 /data /data/config /data/db && \
|
||||
install -d -m 777 /tmp/log /tmp/log/plugins /tmp/api /tmp/run /tmp/nginx && \
|
||||
install -d -m 777 /tmp/nginx/active-config /tmp/nginx/client_body /tmp/nginx/config && \
|
||||
install -d -m 777 /tmp/nginx/fastcgi /tmp/nginx/proxy /tmp/nginx/scgi /tmp/nginx/uwsgi && \
|
||||
install -d -m 777 /tmp/run/tmp /tmp/run/logs && \
|
||||
chmod 777 /workspaces && \
|
||||
chown -R netalertx:netalertx /data && \
|
||||
chmod 666 /data/config/app.conf /data/db/app.db && \
|
||||
chmod 1777 /tmp && \
|
||||
install -d -o root -g root -m 1777 /tmp/.X11-unix && \
|
||||
mkdir -p /home/netalertx && \
|
||||
chown netalertx:netalertx /home/netalertx && \
|
||||
sed -i -e 's#/app:#/workspaces:#' /etc/passwd && \
|
||||
find /opt/venv -type d -exec chmod o+rwx {} \;
|
||||
|
||||
USER netalertx
|
||||
|
||||
37
.devcontainer/NetAlertX.code-workspace
Normal file
37
.devcontainer/NetAlertX.code-workspace
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "NetAlertX Source",
|
||||
"path": "/workspaces/NetAlertX"
|
||||
},
|
||||
{
|
||||
"name": "💾 NetAlertX Data",
|
||||
"path": "/data"
|
||||
},
|
||||
{
|
||||
"name": "🔍 Active NetAlertX log",
|
||||
"path": "/tmp/log"
|
||||
},
|
||||
{
|
||||
"name": "🌐 Active NetAlertX nginx",
|
||||
"path": "/tmp/nginx"
|
||||
},
|
||||
{
|
||||
"name": "📊 Active NetAlertX api",
|
||||
"path": "/tmp/api"
|
||||
},
|
||||
{
|
||||
"name": "⚙️ Active NetAlertX run",
|
||||
"path": "/tmp/run"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"terminal.integrated.suggest.enabled": true,
|
||||
"terminal.integrated.defaultProfile.linux": "zsh",
|
||||
"terminal.integrated.profiles.linux": {
|
||||
"zsh": {
|
||||
"path": "/usr/bin/fish"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,17 @@ Common workflows (F1->Tasks: Run Task)
|
||||
- Backend (GraphQL/Flask): `.devcontainer/scripts/restart-backend.sh` starts it under debugpy and logs to `/app/log/app.log`
|
||||
- Frontend (nginx + PHP-FPM): Started via setup.sh; can be restarted by the task "Start Frontend (nginx and PHP-FPM)".
|
||||
|
||||
Production Container Evaulation
|
||||
1. F1 → Tasks: Shutdown services ([Dev Container] Stop Frontend & Backend Services)
|
||||
2. F1 → Tasks: Docker system and build prune ([Any] Docker system and build Prune)
|
||||
3. F1 → Remote: Close Unused Forwarded Ports (VS Code command)
|
||||
4. F1 → Tasks: Build & Launch Production (Build & Launch Prodcution Docker
|
||||
5. visit http://localhost:20211
|
||||
|
||||
Unit tests
|
||||
1. F1 → Tasks: Rebuild test container ([Any] Build Unit Test Docker image)
|
||||
2. F1 → Test: Run all tests
|
||||
|
||||
Testing
|
||||
- pytest is installed via Alpine packages (py3-pytest, py3-pytest-cov).
|
||||
- PYTHONPATH includes workspace and venv site-packages so tests can import `server/*` modules and third-party libs.
|
||||
|
||||
26
.devcontainer/WORKSPACE.md
Normal file
26
.devcontainer/WORKSPACE.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# NetAlertX Multi-Folder Workspace
|
||||
|
||||
This repository uses a multi-folder workspace configuration to provide easy access to runtime directories.
|
||||
|
||||
## Opening the Multi-Folder Workspace
|
||||
|
||||
After the devcontainer builds, open the workspace file to access all folders:
|
||||
|
||||
1. **File** → **Open Workspace from File**
|
||||
2. Select `NetAlertX.code-workspace`
|
||||
|
||||
Or use Command Palette (Ctrl+Shift+P / Cmd+Shift+P):
|
||||
- Type: `Workspaces: Open Workspace from File`
|
||||
- Select `NetAlertX.code-workspace`
|
||||
|
||||
## Workspace Folders
|
||||
|
||||
The workspace includes:
|
||||
- **NetAlertX** - Main source code
|
||||
- **/tmp** - Runtime temporary files
|
||||
- **/tmp/api** - API response cache (JSON files)
|
||||
- **/tmp/log** - Application and plugin logs
|
||||
|
||||
## Testing Configuration
|
||||
|
||||
Pytest is configured to only discover tests in the main `test/` directory, not in `/tmp` folders.
|
||||
@@ -2,6 +2,8 @@
|
||||
"name": "NetAlertX DevContainer",
|
||||
"remoteUser": "netalertx",
|
||||
"workspaceFolder": "/workspaces/NetAlertX",
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/NetAlertX,type=bind,consistency=cached",
|
||||
"onCreateCommand": "mkdir -p /tmp/api /tmp/log",
|
||||
"build": {
|
||||
"dockerfile": "./Dockerfile", // Dockerfile generated by script
|
||||
"context": "../", // Context is the root of the repository
|
||||
@@ -44,7 +46,8 @@
|
||||
},
|
||||
|
||||
"postCreateCommand": {
|
||||
"Install Pip Requirements": "/opt/venv/bin/pip3 install pytest docker debugpy"
|
||||
"Install Pip Requirements": "/opt/venv/bin/pip3 install pytest docker debugpy",
|
||||
"Workspace Instructions": "printf '\n\n<> DevContainer Ready!\n\n📁 To access /tmp folders in the workspace:\n File → Open Workspace from File → NetAlertX.code-workspace\n\n📖 See .devcontainer/WORKSPACE.md for details\n\n'"
|
||||
},
|
||||
"postStartCommand": {
|
||||
"Start Environment":"${containerWorkspaceFolder}/.devcontainer/scripts/setup.sh",
|
||||
@@ -70,15 +73,25 @@
|
||||
"esbenp.prettier-vscode",
|
||||
"eamodio.gitlens",
|
||||
"alexcvzz.vscode-sqlite",
|
||||
"yzhang.markdown-all-in-one",
|
||||
"mkhl.shfmt"
|
||||
"mkhl.shfmt",
|
||||
"charliermarsh.ruff",
|
||||
"ms-python.flake8"
|
||||
],
|
||||
"settings": {
|
||||
"terminal.integrated.cwd": "${containerWorkspaceFolder}",
|
||||
"terminal.integrated.profiles.linux": {
|
||||
"zsh": {
|
||||
"path": "/bin/zsh",
|
||||
"args": ["-l"]
|
||||
}
|
||||
},
|
||||
"terminal.integrated.defaultProfile.linux": "zsh",
|
||||
|
||||
// Python testing configuration
|
||||
"python.testing.pytestEnabled": true,
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestArgs": ["test"],
|
||||
"python.testing.cwd": "${containerWorkspaceFolder}",
|
||||
// Make sure we discover tests and import server correctly
|
||||
"python.analysis.extraPaths": [
|
||||
"/workspaces/NetAlertX",
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
# .devcontainer/scripts/generate-configs.sh
|
||||
# The generator appends this stage to produce .devcontainer/Dockerfile.
|
||||
# Prefer to place dev-only setup here; use setup.sh only for runtime fixes.
|
||||
# Permissions in devcontainer should be of a brutalist nature. They will be
|
||||
# Open and wide to avoid permission issues during development allowing max
|
||||
# flexibility.
|
||||
|
||||
FROM runner AS netalertx-devcontainer
|
||||
ENV INSTALL_DIR=/app
|
||||
|
||||
ENV PYTHONPATH=/workspaces/NetAlertX/test:/workspaces/NetAlertX/server:/app:/app/server:/opt/venv/lib/python3.12/site-packages:/usr/lib/python3.12/site-packages
|
||||
ENV PYTHONPATH=${PYTHONPATH}:/workspaces/NetAlertX/test:/workspaces/NetAlertX/server:/usr/lib/python3.12/site-packages
|
||||
ENV PATH=/services:${PATH}
|
||||
ENV PHP_INI_SCAN_DIR=/services/config/php/conf.d:/etc/php83/conf.d
|
||||
ENV LISTEN_ADDR=0.0.0.0
|
||||
@@ -18,16 +21,28 @@ COPY .devcontainer/resources/devcontainer-overlay/ /
|
||||
USER root
|
||||
# Install common tools, create user, and set up sudo
|
||||
RUN apk add --no-cache git nano vim jq php83-pecl-xdebug py3-pip nodejs sudo gpgconf pytest \
|
||||
pytest-cov fish shfmt github-cli py3-yaml py3-docker-py docker-cli docker-cli-buildx \
|
||||
pytest-cov zsh alpine-zsh-config shfmt github-cli py3-yaml py3-docker-py docker-cli docker-cli-buildx \
|
||||
docker-cli-compose
|
||||
|
||||
RUN install -d -o netalertx -g netalertx -m 755 /services/php/modules && \
|
||||
cp -a /usr/lib/php83/modules/. /services/php/modules/ && \
|
||||
echo "${NETALERTX_USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
RUN mkdir /workspaces && \
|
||||
install -d -o netalertx -g netalertx -m 777 /services/run/logs && \
|
||||
install -d -o netalertx -g netalertx -m 777 /app/run/tmp/client_body && \
|
||||
sed -i -e 's|:/app:|:/workspaces:|' /etc/passwd && \
|
||||
ENV SHELL=/bin/zsh
|
||||
|
||||
RUN mkdir -p /workspaces && \
|
||||
install -d -m 777 /data /data/config /data/db && \
|
||||
install -d -m 777 /tmp/log /tmp/log/plugins /tmp/api /tmp/run /tmp/nginx && \
|
||||
install -d -m 777 /tmp/nginx/active-config /tmp/nginx/client_body /tmp/nginx/config && \
|
||||
install -d -m 777 /tmp/nginx/fastcgi /tmp/nginx/proxy /tmp/nginx/scgi /tmp/nginx/uwsgi && \
|
||||
install -d -m 777 /tmp/run/tmp /tmp/run/logs && \
|
||||
chmod 777 /workspaces && \
|
||||
chown -R netalertx:netalertx /data && \
|
||||
chmod 666 /data/config/app.conf /data/db/app.db && \
|
||||
chmod 1777 /tmp && \
|
||||
install -d -o root -g root -m 1777 /tmp/.X11-unix && \
|
||||
mkdir -p /home/netalertx && \
|
||||
chown netalertx:netalertx /home/netalertx && \
|
||||
sed -i -e 's#/app:#/workspaces:#' /etc/passwd && \
|
||||
find /opt/venv -type d -exec chmod o+rwx {} \;
|
||||
|
||||
USER netalertx
|
||||
|
||||
@@ -8,7 +8,9 @@ worker_processes auto;
|
||||
pcre_jit on;
|
||||
|
||||
# Configures default error logger.
|
||||
error_log /app/log/nginx-error.log warn;
|
||||
error_log /tmp/log/nginx-error.log warn;
|
||||
|
||||
pid /tmp/run/nginx.pid;
|
||||
|
||||
events {
|
||||
# The maximum number of simultaneous connections that can be opened by
|
||||
@@ -17,13 +19,12 @@ events {
|
||||
}
|
||||
|
||||
http {
|
||||
|
||||
# Mapping of temp paths for various nginx modules.
|
||||
client_body_temp_path /services/run/tmp/client_body;
|
||||
proxy_temp_path /services/run/tmp/proxy;
|
||||
fastcgi_temp_path /services/run/tmp/fastcgi;
|
||||
uwsgi_temp_path /services/run/tmp/uwsgi;
|
||||
scgi_temp_path /services/run/tmp/scgi;
|
||||
client_body_temp_path /tmp/nginx/client_body;
|
||||
proxy_temp_path /tmp/nginx/proxy;
|
||||
fastcgi_temp_path /tmp/nginx/fastcgi;
|
||||
uwsgi_temp_path /tmp/nginx/uwsgi;
|
||||
scgi_temp_path /tmp/nginx/scgi;
|
||||
|
||||
# Includes mapping of file name extensions to MIME types of responses
|
||||
# and defines the default type.
|
||||
@@ -89,7 +90,7 @@ http {
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
# Sets the path, format, and configuration for a buffered log write.
|
||||
access_log /app/log/nginx-access.log main;
|
||||
access_log /tmp/log/nginx-access.log main;
|
||||
|
||||
|
||||
# Virtual host config
|
||||
@@ -100,11 +101,10 @@ http {
|
||||
index index.php;
|
||||
add_header X-Forwarded-Prefix "/app" always;
|
||||
|
||||
|
||||
location ~* \.php$ {
|
||||
# Set Cache-Control header to prevent caching on the first load
|
||||
add_header Cache-Control "no-store";
|
||||
fastcgi_pass unix:/services/run/php.sock;
|
||||
fastcgi_pass unix:/tmp/run/php.sock;
|
||||
include /services/config/nginx/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# NetAlertX devcontainer zsh configuration
|
||||
# Keep this lightweight and deterministic so shells behave consistently.
|
||||
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
export EDITOR=vim
|
||||
export SHELL=/bin/zsh
|
||||
|
||||
# Start inside the workspace if it exists
|
||||
if [ -d "/workspaces/NetAlertX" ]; then
|
||||
cd /workspaces/NetAlertX
|
||||
fi
|
||||
|
||||
# Enable basic completion and prompt helpers
|
||||
autoload -Uz compinit promptinit colors
|
||||
colors
|
||||
compinit -u
|
||||
promptinit
|
||||
|
||||
# Friendly prompt with virtualenv awareness
|
||||
setopt PROMPT_SUBST
|
||||
|
||||
_venv_segment() {
|
||||
if [ -n "$VIRTUAL_ENV" ]; then
|
||||
printf '(%s) ' "${VIRTUAL_ENV:t}"
|
||||
fi
|
||||
}
|
||||
|
||||
PROMPT='%F{green}$(_venv_segment)%f%F{cyan}%n@%m%f %F{yellow}%~%f %# '
|
||||
RPROMPT='%F{magenta}$(git rev-parse --abbrev-ref HEAD 2>/dev/null)%f'
|
||||
|
||||
# Sensible defaults
|
||||
setopt autocd
|
||||
setopt correct
|
||||
setopt extendedglob
|
||||
HISTFILE="$HOME/.zsh_history"
|
||||
HISTSIZE=5000
|
||||
SAVEHIST=5000
|
||||
|
||||
alias ll='ls -alF'
|
||||
alias la='ls -A'
|
||||
alias gs='git status -sb'
|
||||
alias gp='git pull --ff-only'
|
||||
|
||||
# Ensure pyenv/virtualenv activate hooks adjust the prompt cleanly
|
||||
if [ -f "$HOME/.zshrc.local" ]; then
|
||||
source "$HOME/.zshrc.local"
|
||||
fi
|
||||
@@ -1,7 +1,11 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
read -r -p "Are you sure you want to destroy your host docker containers and images? Type YES to continue: " reply
|
||||
if [[ -n "${CONFIRM_PRUNE:-}" && "${CONFIRM_PRUNE}" == "YES" ]]; then
|
||||
reply="YES"
|
||||
else
|
||||
read -r -p "Are you sure you want to destroy your host docker containers and images? Type YES to continue: " reply
|
||||
fi
|
||||
|
||||
if [[ "${reply}" == "YES" ]]; then
|
||||
docker system prune -af
|
||||
|
||||
@@ -1,184 +1,110 @@
|
||||
#!/bin/bash
|
||||
# Runtime setup for devcontainer (executed after container starts).
|
||||
# Prefer building setup into resources/devcontainer-Dockerfile when possible.
|
||||
# Use this script for runtime-only adjustments (permissions, sockets, ownership,
|
||||
# and services managed without init) that are difficult at build time.
|
||||
id
|
||||
|
||||
# Define variables (paths, ports, environment)
|
||||
|
||||
export APP_DIR="/app"
|
||||
export APP_COMMAND="/workspaces/NetAlertX/.devcontainer/scripts/restart-backend.sh"
|
||||
export PHP_FPM_BIN="/usr/sbin/php-fpm83"
|
||||
export CROND_BIN="/usr/sbin/crond -f"
|
||||
# NetAlertX Devcontainer Setup Script
|
||||
#
|
||||
# This script forcefully resets all runtime state for a single-user devcontainer.
|
||||
# It is intentionally idempotent: every run wipes and recreates all relevant folders,
|
||||
# symlinks, and files, so the environment is always fresh and predictable.
|
||||
#
|
||||
# - No conditional logic: everything is (re)created, overwritten, or reset unconditionally.
|
||||
# - No security hardening: this is for disposable, local dev use only.
|
||||
# - No checks for existing files, mounts, or processes—just do the work.
|
||||
#
|
||||
# If you add new runtime files or folders, add them to the creation/reset section below.
|
||||
#
|
||||
# Do not add if-then logic or error handling for missing/existing files. Simplicity is the goal.
|
||||
|
||||
|
||||
export ALWAYS_FRESH_INSTALL=false
|
||||
export INSTALL_DIR=/app
|
||||
export LOGS_LOCATION=/app/logs
|
||||
export CONF_FILE="app.conf"
|
||||
export DB_FILE="app.db"
|
||||
export FULL_FILEDB_PATH="${INSTALL_DIR}/db/${DB_FILE}"
|
||||
export OUI_FILE="/usr/share/arp-scan/ieee-oui.txt" # Define the path to ieee-oui.txt and ieee-iab.txt
|
||||
export TZ=Europe/Paris
|
||||
export PORT=20211
|
||||
export SOURCE_DIR="/workspaces/NetAlertX"
|
||||
SOURCE_DIR=${SOURCE_DIR:-/workspaces/NetAlertX}
|
||||
PY_SITE_PACKAGES="${VIRTUAL_ENV:-/opt/venv}/lib/python3.12/site-packages"
|
||||
SOURCE_SERVICES_DIR="${SOURCE_DIR}/install/production-filesystem/services"
|
||||
|
||||
LOG_FILES=(
|
||||
LOG_APP
|
||||
LOG_APP_FRONT
|
||||
LOG_STDOUT
|
||||
LOG_STDERR
|
||||
LOG_EXECUTION_QUEUE
|
||||
LOG_APP_PHP_ERRORS
|
||||
LOG_IP_CHANGES
|
||||
LOG_CROND
|
||||
LOG_REPORT_OUTPUT_TXT
|
||||
LOG_REPORT_OUTPUT_HTML
|
||||
LOG_REPORT_OUTPUT_JSON
|
||||
LOG_DB_IS_LOCKED
|
||||
LOG_NGINX_ERROR
|
||||
)
|
||||
|
||||
ensure_docker_socket_access() {
|
||||
local socket="/var/run/docker.sock"
|
||||
if [ ! -S "${socket}" ]; then
|
||||
echo "docker socket not present; skipping docker group configuration"
|
||||
return
|
||||
fi
|
||||
sudo chmod 666 /var/run/docker.sock 2>/dev/null || true
|
||||
sudo chown "$(id -u)":"$(id -g)" /workspaces
|
||||
sudo chmod 755 /workspaces
|
||||
|
||||
local sock_gid
|
||||
sock_gid=$(stat -c '%g' "${socket}" 2>/dev/null || true)
|
||||
if [ -z "${sock_gid}" ]; then
|
||||
echo "unable to determine docker socket gid; skipping docker group configuration"
|
||||
return
|
||||
fi
|
||||
killall php-fpm83 nginx crond python3 2>/dev/null || true
|
||||
|
||||
local group_entry=""
|
||||
if command -v getent >/dev/null 2>&1; then
|
||||
group_entry=$(getent group "${sock_gid}" 2>/dev/null || true)
|
||||
else
|
||||
group_entry=$(grep -E ":${sock_gid}:" /etc/group 2>/dev/null || true)
|
||||
fi
|
||||
# Mount ramdisks for volatile data
|
||||
sudo mount -t tmpfs -o size=100m,mode=0777 tmpfs /tmp/log 2>/dev/null || true
|
||||
sudo mount -t tmpfs -o size=50m,mode=0777 tmpfs /tmp/api 2>/dev/null || true
|
||||
sudo mount -t tmpfs -o size=50m,mode=0777 tmpfs /tmp/run 2>/dev/null || true
|
||||
sudo mount -t tmpfs -o size=50m,mode=0777 tmpfs /tmp/nginx 2>/dev/null || true
|
||||
|
||||
local group_name=""
|
||||
if [ -n "${group_entry}" ]; then
|
||||
group_name=$(echo "${group_entry}" | cut -d: -f1)
|
||||
else
|
||||
group_name="docker-host"
|
||||
sudo addgroup -g "${sock_gid}" "${group_name}" 2>/dev/null || group_name=$(grep -E ":${sock_gid}:" /etc/group | head -n1 | cut -d: -f1)
|
||||
fi
|
||||
|
||||
if [ -z "${group_name}" ]; then
|
||||
echo "failed to resolve group for docker socket gid ${sock_gid}; skipping docker group configuration"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! id -nG netalertx | tr ' ' '\n' | grep -qx "${group_name}"; then
|
||||
sudo addgroup netalertx "${group_name}" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
main() {
|
||||
echo "=== NetAlertX Development Container Setup ==="
|
||||
killall php-fpm83 nginx crond python3 2>/dev/null
|
||||
sleep 1
|
||||
echo "Setting up ${SOURCE_DIR}..."
|
||||
ensure_docker_socket_access
|
||||
sudo chown $(id -u):$(id -g) /workspaces
|
||||
sudo chmod 755 /workspaces
|
||||
configure_source
|
||||
|
||||
echo "--- Starting Development Services ---"
|
||||
configure_php
|
||||
|
||||
|
||||
start_services
|
||||
}
|
||||
|
||||
isRamDisk() {
|
||||
if [ -z "$1" ] || [ ! -d "$1" ]; then
|
||||
echo "Usage: isRamDisk <directory>" >&2
|
||||
return 2
|
||||
fi
|
||||
|
||||
local fstype
|
||||
fstype=$(df -T "$1" | awk 'NR==2 {print $2}')
|
||||
|
||||
if [ "$fstype" = "tmpfs" ] || [ "$fstype" = "ramfs" ]; then
|
||||
return 0 # Success (is a ramdisk)
|
||||
else
|
||||
return 1 # Failure (is not a ramdisk)
|
||||
fi
|
||||
}
|
||||
|
||||
# Setup source directory
|
||||
configure_source() {
|
||||
echo "[1/4] Configuring System..."
|
||||
echo " -> Setting up /services permissions"
|
||||
sudo chown -R netalertx /services
|
||||
|
||||
echo "[2/4] Configuring Source..."
|
||||
echo " -> Cleaning up previous instances"
|
||||
|
||||
test -e ${NETALERTX_LOG} && sudo umount "${NETALERTX_LOG}" 2>/dev/null || true
|
||||
test -e ${NETALERTX_API} && sudo umount "${NETALERTX_API}" 2>/dev/null || true
|
||||
test -e ${NETALERTX_APP} && sudo rm -Rf ${NETALERTX_APP}/
|
||||
|
||||
echo " -> Linking source to ${NETALERTX_APP}"
|
||||
sudo ln -s ${SOURCE_DIR}/ ${NETALERTX_APP}
|
||||
|
||||
echo " -> Mounting ramdisks for /log and /api"
|
||||
mkdir -p ${NETALERTX_LOG} ${NETALERTX_API}
|
||||
sudo mount -o uid=$(id -u netalertx),gid=$(id -g netalertx),mode=775 -t tmpfs -o size=256M tmpfs "${NETALERTX_LOG}"
|
||||
sudo mount -o uid=$(id -u netalertx),gid=$(id -g netalertx),mode=775 -t tmpfs -o size=256M tmpfs "${NETALERTX_API}"
|
||||
mkdir -p ${NETALERTX_PLUGINS_LOG}
|
||||
touch ${NETALERTX_PLUGINS_LOG}/.dockerignore ${NETALERTX_API}/.dockerignore
|
||||
# tmpfs mounts configured with netalertx ownership and 775 permissions above
|
||||
|
||||
touch /app/log/nginx_error.log
|
||||
echo " -> Empty log"|tee ${INSTALL_DIR}/log/app.log \
|
||||
${INSTALL_DIR}/log/app_front.log \
|
||||
${INSTALL_DIR}/log/stdout.log
|
||||
touch ${INSTALL_DIR}/log/stderr.log \
|
||||
${INSTALL_DIR}/log/execution_queue.log
|
||||
echo 0 > ${INSTALL_DIR}/log/db_is_locked.log
|
||||
for f in ${INSTALL_DIR}/log/*.log; do
|
||||
sudo chown netalertx:www-data $f
|
||||
sudo chmod 664 $f
|
||||
echo "" > $f
|
||||
done
|
||||
|
||||
mkdir -p /app/log/plugins
|
||||
sudo chown -R netalertx:www-data ${INSTALL_DIR}
|
||||
|
||||
|
||||
while ps ax | grep -v grep | grep python3 > /dev/null; do
|
||||
killall python3 &>/dev/null
|
||||
sleep 0.2
|
||||
done
|
||||
sudo chmod 777 /opt/venv/lib/python3.12/site-packages/ && \
|
||||
sudo chmod 005 /opt/venv/lib/python3.12/site-packages/
|
||||
sudo chmod 666 /var/run/docker.sock
|
||||
|
||||
echo " -> Updating build timestamp"
|
||||
date +%s > ${NETALERTX_FRONT}/buildtimestamp.txt
|
||||
|
||||
}
|
||||
|
||||
# configure_php: configure PHP-FPM and enable dev debug options
|
||||
configure_php() {
|
||||
echo "[3/4] Configuring PHP-FPM..."
|
||||
sudo chown -R netalertx:netalertx ${SYSTEM_SERVICES_RUN} 2>/dev/null || true
|
||||
|
||||
}
|
||||
|
||||
# start_services: start crond, PHP-FPM, nginx and the application
|
||||
start_services() {
|
||||
echo "[4/4] Starting services"
|
||||
|
||||
sudo chmod +x /entrypoint.sh
|
||||
setsid bash /entrypoint.sh&
|
||||
sleep 1
|
||||
}
|
||||
|
||||
|
||||
sudo chmod 755 /app/
|
||||
echo "Development $(git rev-parse --short=8 HEAD)"| sudo tee /app/.VERSION
|
||||
# Run the main function
|
||||
main
|
||||
|
||||
# create a services readme file
|
||||
echo "This folder is auto-generated by the container and devcontainer setup.sh script." > /services/README.md
|
||||
echo "Any changes here will be lost on rebuild. To make permanent changes, edit files in .devcontainer or production filesystem and rebuild the container." >> /services/README.md
|
||||
echo "Only make temporary/test changes in this folder, then perform a rebuild to reset." >> /services/README.md
|
||||
sudo chmod 777 /tmp/log /tmp/api /tmp/run /tmp/nginx
|
||||
|
||||
|
||||
|
||||
sudo rm -rf "${SYSTEM_NGINX_CONFIG}/conf.active"
|
||||
sudo ln -s "${SYSTEM_SERVICES_ACTIVE_CONFIG}" "${SYSTEM_NGINX_CONFIG}/conf.active"
|
||||
|
||||
sudo rm -rf /entrypoint.d
|
||||
sudo ln -s "${SOURCE_DIR}/install/production-filesystem/entrypoint.d" /entrypoint.d
|
||||
|
||||
sudo rm -rf "${NETALERTX_APP}"
|
||||
sudo ln -s "${SOURCE_DIR}/" "${NETALERTX_APP}"
|
||||
|
||||
for dir in "${NETALERTX_DATA}" "${NETALERTX_CONFIG}" "${NETALERTX_DB}"; do
|
||||
sudo install -d -m 777 "${dir}"
|
||||
done
|
||||
|
||||
for dir in \
|
||||
"${SYSTEM_SERVICES_RUN_LOG}" \
|
||||
"${SYSTEM_SERVICES_ACTIVE_CONFIG}" \
|
||||
"${NETALERTX_PLUGINS_LOG}" \
|
||||
"/tmp/nginx/client_body" \
|
||||
"/tmp/nginx/proxy" \
|
||||
"/tmp/nginx/fastcgi" \
|
||||
"/tmp/nginx/uwsgi" \
|
||||
"/tmp/nginx/scgi"; do
|
||||
sudo install -d -m 777 "${dir}"
|
||||
done
|
||||
|
||||
# Create nginx temp subdirs with permissions
|
||||
sudo mkdir -p "${SYSTEM_SERVICES_RUN_TMP}/client_body" "${SYSTEM_SERVICES_RUN_TMP}/proxy" "${SYSTEM_SERVICES_RUN_TMP}/fastcgi" "${SYSTEM_SERVICES_RUN_TMP}/uwsgi" "${SYSTEM_SERVICES_RUN_TMP}/scgi"
|
||||
sudo chmod -R 777 "${SYSTEM_SERVICES_RUN_TMP}"
|
||||
|
||||
for var in "${LOG_FILES[@]}"; do
|
||||
path=${!var}
|
||||
dir=$(dirname "${path}")
|
||||
sudo install -d -m 777 "${dir}"
|
||||
touch "${path}"
|
||||
done
|
||||
|
||||
printf '0\n' | sudo tee "${LOG_DB_IS_LOCKED}" >/dev/null
|
||||
sudo chmod 777 "${LOG_DB_IS_LOCKED}"
|
||||
|
||||
sudo pkill -f python3 2>/dev/null || true
|
||||
|
||||
sudo chmod 777 "${PY_SITE_PACKAGES}" "${NETALERTX_DATA}" "${NETALERTX_DATA}"/* 2>/dev/null || true
|
||||
|
||||
sudo chmod 005 "${PY_SITE_PACKAGES}" 2>/dev/null || true
|
||||
|
||||
sudo chown -R "${NETALERTX_USER}:${NETALERTX_GROUP}" "${NETALERTX_APP}"
|
||||
date +%s | sudo tee "${NETALERTX_FRONT}/buildtimestamp.txt" >/dev/null
|
||||
|
||||
sudo chmod 755 "${NETALERTX_APP}"
|
||||
|
||||
sudo chmod +x /entrypoint.sh
|
||||
setsid bash /entrypoint.sh &
|
||||
sleep 1
|
||||
|
||||
echo "Development $(git rev-parse --short=8 HEAD)" | sudo tee "${NETALERTX_APP}/.VERSION" >/dev/null
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.dockerignore
|
||||
**/.dockerignore
|
||||
.env
|
||||
.git
|
||||
.github
|
||||
|
||||
3
.flake8
Normal file
3
.flake8
Normal file
@@ -0,0 +1,3 @@
|
||||
[flake8]
|
||||
max-line-length = 180
|
||||
ignore = E221,E222,E251,E203
|
||||
24
.github/ISSUE_TEMPLATE/i-have-an-issue.yml
vendored
24
.github/ISSUE_TEMPLATE/i-have-an-issue.yml
vendored
@@ -46,7 +46,7 @@ body:
|
||||
attributes:
|
||||
label: app.conf
|
||||
description: |
|
||||
Paste your `app.conf` (remove personal info)
|
||||
Paste relevant `app.conf`settings (remove sensitive info)
|
||||
render: python
|
||||
validations:
|
||||
required: false
|
||||
@@ -70,6 +70,13 @@ body:
|
||||
- Bare-metal (community only support - Check Discord)
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Debug or Trace enabled
|
||||
description: I confirm I set `LOG_LEVEL` to `debug` or `trace`
|
||||
options:
|
||||
- label: I have read and followed the steps in the wiki link above and provided the required debug logs and the log section covers the time when the issue occurs.
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: app.log
|
||||
@@ -78,13 +85,14 @@ body:
|
||||
***Generally speaking, all bug reports should have logs provided.***
|
||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||
Additionally, any additional info? Screenshots? References? Anything that will give us more context about the issue you are encountering!
|
||||
You can use `tail -100 /app/log/app.log` in the container if you have trouble getting to the log files.
|
||||
You can use `tail -100 /app/log/app.log` in the container if you have trouble getting to the log files or send them to netalertx@gmail.com with the issue number.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Debug enabled
|
||||
description: I confirm I enabled `debug`
|
||||
options:
|
||||
- label: I have read and followed the steps in the wiki link above and provided the required debug logs and the log section covers the time when the issue occurs.
|
||||
required: true
|
||||
label: Docker Logs
|
||||
description: |
|
||||
You can retrieve the logs from Portainer -> Containers -> your NetAlertX container -> Logs or by running `sudo docker logs netalertx`.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
19
.github/copilot-instructions.md
vendored
19
.github/copilot-instructions.md
vendored
@@ -18,7 +18,7 @@ Backend loop phases (see `server/__main__.py` and `server/plugin.py`): `once`, `
|
||||
## Plugin patterns that matter
|
||||
- Manifest lives at `front/plugins/<code_name>/config.json`; `code_name` == folder, `unique_prefix` drives settings and filenames (e.g., `ARPSCAN`).
|
||||
- Control via settings: `<PREF>_RUN` (phase), `<PREF>_RUN_SCHD` (cron-like), `<PREF>_CMD` (script path), `<PREF>_RUN_TIMEOUT`, `<PREF>_WATCH` (diff columns).
|
||||
- Data contract: scripts write `/app/log/plugins/last_result.<PREF>.log` (pipe‑delimited: 9 required cols + optional 4). Use `front/plugins/plugin_helper.py`’s `Plugin_Objects` to sanitize text and normalize MACs, then `write_result_file()`.
|
||||
- Data contract: scripts write `/tmp/log/plugins/last_result.<PREF>.log` (pipe‑delimited: 9 required cols + optional 4). Use `front/plugins/plugin_helper.py`’s `Plugin_Objects` to sanitize text and normalize MACs, then `write_result_file()`.
|
||||
- Device import: define `database_column_definitions` when creating/updating devices; watched fields trigger notifications.
|
||||
|
||||
### Standard Plugin Formats
|
||||
@@ -30,6 +30,7 @@ Backend loop phases (see `server/__main__.py` and `server/plugin.py`): `once`, `
|
||||
* other: Miscellaneous plugins. Runs at various times. Data source: self / Template.
|
||||
|
||||
### Plugin logging & outputs
|
||||
- Always check relevant logs first.
|
||||
- Use logging as shown in other plugins.
|
||||
- Collect results with `Plugin_Objects.add_object(...)` during processing and call `plugin_objects.write_result_file()` exactly once at the end of the script.
|
||||
- Prefer to log a brief summary before writing (e.g., total objects added) to aid troubleshooting; keep logs concise at `info` level and use `verbose` or `debug` for extra context.
|
||||
@@ -42,22 +43,32 @@ Backend loop phases (see `server/__main__.py` and `server/plugin.py`): `once`, `
|
||||
## Conventions & helpers to reuse
|
||||
- Settings: add/modify via `ccd()` in `server/initialise.py` or per‑plugin manifest. Never hardcode ports or secrets; use `get_setting_value()`.
|
||||
- Logging: use `logger.mylog(level, [message])`; levels: none/minimal/verbose/debug/trace.
|
||||
- Time/MAC/strings: `helper.py` (`timeNowTZ`, `normalize_mac`, sanitizers). Validate MACs before DB writes.
|
||||
- Time/MAC/strings: `helper.py` (`timeNowDB`, `normalize_mac`, sanitizers). Validate MACs before DB writes.
|
||||
- DB helpers: prefer `server/db/db_helper.py` functions (e.g., `get_table_json`, device condition helpers) over raw SQL in new paths.
|
||||
|
||||
## Dev workflow (devcontainer)
|
||||
- **Devcontainer philosophy: brutal simplicity.** One user, everything writable, completely idempotent. No permission checks, no conditional logic, no sudo needed. If something doesn't work, tear down the wall and rebuild - don't patch. We unit test permissions in the hardened build.
|
||||
- **Permissions:** Never `chmod` or `chown` during operations. Everything is already writable. If you need permissions, the devcontainer setup is broken - fix `.devcontainer/scripts/setup.sh` or `.devcontainer/resources/devcontainer-Dockerfile` instead.
|
||||
- **Files & Paths:** Use environment variables (`NETALERTX_DB`, `NETALERTX_LOG`, etc.) everywhere. `/data` for persistent config/db, `/tmp` for runtime logs/api/nginx state. Never hardcode `/data/db` or relative paths.
|
||||
- **Database reset:** Use the `[Dev Container] Wipe and Regenerate Database` task. Kills backend, deletes `/data/{db,config}/*`, runs first-time setup scripts. Clean slate, no questions.
|
||||
- Services: use tasks to (re)start backend and nginx/PHP-FPM. Backend runs with debugpy on 5678; attach a Python debugger if needed.
|
||||
- Run a plugin manually: `python3 front/plugins/<code_name>/script.py` (ensure `sys.path` includes `/app/front/plugins` and `/app/server` like the template).
|
||||
- Testing: pytest available via Alpine packages. Tests live in `test/`; app code is under `server/`. PYTHONPATH is preconfigured to include workspace and `/opt/venv` site‑packages.
|
||||
- **Subprocess calls:** ALWAYS set explicit timeouts. Default to 60s minimum unless plugin config specifies otherwise. Nested subprocess calls (e.g., plugins calling external tools) need their own timeout - outer plugin timeout won't save you.
|
||||
|
||||
## What “done right” looks like
|
||||
- When adding a plugin, start from `front/plugins/__template`, implement with `plugin_helper`, define manifest settings, and wire phase via `<PREF>_RUN`. Verify logs in `/app/log/plugins/` and data in `api/*.json`.
|
||||
- When adding a plugin, start from `front/plugins/__template`, implement with `plugin_helper`, define manifest settings, and wire phase via `<PREF>_RUN`. Verify logs in `/tmp/log/plugins/` and data in `api/*.json`.
|
||||
- When introducing new config, define it once (core `ccd()` or plugin manifest) and read it via helpers everywhere.
|
||||
- When exposing new server functionality, add endpoints in `server/api_server/*` and keep authorization consistent; update UI by reading/writing JSON cache rather than bypassing the pipeline.
|
||||
|
||||
## Useful references
|
||||
- Docs: `docs/PLUGINS_DEV.md`, `docs/SETTINGS_SYSTEM.md`, `docs/API_*.md`, `docs/DEBUG_*.md`
|
||||
- Logs: backend `/app/log/app.log`, plugin logs under `/app/log/plugins/`, nginx/php logs under `/var/log/*`
|
||||
- Logs: All logs are under `/tmp/log/`. Plugin logs are very shortly under `/tmp/log/plugins/` until picked up by the server.
|
||||
- plugin logs: `/tmp/log/app.log`
|
||||
- backend logs: `/tmp/log/stdout.log` and `/tmp/log/stderr.log`
|
||||
- frontend commands logs: `/tmp/log/app_front.log`
|
||||
- php errors: `/tmp/log/app.php_errors.log`
|
||||
- nginx logs: `/tmp/log/nginx-access.log` and `/tmp/log/nginx-error.log`
|
||||
|
||||
## Assistant expectations:
|
||||
- Be concise, opinionated, and biased toward security and simplicity.
|
||||
|
||||
21
.github/workflows/docker_dev.yml
vendored
21
.github/workflows/docker_dev.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
branches:
|
||||
- next_release
|
||||
|
||||
jobs:
|
||||
jobs:
|
||||
docker_dev:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
@@ -19,7 +19,8 @@ jobs:
|
||||
packages: write
|
||||
if: >
|
||||
contains(github.event.head_commit.message, 'PUSHPROD') != 'True' &&
|
||||
github.repository == 'jokob-sk/NetAlertX'
|
||||
github.repository == 'jokob-sk/NetAlertX'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -30,26 +31,36 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
# --- Generate timestamped dev version
|
||||
- name: Generate timestamp version
|
||||
id: timestamp
|
||||
run: |
|
||||
ts=$(date -u +'%Y%m%d-%H%M%S')
|
||||
echo "version=dev-${ts}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: dev-${ts}"
|
||||
|
||||
- name: Set up dynamic build ARGs
|
||||
id: getargs
|
||||
id: getargs
|
||||
run: echo "version=$(cat ./stable/VERSION)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get release version
|
||||
id: get_version
|
||||
run: echo "version=Dev" >> $GITHUB_OUTPUT
|
||||
|
||||
# --- Write the timestamped version to .VERSION file
|
||||
- name: Create .VERSION file
|
||||
run: echo "${{ steps.get_version.outputs.version }}" >> .VERSION
|
||||
run: echo "${{ steps.timestamp.outputs.version }}" > .VERSION
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/jokob-sk/netalertx-dev
|
||||
jokobsk/netalertx-dev
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=raw,value=${{ steps.timestamp.outputs.version }}
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
|
||||
31
.github/workflows/docker_prod.yml
vendored
31
.github/workflows/docker_prod.yml
vendored
@@ -6,7 +6,6 @@
|
||||
# GitHub recommends pinning actions to a commit SHA.
|
||||
# To get a newer version, you will need to update the SHA.
|
||||
# You can also reference a tag or branch, but the action may change without warning.
|
||||
|
||||
name: Publish Docker image
|
||||
|
||||
on:
|
||||
@@ -14,6 +13,7 @@ on:
|
||||
types: [published]
|
||||
tags:
|
||||
- '*.[1-9]+[0-9]?.[1-9]+*'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -21,6 +21,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -31,42 +32,39 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Set up dynamic build ARGs
|
||||
id: getargs
|
||||
run: echo "version=$(cat ./stable/VERSION)" >> $GITHUB_OUTPUT
|
||||
|
||||
# --- Get release version from tag
|
||||
- name: Get release version
|
||||
id: get_version
|
||||
run: echo "::set-output name=version::${GITHUB_REF#refs/tags/}"
|
||||
run: echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||
|
||||
# --- Write version to .VERSION file
|
||||
- name: Create .VERSION file
|
||||
run: echo "${{ steps.get_version.outputs.version }}" >> .VERSION
|
||||
run: echo "${{ steps.get_version.outputs.version }}" > .VERSION
|
||||
|
||||
# --- Generate Docker metadata and tags
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
# list of Docker images to use as base name for tags
|
||||
images: |
|
||||
ghcr.io/jokob-sk/netalertx
|
||||
jokobsk/netalertx
|
||||
# generate Docker tags based on the following events/attributes
|
||||
jokobsk/netalertx
|
||||
tags: |
|
||||
type=semver,pattern={{version}},value=${{ inputs.version }}
|
||||
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.version }}
|
||||
type=semver,pattern={{major}},value=${{ inputs.version }}
|
||||
type=semver,pattern={{version}},value=${{ steps.get_version.outputs.version }}
|
||||
type=semver,pattern={{major}}.{{minor}},value=${{ steps.get_version.outputs.version }}
|
||||
type=semver,pattern={{major}},value=${{ steps.get_version.outputs.version }}
|
||||
type=ref,event=branch,suffix=-{{ sha }}
|
||||
type=ref,event=pr
|
||||
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }}
|
||||
|
||||
- name: Log in to Github Container registry
|
||||
- name: Log in to Github Container Registry (GHCR)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: jokob-sk
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
- name: Log in to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
@@ -81,6 +79,5 @@ jobs:
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
# # ⚠ disable cache if build is failing to download debian packages
|
||||
# cache-from: type=registry,ref=ghcr.io/jokob-sk/netalertx:buildcache
|
||||
# cache-to: type=registry,ref=ghcr.io/jokob-sk/netalertx:buildcache,mode=max
|
||||
|
||||
2
.github/workflows/docker_rewrite.yml
vendored
2
.github/workflows/docker_rewrite.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/jokob-sk/netalertx-dev-rewrite
|
||||
|
||||
37
.gitignore
vendored
37
.gitignore
vendored
@@ -5,13 +5,12 @@
|
||||
.gitconfig
|
||||
.*CommandMarker
|
||||
deviceid
|
||||
.VERSION
|
||||
|
||||
# Sensitive data
|
||||
.DS_Store
|
||||
.cache
|
||||
nohup.out
|
||||
config/*
|
||||
.ash_history
|
||||
.VERSION
|
||||
config/pialert.conf
|
||||
config/app.conf
|
||||
db/*
|
||||
@@ -24,35 +23,23 @@ front/api/*
|
||||
/api/*
|
||||
**/plugins/**/*.log
|
||||
**/plugins/cloud_services/*
|
||||
**/%40eaDir/
|
||||
**/@eaDir/
|
||||
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
**/last_result.log
|
||||
**/script.log
|
||||
**/pialert.conf_bak
|
||||
**/pialert.db_bak
|
||||
.*.swp
|
||||
|
||||
# future stuff
|
||||
front/img/cloud_services/*
|
||||
**/cloud_services.php
|
||||
**/cloud_services.js
|
||||
front/css/cloud_services.css
|
||||
|
||||
# OS junk
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
**/%40eaDir/
|
||||
**/@eaDir/
|
||||
*/%40eaDir/
|
||||
*/@eaDir/
|
||||
.DS_Store
|
||||
.*.swp
|
||||
|
||||
# Python junk
|
||||
venv/
|
||||
.env/
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# Build artifacts (if you ever package anything)
|
||||
dist/
|
||||
build/
|
||||
docker-compose.yml.ffsb42
|
||||
.env.omada.ffsb42
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import sys, importlib
|
||||
mods = [
|
||||
'json', 'simplejson',
|
||||
'httplib', 'http.client',
|
||||
'urllib2', 'urllib.request',
|
||||
'Queue', 'queue',
|
||||
'cStringIO', 'StringIO', 'io',
|
||||
'md5', 'hashlib',
|
||||
'ssl'
|
||||
]
|
||||
print('PYTHON_EXE:' + sys.executable)
|
||||
print('PYTHON_VER:' + sys.version.replace('\n', ' '))
|
||||
for m in mods:
|
||||
try:
|
||||
mod = importlib.import_module(m)
|
||||
ver = getattr(mod, '__version__', None)
|
||||
if ver is None:
|
||||
# try common attributes
|
||||
ver = getattr(mod, 'version', None)
|
||||
info = (' version=' + str(ver)) if ver is not None else ''
|
||||
print('OK %s%s' % (m, info))
|
||||
except Exception as e:
|
||||
print('MISSING %s %s: %s' % (m, e.__class__.__name__, e))
|
||||
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@@ -29,6 +29,14 @@
|
||||
"pathMappings": {
|
||||
"/app": "${workspaceFolder}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Python: Current File",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
}
|
||||
18
.vscode/settings.json
vendored
18
.vscode/settings.json
vendored
@@ -11,13 +11,23 @@
|
||||
// Let the Python extension invoke pytest via the interpreter; avoid hardcoded paths
|
||||
// Removed python.testing.pytestPath and legacy pytest.command overrides
|
||||
|
||||
"terminal.integrated.defaultProfile.linux": "fish",
|
||||
"terminal.integrated.defaultProfile.linux": "zsh",
|
||||
"terminal.integrated.profiles.linux": {
|
||||
"fish": {
|
||||
"path": "/usr/bin/fish"
|
||||
"zsh": {
|
||||
"path": "/bin/zsh"
|
||||
}
|
||||
}
|
||||
,
|
||||
// Fallback for older VS Code versions or schema validators that don't accept custom profiles
|
||||
"terminal.integrated.shell.linux": "/usr/bin/fish"
|
||||
"terminal.integrated.shell.linux": "/usr/bin/zsh"
|
||||
,
|
||||
"python.linting.flake8Enabled": true,
|
||||
"python.linting.enabled": true,
|
||||
"python.linting.flake8Args": [
|
||||
"--config=.flake8"
|
||||
],
|
||||
"python.formatting.provider": "black",
|
||||
"python.formatting.blackArgs": [
|
||||
"--line-length=180"
|
||||
]
|
||||
}
|
||||
93
.vscode/tasks.json
vendored
93
.vscode/tasks.json
vendored
@@ -1,16 +1,27 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"inputs": [
|
||||
{
|
||||
"id": "confirmPrune",
|
||||
"type": "promptString",
|
||||
"description": "DANGER! Type YES to confirm pruning all unused Docker resources. This will destroy containers, images, volumes, and networks!",
|
||||
"default": ""
|
||||
}
|
||||
],
|
||||
"tasks": [
|
||||
{
|
||||
"label": "[Any POSIX] Generate Devcontainer Configs",
|
||||
"type": "shell",
|
||||
"command": ".devcontainer/scripts/generate-configs.sh",
|
||||
"detail": "Generates devcontainer configs from the template. This must be run after changes to devcontainer to combine/merge them into the final config used by VS Code. Note- this has no bearing on the production or test image.",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false
|
||||
"showReuseMessage": false,
|
||||
"group": "POSIX Tasks"
|
||||
},
|
||||
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
@@ -24,12 +35,19 @@
|
||||
{
|
||||
"label": "[Any] Docker system and build Prune",
|
||||
"type": "shell",
|
||||
"command": ".devcontainer/scripts/confirm-docker-prune.sh",
|
||||
"command": ".devcontainer/scripts/confirm-docker-prune.sh",
|
||||
"detail": "DANGER! Prunes all unused Docker resources (images, containers, volumes, networks). Any stopped container will be wiped and data will be lost. Use with caution.",
|
||||
"options": {
|
||||
"env": {
|
||||
"CONFIRM_PRUNE": "${input:confirmPrune}"
|
||||
}
|
||||
},
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false
|
||||
"showReuseMessage": false,
|
||||
"group": "Any"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
@@ -45,6 +63,7 @@
|
||||
"label": "[Dev Container] Re-Run Startup Script",
|
||||
"type": "shell",
|
||||
"command": "./isDevContainer.sh || exit 1;/workspaces/NetAlertX/.devcontainer/scripts/setup.sh",
|
||||
"detail": "The startup script runs directly after the container is started. It reprovisions permissions, links folders, and performs other setup tasks. Run this if you have made changes to the setup script or need to reprovision the container.",
|
||||
"options": {
|
||||
"cwd": "/workspaces/NetAlertX/.devcontainer/scripts"
|
||||
},
|
||||
@@ -65,6 +84,7 @@
|
||||
"label": "[Dev Container] Start Backend (Python)",
|
||||
"type": "shell",
|
||||
"command": "./isDevContainer.sh || exit 1; /services/start-backend.sh",
|
||||
"detail": "Restarts the NetAlertX backend (Python) service in the dev container. This may take 5 seconds to be completely ready.",
|
||||
"options": {
|
||||
"cwd": "/workspaces/NetAlertX/.devcontainer/scripts"
|
||||
},
|
||||
@@ -73,7 +93,8 @@
|
||||
"reveal": "always",
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false,
|
||||
"clear": false
|
||||
"clear": false,
|
||||
"group": "Devcontainer"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"icon": {
|
||||
@@ -85,6 +106,7 @@
|
||||
"label": "[Dev Container] Start CronD (Scheduler)",
|
||||
"type": "shell",
|
||||
"command": "./isDevContainer.sh || exit 1; /services/start-crond.sh",
|
||||
"detail": "Stops and restarts the crond service.",
|
||||
"options": {
|
||||
"cwd": "/workspaces/NetAlertX/.devcontainer/scripts"
|
||||
},
|
||||
@@ -93,7 +115,8 @@
|
||||
"reveal": "always",
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false,
|
||||
"clear": false
|
||||
"clear": false,
|
||||
"group": "Devcontainer"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"icon": {
|
||||
@@ -105,6 +128,7 @@
|
||||
"label": "[Dev Container] Start Frontend (nginx and PHP-FPM)",
|
||||
"type": "shell",
|
||||
"command": "./isDevContainer.sh || exit 1; /services/start-php-fpm.sh & /services/start-nginx.sh &",
|
||||
"detail": "Stops and restarts the NetAlertX frontend services (nginx and PHP-FPM) in the dev container. This launches almost instantly.",
|
||||
"options": {
|
||||
"cwd": "/workspaces/NetAlertX/.devcontainer/scripts"
|
||||
|
||||
@@ -114,7 +138,8 @@
|
||||
"reveal": "always",
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false,
|
||||
"clear": false
|
||||
"clear": false,
|
||||
"group": "Devcontainer"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"icon": {
|
||||
@@ -126,6 +151,7 @@
|
||||
"label": "[Dev Container] Stop Frontend & Backend Services",
|
||||
"type": "shell",
|
||||
"command": "./isDevContainer.sh || exit 1; pkill -f 'php-fpm83|nginx|crond|python3' || true",
|
||||
"detail": "Stops all NetAlertX services running in the dev container.",
|
||||
"options": {
|
||||
"cwd": "/workspaces/NetAlertX/.devcontainer/scripts"
|
||||
},
|
||||
@@ -133,7 +159,8 @@
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false
|
||||
"showReuseMessage": false,
|
||||
"group": "Devcontainer"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"icon": {
|
||||
@@ -142,29 +169,55 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "[Dev Container] List NetAlertX Ports",
|
||||
"label": "[Any] Build Unit Test Docker image",
|
||||
"type": "shell",
|
||||
"command": "list-ports.sh",
|
||||
"options": {
|
||||
"cwd": "/workspaces/NetAlertX/.devcontainer/scripts"
|
||||
},
|
||||
"command": "docker buildx build -t netalertx-test . && echo '🧪 Unit Test Docker image built: netalertx-test'",
|
||||
"detail": "This must be run after changes to the container. Unit testing will not register changes until after this image is rebuilt. It takes about 30 seconds to build unless changes to the venv stage are made. venv takes 90s alone.",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false
|
||||
"showReuseMessage": false,
|
||||
"group": "Any"
|
||||
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"icon": {
|
||||
"id": "beaker",
|
||||
"color": "terminal.ansiBlue"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "[Dev Container] Wipe and Regenerate Database",
|
||||
"type": "shell",
|
||||
"command": "killall 'python3' || true && sleep 1 && rm -rf /data/db/* /data/config/* && bash /entrypoint.d/15-first-run-config.sh && bash /entrypoint.d/20-first-run-db.sh && echo '✅ Database and config wiped and regenerated'",
|
||||
"detail": "Wipes devcontainer db and config. Provides a fresh start in devcontainer, run this task, then run the Rerun Startup Task",
|
||||
"options": {},
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false,
|
||||
"group": "Devcontainer"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"icon": {
|
||||
"id": "output",
|
||||
"color": "terminal.ansiBlue"
|
||||
"id": "database",
|
||||
"color": "terminal.ansiRed"
|
||||
}
|
||||
}
|
||||
,
|
||||
},
|
||||
{
|
||||
"label": "[Any] Build Unit Test Docker image",
|
||||
"label": "Build & Launch Prodcution Docker Container",
|
||||
"type": "shell",
|
||||
"command": "docker buildx build -t netalertx-test . && echo '🧪 Unit Test Docker image built: netalertx-test'",
|
||||
"command": "docker compose up -d --build --force-recreate",
|
||||
"detail": "Before launching, ensure VSCode Ports are closed and services are stopped. Tasks: Stop Frontend & Backend Services & Remote: Close Unused Forwarded Ports to ensure proper operation of the new container.",
|
||||
"options": {
|
||||
"cwd": "/workspaces/NetAlertX"
|
||||
},
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
@@ -177,7 +230,7 @@
|
||||
"isDefault": false
|
||||
},
|
||||
"icon": {
|
||||
"id": "beaker",
|
||||
"id": "package",
|
||||
"color": "terminal.ansiBlue"
|
||||
}
|
||||
}
|
||||
|
||||
38
Dockerfile
38
Dockerfile
@@ -43,14 +43,16 @@ ARG INSTALL_DIR=/app
|
||||
|
||||
# NetAlertX app directories
|
||||
ENV NETALERTX_APP=${INSTALL_DIR}
|
||||
ENV NETALERTX_CONFIG=${NETALERTX_APP}/config
|
||||
ENV NETALERTX_DATA=/data
|
||||
ENV NETALERTX_CONFIG=${NETALERTX_DATA}/config
|
||||
ENV NETALERTX_FRONT=${NETALERTX_APP}/front
|
||||
ENV NETALERTX_PLUGINS=${NETALERTX_FRONT}/plugins
|
||||
ENV NETALERTX_SERVER=${NETALERTX_APP}/server
|
||||
ENV NETALERTX_API=${NETALERTX_APP}/api
|
||||
ENV NETALERTX_DB=${NETALERTX_APP}/db
|
||||
ENV NETALERTX_API=/tmp/api
|
||||
ENV NETALERTX_DB=${NETALERTX_DATA}/db
|
||||
ENV NETALERTX_DB_FILE=${NETALERTX_DB}/app.db
|
||||
ENV NETALERTX_BACK=${NETALERTX_APP}/back
|
||||
ENV NETALERTX_LOG=${NETALERTX_APP}/log
|
||||
ENV NETALERTX_LOG=/tmp/log
|
||||
ENV NETALERTX_PLUGINS_LOG=${NETALERTX_LOG}/plugins
|
||||
ENV NETALERTX_CONFIG_FILE=${NETALERTX_CONFIG}/app.conf
|
||||
|
||||
@@ -67,31 +69,35 @@ ENV LOG_EXECUTION_QUEUE=${NETALERTX_LOG}/execution_queue.log
|
||||
ENV LOG_REPORT_OUTPUT_JSON=${NETALERTX_LOG}/report_output.json
|
||||
ENV LOG_STDOUT=${NETALERTX_LOG}/stdout.log
|
||||
ENV LOG_CROND=${NETALERTX_LOG}/crond.log
|
||||
ENV LOG_NGINX_ERROR=${NETALERTX_LOG}/nginx-error.log
|
||||
|
||||
# System Services configuration files
|
||||
ENV ENTRYPOINT_CHECKS=/entrypoint.d
|
||||
ENV SYSTEM_SERVICES=/services
|
||||
ENV SYSTEM_SERVICES_SCRIPTS=${SYSTEM_SERVICES}/scripts
|
||||
ENV SYSTEM_SERVICES_CONFIG=${SYSTEM_SERVICES}/config
|
||||
ENV SYSTEM_NGINX_CONFIG=${SYSTEM_SERVICES_CONFIG}/nginx
|
||||
ENV SYSTEM_NGINX_CONFIG_FILE=${SYSTEM_NGINX_CONFIG}/nginx.conf
|
||||
ENV SYSTEM_SERVICES_ACTIVE_CONFIG=/tmp/nginx/active-config
|
||||
ENV SYSTEM_SERVICES_PHP_FOLDER=${SYSTEM_SERVICES_CONFIG}/php
|
||||
ENV SYSTEM_SERVICES_PHP_FPM_D=${SYSTEM_SERVICES_PHP_FOLDER}/php-fpm.d
|
||||
ENV SYSTEM_SERVICES_CROND=${SYSTEM_SERVICES_CONFIG}/crond
|
||||
ENV SYSTEM_SERVICES_RUN=${SYSTEM_SERVICES}/run
|
||||
ENV SYSTEM_SERVICES_RUN=/tmp/run
|
||||
ENV SYSTEM_SERVICES_RUN_TMP=${SYSTEM_SERVICES_RUN}/tmp
|
||||
ENV SYSTEM_SERVICES_RUN_LOG=${SYSTEM_SERVICES_RUN}/logs
|
||||
ENV PHP_FPM_CONFIG_FILE=${SYSTEM_SERVICES_PHP_FOLDER}/php-fpm.conf
|
||||
ENV READ_ONLY_FOLDERS="${NETALERTX_BACK} ${NETALERTX_FRONT} ${NETALERTX_SERVER} ${SYSTEM_SERVICES} \
|
||||
${SYSTEM_SERVICES_CONFIG}"
|
||||
ENV READ_WRITE_FOLDERS="${NETALERTX_CONFIG} ${NETALERTX_DB} ${NETALERTX_API} ${NETALERTX_LOG} \
|
||||
${NETALERTX_PLUGINS_LOG} ${SYSTEM_SERVICES_RUN} ${SYSTEM_SERVICES_RUN_TMP} \
|
||||
${SYSTEM_SERVICES_RUN_LOG}"
|
||||
${SYSTEM_SERVICES_CONFIG} ${ENTRYPOINT_CHECKS}"
|
||||
ENV READ_WRITE_FOLDERS="${NETALERTX_DATA} ${NETALERTX_CONFIG} ${NETALERTX_DB} ${NETALERTX_API} \
|
||||
${NETALERTX_LOG} ${NETALERTX_PLUGINS_LOG} ${SYSTEM_SERVICES_RUN} \
|
||||
${SYSTEM_SERVICES_RUN_TMP} ${SYSTEM_SERVICES_RUN_LOG} \
|
||||
${SYSTEM_SERVICES_ACTIVE_CONFIG}"
|
||||
|
||||
#Python environment
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV VIRTUAL_ENV=/opt/venv
|
||||
ENV VIRTUAL_ENV_BIN=/opt/venv/bin
|
||||
ENV PYTHONPATH=${NETALERTX_APP}:${NETALERTX_SERVER}:${VIRTUAL_ENV}/lib/python3.12/site-packages
|
||||
ENV PYTHONPATH=${NETALERTX_APP}:${NETALERTX_SERVER}:${NETALERTX_PLUGINS}:${VIRTUAL_ENV}/lib/python3.12/site-packages
|
||||
ENV PATH="${SYSTEM_SERVICES}:${VIRTUAL_ENV_BIN}:$PATH"
|
||||
|
||||
# App Environment
|
||||
@@ -99,7 +105,7 @@ ENV LISTEN_ADDR=0.0.0.0
|
||||
ENV PORT=20211
|
||||
ENV NETALERTX_DEBUG=0
|
||||
ENV VENDORSPATH=/app/back/ieee-oui.txt
|
||||
ENV VENDORSPATH_NEWEST=/services/run/tmp/ieee-oui.txt
|
||||
ENV VENDORSPATH_NEWEST=${SYSTEM_SERVICES_RUN_TMP}/ieee-oui.txt
|
||||
ENV ENVIRONMENT=alpine
|
||||
ENV READ_ONLY_USER=readonly READ_ONLY_GROUP=readonly
|
||||
ENV NETALERTX_USER=netalertx NETALERTX_GROUP=netalertx
|
||||
@@ -123,11 +129,15 @@ COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} install/production-filesystem/
|
||||
COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} --chmod=755 back ${NETALERTX_BACK}
|
||||
COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} --chmod=755 front ${NETALERTX_FRONT}
|
||||
COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} --chmod=755 server ${NETALERTX_SERVER}
|
||||
RUN install -d -o ${NETALERTX_USER} -g ${NETALERTX_GROUP} -m 755 ${NETALERTX_API} \
|
||||
${NETALERTX_LOG} ${SYSTEM_SERVICES_RUN_TMP} ${SYSTEM_SERVICES_RUN_LOG} && \
|
||||
|
||||
# Create required folders with correct ownership and permissions
|
||||
RUN install -d -o ${NETALERTX_USER} -g ${NETALERTX_GROUP} -m 700 ${READ_WRITE_FOLDERS} && \
|
||||
sh -c "find ${NETALERTX_APP} -type f \( -name '*.sh' -o -name 'speedtest-cli' \) \
|
||||
-exec chmod 750 {} \;"
|
||||
|
||||
# Copy version information into the image
|
||||
COPY --chown=${NETALERTX_USER}:${NETALERTX_GROUP} .VERSION ${NETALERTX_APP}/.VERSION
|
||||
|
||||
# Copy the virtualenv from the builder stage
|
||||
COPY --from=builder --chown=20212:20212 ${VIRTUAL_ENV} ${VIRTUAL_ENV}
|
||||
|
||||
@@ -181,7 +191,7 @@ RUN chown -R ${READ_ONLY_USER}:${READ_ONLY_GROUP} ${READ_ONLY_FOLDERS} && \
|
||||
chmod -R 600 ${READ_WRITE_FOLDERS} && \
|
||||
find ${READ_WRITE_FOLDERS} -type d -exec chmod 700 {} + && \
|
||||
chown ${READ_ONLY_USER}:${READ_ONLY_GROUP} /entrypoint.sh /opt /opt/venv && \
|
||||
chmod 005 /entrypoint.sh ${SYSTEM_SERVICES}/*.sh /app /opt /opt/venv && \
|
||||
chmod 005 /entrypoint.sh ${SYSTEM_SERVICES}/*.sh ${SYSTEM_SERVICES_SCRIPTS}/* ${ENTRYPOINT_CHECKS}/* /app /opt /opt/venv && \
|
||||
for dir in ${READ_WRITE_FOLDERS}; do \
|
||||
install -d -o ${NETALERTX_USER} -g ${NETALERTX_GROUP} -m 700 "$dir"; \
|
||||
done && \
|
||||
|
||||
@@ -49,14 +49,15 @@ FROM debian:bookworm-slim
|
||||
# NetAlertX app directories
|
||||
ENV INSTALL_DIR=/app
|
||||
ENV NETALERTX_APP=${INSTALL_DIR}
|
||||
ENV NETALERTX_CONFIG=${NETALERTX_APP}/config
|
||||
ENV NETALERTX_DATA=/data
|
||||
ENV NETALERTX_CONFIG=${NETALERTX_DATA}/config
|
||||
ENV NETALERTX_FRONT=${NETALERTX_APP}/front
|
||||
ENV NETALERTX_SERVER=${NETALERTX_APP}/server
|
||||
ENV NETALERTX_API=${NETALERTX_APP}/api
|
||||
ENV NETALERTX_DB=${NETALERTX_APP}/db
|
||||
ENV NETALERTX_API=/tmp/api
|
||||
ENV NETALERTX_DB=${NETALERTX_DATA}/db
|
||||
ENV NETALERTX_DB_FILE=${NETALERTX_DB}/app.db
|
||||
ENV NETALERTX_BACK=${NETALERTX_APP}/back
|
||||
ENV NETALERTX_LOG=${NETALERTX_APP}/log
|
||||
ENV NETALERTX_LOG=/tmp/log
|
||||
ENV NETALERTX_PLUGINS_LOG=${NETALERTX_LOG}/plugins
|
||||
|
||||
# NetAlertX log files
|
||||
@@ -72,17 +73,19 @@ ENV LOG_EXECUTION_QUEUE=${NETALERTX_LOG}/execution_queue.log
|
||||
ENV LOG_REPORT_OUTPUT_JSON=${NETALERTX_LOG}/report_output.json
|
||||
ENV LOG_STDOUT=${NETALERTX_LOG}/stdout.log
|
||||
ENV LOG_CROND=${NETALERTX_LOG}/crond.log
|
||||
ENV LOG_NGINX_ERROR=${NETALERTX_LOG}/nginx-error.log
|
||||
|
||||
# System Services configuration files
|
||||
ENV SYSTEM_SERVICES=/services
|
||||
ENV SYSTEM_SERVICES_CONFIG=${SYSTEM_SERVICES}/config
|
||||
ENV SYSTEM_NGINIX_CONFIG=${SYSTEM_SERVICES_CONFIG}/nginx
|
||||
ENV SYSTEM_NGINX_CONFIG_FILE=${SYSTEM_NGINIX_CONFIG}/nginx.conf
|
||||
ENV SYSTEM_SERVICES_ACTIVE_CONFIG=/tmp/nginx/active-config
|
||||
ENV NETALERTX_CONFIG_FILE=${NETALERTX_CONFIG}/app.conf
|
||||
ENV SYSTEM_SERVICES_PHP_FOLDER=${SYSTEM_SERVICES_CONFIG}/php
|
||||
ENV SYSTEM_SERVICES_PHP_FPM_D=${SYSTEM_SERVICES_PHP_FOLDER}/php-fpm.d
|
||||
ENV SYSTEM_SERVICES_CROND=${SYSTEM_SERVICES_CONFIG}/crond
|
||||
ENV SYSTEM_SERVICES_RUN=${SYSTEM_SERVICES}/run
|
||||
ENV SYSTEM_SERVICES_RUN=/tmp/run
|
||||
ENV SYSTEM_SERVICES_RUN_TMP=${SYSTEM_SERVICES_RUN}/tmp
|
||||
ENV SYSTEM_SERVICES_RUN_LOG=${SYSTEM_SERVICES_RUN}/logs
|
||||
ENV PHP_FPM_CONFIG_FILE=${SYSTEM_SERVICES_PHP_FOLDER}/php-fpm.conf
|
||||
@@ -94,7 +97,7 @@ ENV VIRTUAL_ENV=/opt/venv
|
||||
ENV VIRTUAL_ENV_BIN=/opt/venv/bin
|
||||
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}:/services"
|
||||
ENV VENDORSPATH=/app/back/ieee-oui.txt
|
||||
ENV VENDORSPATH_NEWEST=/services/run/tmp/ieee-oui.txt
|
||||
ENV VENDORSPATH_NEWEST=${SYSTEM_SERVICES_RUN_TMP}/ieee-oui.txt
|
||||
|
||||
|
||||
# App Environment
|
||||
|
||||
16
README.md
16
README.md
@@ -6,7 +6,7 @@
|
||||
|
||||
# NetAlertX - Network, presence scanner and alert framework
|
||||
|
||||
Get visibility of what's going on on your WIFI/LAN network and enable presence detection of important devices. Schedule scans for devices, port changes and get alerts if unknown devices or changes are found. Write your own [Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md#readme) with auto-generated UI and in-build notification system. Build out and easily maintain your network source of truth (NSoT).
|
||||
Get visibility of what's going on on your WIFI/LAN network and enable presence detection of important devices. Schedule scans for devices, port changes and get alerts if unknown devices or changes are found. Write your own [Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/docs/PLUGINS.md#readme) with auto-generated UI and in-build notification system. Build out and easily maintain your network source of truth (NSoT) and device inventory.
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
@@ -33,13 +33,13 @@ Get visibility of what's going on on your WIFI/LAN network and enable presence d
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
To launch NetAlertX in seconds, replace `local_path` with the absolute path on your system that contains your `config` and `db` folders, then run::
|
||||
Start NetAlertX in seconds with Docker:
|
||||
|
||||
```bash
|
||||
docker run -d --rm --network=host \
|
||||
-v local_path/config:/app/config \
|
||||
-v local_path/db:/app/db \
|
||||
--mount type=tmpfs,target=/app/api \
|
||||
-v local_path/config:/data/config \
|
||||
-v local_path/db:/data/db \
|
||||
--mount type=tmpfs,target=/tmp/api \
|
||||
-e PUID=200 -e PGID=300 \
|
||||
-e TZ=Europe/Berlin \
|
||||
-e PORT=20211 \
|
||||
@@ -61,7 +61,7 @@ For Home Assistant users: [Click here to add NetAlertX](https://my.home-assistan
|
||||
For other install methods, check the [installation docs](#-documentation)
|
||||
|
||||
|
||||
| [📑 Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://jokob-sk.github.io/NetAlertX/) | [🔌 Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md) | [🤖 Ask AI](https://gurubase.io/g/netalertx)
|
||||
| [📑 Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_INSTALLATION.md) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://jokob-sk.github.io/NetAlertX/) | [🔌 Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md) | [🤖 Ask AI](https://gurubase.io/g/netalertx)
|
||||
|----------------------| ----------------------| ----------------------| ----------------------| ----------------------|
|
||||
|
||||
![showcase][showcase]
|
||||
@@ -103,7 +103,7 @@ The [workflows module](https://github.com/jokob-sk/NetAlertX/blob/main/docs/WORK
|
||||
|
||||
Supported browsers: Chrome, Firefox
|
||||
|
||||
- [[Installation] Docker](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md)
|
||||
- [[Installation] Docker](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_INSTALLATION.md)
|
||||
- [[Installation] Home Assistant](https://github.com/alexbelgium/hassio-addons/tree/master/netalertx)
|
||||
- [[Installation] Bare metal](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md)
|
||||
- [[Installation] Unraid App](https://unraid.net/community/apps)
|
||||
@@ -140,7 +140,7 @@ A: No. All scans and data remain local, unless you set up cloud-based notificati
|
||||
A: Yes! You can install it bare-metal. See the [bare metal installation guide](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md).
|
||||
|
||||
**Q: Where is the data stored?**
|
||||
A: In the `/config` and `/db` folders, mapped in Docker. Back up these folders regularly.
|
||||
A: In the `/data/config` and `/data/db` folders. Back up these folders regularly.
|
||||
|
||||
|
||||
## 🐞 Known Issues
|
||||
|
||||
2
db/.gitignore
vendored
2
db/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -17,53 +17,38 @@ services:
|
||||
|
||||
volumes:
|
||||
|
||||
- type: volume # Persistent Docker-managed Named Volume for storage of config files
|
||||
source: netalertx_config # the default name of the volume is netalertx_config
|
||||
target: /app/config # inside the container mounted to /app/config
|
||||
- type: volume # Persistent Docker-managed Named Volume for storage
|
||||
source: netalertx_data # the default name of the volume is netalertx_data
|
||||
target: /data # consolidated configuration and database storage
|
||||
read_only: false # writable volume
|
||||
|
||||
# Example custom local folder called /home/user/netalertx_config
|
||||
# Example custom local folder called /home/user/netalertx_data
|
||||
# - type: bind
|
||||
# source: /home/user/netalertx_config
|
||||
# target: /app/config
|
||||
# source: /home/user/netalertx_data
|
||||
# target: /data
|
||||
# read_only: false
|
||||
# ... or use the alternative format
|
||||
# - /home/user/netalertx_config:/app/config:rw
|
||||
|
||||
- type: volume
|
||||
source: netalertx_db
|
||||
target: /app/db
|
||||
read_only: false
|
||||
# - /home/user/netalertx_data:/data:rw
|
||||
|
||||
- type: bind # Bind mount for timezone consistency
|
||||
source: /etc/localtime
|
||||
target: /etc/localtime
|
||||
read_only: true
|
||||
|
||||
# Use a custom Enterprise-configured nginx config for ldap or other settings
|
||||
# - /custom-enterprise.conf:/services/config/nginx/conf.active/netalertx.conf:ro
|
||||
# Use a custom Enterprise-configured nginx config for ldap or other settings
|
||||
# - /custom-enterprise.conf:/tmp/nginx/active-config/netalertx.conf:ro
|
||||
|
||||
# Test your plugin on the production container
|
||||
# - /path/on/host:/app/front/plugins/custom
|
||||
|
||||
# Retain logs - comment out tmpfs /app/log if you want to retain logs between container restarts
|
||||
# - /path/on/host/log:/app/log
|
||||
# Retain logs - comment out tmpfs /tmp/log if you want to retain logs between container restarts
|
||||
# - /path/on/host/log:/tmp/log
|
||||
|
||||
# Tempfs mounts for writable directories in a read-only container and improve system performance
|
||||
# All mounts have noexec,nosuid,nodev for security purposes no devices, no suid/sgid and no execution of binaries
|
||||
# async where possible for performance, sync where required for correctness
|
||||
# tmpfs mounts for writable directories in a read-only container and improve system performance
|
||||
# All writes now live under /tmp/* subdirectories which are created dynamically by entrypoint.d scripts
|
||||
# uid=20211 and gid=20211 is the netalertx user inside the container
|
||||
# mode=1700 gives rwx------ permissions to the netalertx user only
|
||||
tmpfs:
|
||||
# Speed up logging. This can be commented out to retain logs between container restarts
|
||||
- "/app/log:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# Speed up API access as frontend/backend API is very chatty
|
||||
- "/app/api:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,sync,noatime,nodiratime"
|
||||
# Required for customization of the nginx listen addr/port without rebuilding the container
|
||||
- "/services/config/nginx/conf.active:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# /services/config/nginx/conf.d is required for nginx and php to start
|
||||
- "/services/run:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# /tmp is required by php for session save this should be reworked to /services/run/tmp
|
||||
- "/tmp:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
environment:
|
||||
LISTEN_ADDR: ${LISTEN_ADDR:-0.0.0.0} # Listen for connections on all interfaces
|
||||
@@ -86,6 +71,5 @@ services:
|
||||
# Always restart the container unless explicitly stopped
|
||||
restart: unless-stopped
|
||||
|
||||
volumes: # Persistent volumes for configuration and database storage
|
||||
netalertx_config: # Configuration files
|
||||
netalertx_db: # Database files
|
||||
volumes: # Persistent volume for configuration and database storage
|
||||
netalertx_data:
|
||||
|
||||
@@ -64,8 +64,9 @@ http://<server>:<GRAPHQL_PORT>/
|
||||
* [Metrics](API_METRICS.md) – Prometheus metrics and per-device status
|
||||
* [Network Tools](API_NETTOOLS.md) – Utilities like Wake-on-LAN, traceroute, nslookup, nmap, and internet info
|
||||
* [Online History](API_ONLINEHISTORY.md) – Online/offline device records
|
||||
* [GraphQL](API_GRAPHQL.md) – Advanced queries and filtering
|
||||
* [GraphQL](API_GRAPHQL.md) – Advanced queries and filtering for Devices, Settings and Language Strings
|
||||
* [Sync](API_SYNC.md) – Synchronization between multiple NetAlertX instances
|
||||
* [Logs](API_LOGS.md) – Purging of logs and adding to the event execution queue for user triggered events
|
||||
* [DB query](API_DBQUERY.md) (⚠ Internal) - Low level database access - use other endpoints if possible
|
||||
|
||||
See [Testing](API_TESTS.md) for example requests and usage.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# GraphQL API Endpoint
|
||||
|
||||
GraphQL queries are **read-optimized for speed**. Data may be slightly out of date until the file system cache refreshes. The GraphQL endpoints allows you to access the following objects:
|
||||
GraphQL queries are **read-optimized for speed**. Data may be slightly out of date until the file system cache refreshes. The GraphQL endpoints allow you to access the following objects:
|
||||
|
||||
- Devices
|
||||
- Settings
|
||||
* Devices
|
||||
* Settings
|
||||
* Language Strings (LangStrings)
|
||||
|
||||
## Endpoints
|
||||
|
||||
@@ -190,11 +191,74 @@ curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## LangStrings Query
|
||||
|
||||
The **LangStrings query** provides access to localized strings. Supports filtering by `langCode` and `langStringKey`. If the requested string is missing or empty, you can optionally fallback to `en_us`.
|
||||
|
||||
### Sample Query
|
||||
|
||||
```graphql
|
||||
query GetLangStrings {
|
||||
langStrings(langCode: "de_de", langStringKey: "settings_other_scanners") {
|
||||
langStrings {
|
||||
langCode
|
||||
langStringKey
|
||||
langStringText
|
||||
}
|
||||
count
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Query Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| ---------------- | ------- | ---------------------------------------------------------------------------------------- |
|
||||
| `langCode` | String | Optional language code (e.g., `en_us`, `de_de`). If omitted, all languages are returned. |
|
||||
| `langStringKey` | String | Optional string key to retrieve a specific entry. |
|
||||
| `fallback_to_en` | Boolean | Optional (default `true`). If `true`, empty or missing strings fallback to `en_us`. |
|
||||
|
||||
### `curl` Example
|
||||
|
||||
```sh
|
||||
curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||
-X POST \
|
||||
-H 'Authorization: Bearer API_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"query": "query GetLangStrings { langStrings(langCode: \"de_de\", langStringKey: \"settings_other_scanners\") { langStrings { langCode langStringKey langStringText } count } }"
|
||||
}'
|
||||
```
|
||||
|
||||
### Sample Response
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"langStrings": {
|
||||
"count": 1,
|
||||
"langStrings": [
|
||||
{
|
||||
"langCode": "de_de",
|
||||
"langStringKey": "settings_other_scanners",
|
||||
"langStringText": "Other, non-device scanner plugins that are currently enabled." // falls back to en_us if empty
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
* Device and settings queries can be combined in one request since GraphQL supports batching.
|
||||
* Device, settings, and LangStrings queries can be combined in **one request** since GraphQL supports batching.
|
||||
* The `fallback_to_en` feature ensures UI always has a value even if a translation is missing.
|
||||
* Data is **cached in memory** per JSON file; changes to language or plugin files will only refresh after the cache detects a file modification.
|
||||
* The `setOverriddenByEnv` flag helps identify setting values that are locked at container runtime.
|
||||
* The schema is **read-only** — updates must be performed through other APIs or configuration management. See the other [API](API.md) endpoints for details.
|
||||
|
||||
|
||||
179
docs/API_LOGS.md
Normal file
179
docs/API_LOGS.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Logs API Endpoints
|
||||
|
||||
Manage or purge application log files stored under `/app/log` and manage the execution queue. These endpoints are primarily used for maintenance tasks such as clearing accumulated logs or adding system actions without restarting the container.
|
||||
|
||||
Only specific, pre-approved log files can be purged for security and stability reasons.
|
||||
|
||||
---
|
||||
|
||||
## Delete (Purge) a Log File
|
||||
|
||||
* **DELETE** `/logs?file=<log_file>` → Purge the contents of an allowed log file.
|
||||
|
||||
**Query Parameter:**
|
||||
|
||||
* `file` → The name of the log file to purge (e.g., `app.log`, `stdout.log`)
|
||||
|
||||
**Allowed Files:**
|
||||
|
||||
```
|
||||
app.log
|
||||
app_front.log
|
||||
IP_changes.log
|
||||
stdout.log
|
||||
stderr.log
|
||||
app.php_errors.log
|
||||
execution_queue.log
|
||||
db_is_locked.log
|
||||
```
|
||||
|
||||
**Authorization:**
|
||||
Requires a valid API token in the `Authorization` header.
|
||||
|
||||
---
|
||||
|
||||
### `curl` Example (Success)
|
||||
|
||||
```sh
|
||||
curl -X DELETE 'http://<server_ip>:<GRAPHQL_PORT>/logs?file=app.log' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Accept: application/json'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "[clean_log] File app.log purged successfully"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `curl` Example (Not Allowed)
|
||||
|
||||
```sh
|
||||
curl -X DELETE 'http://<server_ip>:<GRAPHQL_PORT>/logs?file=not_allowed.log' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Accept: application/json'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "[clean_log] File not_allowed.log is not allowed to be purged"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `curl` Example (Unauthorized)
|
||||
|
||||
```sh
|
||||
curl -X DELETE 'http://<server_ip>:<GRAPHQL_PORT>/logs?file=app.log' \
|
||||
-H 'Accept: application/json'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "Forbidden"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Add an Action to the Execution Queue
|
||||
|
||||
* **POST** `/logs/add-to-execution-queue` → Add a system action to the execution queue.
|
||||
|
||||
**Request Body (JSON):**
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "update_api|devices"
|
||||
}
|
||||
```
|
||||
|
||||
**Authorization:**
|
||||
Requires a valid API token in the `Authorization` header.
|
||||
|
||||
---
|
||||
|
||||
### `curl` Example (Success)
|
||||
|
||||
The below will update the API cache for Devices
|
||||
|
||||
```sh
|
||||
curl -X POST 'http://<server_ip>:<GRAPHQL_PORT>/logs/add-to-execution-queue' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{"action": "update_api|devices"}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "[UserEventsQueueInstance] Action \"update_api|devices\" added to the execution queue."
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `curl` Example (Missing Parameter)
|
||||
|
||||
```sh
|
||||
curl -X POST 'http://<server_ip>:<GRAPHQL_PORT>/logs/add-to-execution-queue' \
|
||||
-H 'Authorization: Bearer <API_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "Missing parameters",
|
||||
"error": "Missing required 'action' field in JSON body"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `curl` Example (Unauthorized)
|
||||
|
||||
```sh
|
||||
curl -X POST 'http://<server_ip>:<GRAPHQL_PORT>/logs/add-to-execution-queue' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{"action": "update_api|devices"}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "Forbidden"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
* Only predefined files in `/app/log` can be purged — arbitrary paths are **not permitted**.
|
||||
* When a log file is purged:
|
||||
|
||||
* Its content is replaced with a short marker text: `"File manually purged"`.
|
||||
* A backend log entry is created via `mylog()`.
|
||||
* A frontend notification is generated via `write_notification()`.
|
||||
* Execution queue actions are appended to `execution_queue.log` and can be processed asynchronously by background tasks or workflows.
|
||||
* Unauthorized or invalid attempts are safely logged and rejected.
|
||||
* For advanced log retrieval, analysis, or structured querying, use the frontend log viewer.
|
||||
* Always ensure that sensitive or production logs are handled carefully — purging cannot be undone.
|
||||
@@ -141,7 +141,7 @@ The endpoints are updated when objects in the API endpoints are changed.
|
||||
|
||||
### Location of the endpoints
|
||||
|
||||
In the container, these files are located under the `/app/api/` folder. You can access them via the `/php/server/query_json.php?file=user_notifications.json` endpoint.
|
||||
In the container, these files are located under the API directory (default: `/tmp/api/`, configurable via `NETALERTX_API` environment variable). You can access them via the `/php/server/query_json.php?file=user_notifications.json` endpoint.
|
||||
|
||||
### Available endpoints
|
||||
|
||||
@@ -332,7 +332,7 @@ Grafana template sample: [Download json](./samples/API/Grafana_Dashboard.json)
|
||||
|
||||
## API Endpoint: /log files
|
||||
|
||||
This API endpoint retrieves files from the `/app/log` folder.
|
||||
This API endpoint retrieves files from the `/tmp/log` folder.
|
||||
|
||||
- Endpoint URL: `php/server/query_logs.php?file=<file name>`
|
||||
- Host: `same as front end (web ui)`
|
||||
@@ -357,7 +357,7 @@ This API endpoint retrieves files from the `/app/log` folder.
|
||||
|
||||
## API Endpoint: /config files
|
||||
|
||||
To retrieve files from the `/app/config` folder.
|
||||
To retrieve files from the `/data/config` folder.
|
||||
|
||||
- Endpoint URL: `php/server/query_config.php?file=<file name>`
|
||||
- Host: `same as front end (web ui)`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Backing Things Up
|
||||
|
||||
> [!NOTE]
|
||||
> To back up 99% of your configuration, back up at least the `/app/config` folder.
|
||||
> To back up 99% of your configuration, back up at least the `/data/config` folder.
|
||||
> Database definitions can change between releases, so the safest method is to restore backups using the **same app version** they were taken from, then upgrade incrementally.
|
||||
|
||||
---
|
||||
@@ -25,7 +25,7 @@ Understanding where your data is stored helps you plan your backup strategy.
|
||||
|
||||
### Core Configuration
|
||||
|
||||
Stored in `/app/config/app.conf`.
|
||||
Stored in `/data/config/app.conf`.
|
||||
This includes settings for:
|
||||
|
||||
* Notifications
|
||||
@@ -37,7 +37,7 @@ This includes settings for:
|
||||
|
||||
### Device Data
|
||||
|
||||
Stored in `/app/config/devices_<timestamp>.csv` or `/app/config/devices.csv`, created by the [CSV Backup `CSVBCKP` Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup).
|
||||
Stored in `/data/config/devices_<timestamp>.csv` or `/data/config/devices.csv`, created by the [CSV Backup `CSVBCKP` Plugin](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/csv_backup).
|
||||
Contains:
|
||||
|
||||
* Device names, icons, and categories
|
||||
@@ -46,7 +46,7 @@ Contains:
|
||||
|
||||
### Historical Data
|
||||
|
||||
Stored in `/app/db/app.db` (see [Database Overview](./DATABASE.md)).
|
||||
Stored in `/data/db/app.db` (see [Database Overview](./DATABASE.md)).
|
||||
Contains:
|
||||
|
||||
* Plugin data and historical entries
|
||||
@@ -77,13 +77,13 @@ You can also download the `app.conf` and `devices.csv` files from the **Maintena
|
||||
|
||||
### 💾 What to Back Up
|
||||
|
||||
* `/app/db/app.db` (uncorrupted)
|
||||
* `/app/config/app.conf`
|
||||
* `/app/config/workflows.json`
|
||||
* `/data/db/app.db` (uncorrupted)
|
||||
* `/data/config/app.conf`
|
||||
* `/data/config/workflows.json`
|
||||
|
||||
### 📥 How to Restore
|
||||
|
||||
Map these files into your container as described in the [Setup documentation](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#docker-paths).
|
||||
Map these files into your container as described in the [Setup documentation](./DOCKER_INSTALLATION.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -93,14 +93,14 @@ Map these files into your container as described in the [Setup documentation](ht
|
||||
|
||||
### 💾 What to Back Up
|
||||
|
||||
* `/app/config/app.conf`
|
||||
* `/app/config/workflows.json`
|
||||
* `/app/config/devices_<timestamp>.csv` (rename to `devices.csv` during restore)
|
||||
* `/data/config/app.conf`
|
||||
* `/data/config/workflows.json`
|
||||
* `/data/config/devices_<timestamp>.csv` (rename to `devices.csv` during restore)
|
||||
|
||||
### 📥 How to Restore
|
||||
|
||||
1. Copy `app.conf` and `workflows.json` into `/app/config/`
|
||||
2. Rename and place `devices_<timestamp>.csv` → `/app/config/devices.csv`
|
||||
1. Copy `app.conf` and `workflows.json` into `/data/config/`
|
||||
2. Rename and place `devices_<timestamp>.csv` → `/data/config/devices.csv`
|
||||
3. Restore via the **Maintenance** section under *Devices → Bulk Editing*
|
||||
|
||||
This recovers nearly all configuration, workflows, and device metadata.
|
||||
@@ -157,6 +157,6 @@ For users running NetAlertX via Docker, you can back up or restore directly from
|
||||
|
||||
## Summary
|
||||
|
||||
* Back up `/app/config` for configuration and devices; `/app/db` for history
|
||||
* Back up `/data/config` for configuration and devices; `/data/db` for history
|
||||
* Keep regular backups, especially before upgrades
|
||||
* For Docker setups, use the lightweight `alpine`-based backup method for consistency and portability
|
||||
|
||||
@@ -14,9 +14,9 @@ The app uses the MAC address as an unique identifier for devices. If a new MAC i
|
||||
|
||||
Make sure you [File permissions](./FILE_PERMISSIONS.md) are set correctly.
|
||||
|
||||
* If facing issues (AJAX errors, can't write to DB, empty screen, etc,) make sure permissions are set correctly, and check the logs under `/app/log`.
|
||||
* To solve permission issues you can try setting the owner and group of the `app.db` by executing the following on the host system: `docker exec netalertx chown -R www-data:www-data /app/db/app.db`.
|
||||
* If still facing issues, try to map the app.db file (⚠ not folder) to `:/app/db/app.db` (see [docker-compose Examples](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#-docker-composeyml-examples) for details)
|
||||
* If facing issues (AJAX errors, can't write to DB, empty screen, etc,) make sure permissions are set correctly, and check the logs under `/tmp/log`.
|
||||
* To solve permission issues you can try setting the owner and group of the `app.db` by executing the following on the host system: `docker exec netalertx chown -R www-data:www-data /data/db/app.db`.
|
||||
* If still facing issues, try to map the app.db file (⚠ not folder) to `:/data/db/app.db` (see [docker-compose Examples](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md#-docker-composeyml-examples) for details)
|
||||
|
||||
### Container restarts / crashes
|
||||
|
||||
@@ -49,7 +49,7 @@ Make sure that the subnet and interface in `SCAN_SUBNETS` are correct. If your d
|
||||
|
||||
### Losing my settings and devices after an update
|
||||
|
||||
If you lose your devices and/or settings after an update that means you don't have the `/app/db` and `/app/config` folders mapped to a permanent storage. That means every time you update these folders are re-created. Make sure you have the [volumes specified correctly](./DOCKER_COMPOSE.md) in your `docker-compose.yml` or run command.
|
||||
If you lose your devices and/or settings after an update that means you don't have the `/data/db` and `/data/config` folders mapped to a permanent storage. That means every time you update these folders are re-created. Make sure you have the [volumes specified correctly](./DOCKER_COMPOSE.md) in your `docker-compose.yml` or run command.
|
||||
|
||||
|
||||
### The application is slow
|
||||
|
||||
@@ -27,7 +27,7 @@ Sometimes, the UI might not be accessible. In that case, you can access the logs
|
||||
3. **Check the PHP application error log:**
|
||||
|
||||
```bash
|
||||
cat /app/log/app.php_errors.log
|
||||
cat /tmp/log/app.php_errors.log
|
||||
```
|
||||
|
||||
These logs will help identify syntax issues, fatal errors, or startup problems when the UI fails to load properly.
|
||||
|
||||
@@ -14,8 +14,8 @@ Start the container via the **terminal** with a command similar to this one:
|
||||
|
||||
```bash
|
||||
docker run --rm --network=host \
|
||||
-v local/path/netalertx/config:/app/config \
|
||||
-v local/path/netalertx/db:/app/db \
|
||||
-v local/path/netalertx/config:/data/config \
|
||||
-v local/path/netalertx/db:/data/db \
|
||||
-e TZ=Europe/Berlin \
|
||||
-e PORT=20211 \
|
||||
ghcr.io/jokob-sk/netalertx:latest
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# NetAlertX and Docker Compose
|
||||
|
||||
> [!WARNING]
|
||||
> ⚠️ **Important:** The documentation has been recently updated and some instructions may have changed.
|
||||
> If you are using the currently live production image, please follow the instructions on [Docker Hub](https://hub.docker.com/r/jokobsk/netalertx) for building and running the container.
|
||||
> These docs reflect the latest development version and may differ from the production image.
|
||||
|
||||
Great care is taken to ensure NetAlertX meets the needs of everyone while being flexible enough for anyone. This document outlines how you can configure your docker-compose. There are many settings, so we recommend using the Baseline Docker Compose as-is, or modifying it for your system.Good care is taken to ensure NetAlertX meets the needs of everyone while being flexible enough for anyone. This document outlines how you can configure your docker-compose. There are many settings, so we recommend using the Baseline Docker Compose as-is, or modifying it for your system.
|
||||
|
||||
> [!NOTE]
|
||||
@@ -26,61 +31,46 @@ services:
|
||||
- NET_BIND_SERVICE # Required to bind to privileged ports (nbtscan)
|
||||
|
||||
volumes:
|
||||
- type: volume # Persistent Docker-managed Named Volume for storage of config files
|
||||
source: netalertx_config # the default name of the volume is netalertx_config
|
||||
target: /app/config # inside the container mounted to /app/config
|
||||
read_only: false # writable volume
|
||||
|
||||
# Example custom local folder called /home/user/netalertx_config
|
||||
# - type: bind
|
||||
# source: /home/user/netalertx_config
|
||||
# target: /app/config
|
||||
# read_only: false
|
||||
# ... or use the alternative format
|
||||
# - /home/user/netalertx_config:/app/config:rw
|
||||
|
||||
- type: volume # NetAlertX Database partiton
|
||||
source: netalertx_db
|
||||
target: /app/db
|
||||
- type: volume # Persistent Docker-managed named volume for config + database
|
||||
source: netalertx_data
|
||||
target: /data # `/data/config` and `/data/db` live inside this mount
|
||||
read_only: false
|
||||
|
||||
- type: volume # Future proof mount. During the migration to a
|
||||
source: netalertx_data # future version, app and db will be migrated to
|
||||
target: /data # the /data partition. This will reduce the
|
||||
read_only: false # overhead and pain in the upcoming migration.
|
||||
# Example custom local folder called /home/user/netalertx_data
|
||||
# - type: bind
|
||||
# source: /home/user/netalertx_data
|
||||
# target: /data
|
||||
# read_only: false
|
||||
# ... or use the alternative format
|
||||
# - /home/user/netalertx_data:/data:rw
|
||||
|
||||
- type: bind # Bind mount for timezone consistency
|
||||
source: /etc/localtime
|
||||
source: /etc/localtime # Alternatively add environment TZ: America/New York
|
||||
target: /etc/localtime
|
||||
read_only: true
|
||||
|
||||
# Mount your DHCP server file into NetAlertX for a plugin to access
|
||||
# - path/on/host/to/dhcp.file:/resources/dhcp.file
|
||||
|
||||
# Retain logs - comment out tmpfs /app/log if you want to retain logs between container restarts
|
||||
# - /path/on/host/log:/app/log
|
||||
|
||||
# Tempfs mounts for writable directories in a read-only container and improve system performance
|
||||
# All mounts have noexec,nosuid,nodev for security purposes no devices, no suid/sgid and no execution of binaries
|
||||
# async where possible for performance, sync where required for correctness
|
||||
# tmpfs mount consolidates writable state for a read-only container and improves performance
|
||||
# uid=20211 and gid=20211 is the netalertx user inside the container
|
||||
# mode=1700 gives rwx------ permissions to the netalertx user only
|
||||
# mode=1700 grants rwx------ permissions to the netalertx user only
|
||||
tmpfs:
|
||||
# Speed up logging. This can be commented out to retain logs between container restarts
|
||||
- "/app/log:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# Speed up API access as frontend/backend API is very chatty
|
||||
- "/app/api:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,sync,noatime,nodiratime"
|
||||
# Required for customization of the nginx listen addr/port without rebuilding the container
|
||||
- "/services/config/nginx/conf.active:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# /services/config/nginx/conf.d is required for nginx and php to start
|
||||
- "/services/run:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# /tmp is required by php for session save this should be reworked to /services/run/tmp
|
||||
- "/tmp:uid=2Key-Value Pairs: 20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# Comment out to retain logs between container restarts - this has a server performance impact.
|
||||
- "/tmp:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
|
||||
# Retain logs - comment out tmpfs /tmp if you want to retain logs between container restarts
|
||||
# Please note if you remove the /tmp mount, you must create and maintain sub-folder mounts.
|
||||
# - /path/on/host/log:/tmp/log
|
||||
# - "/tmp/api:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# - "/tmp/nginx:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# - "/tmp/run:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
|
||||
environment:
|
||||
LISTEN_ADDR: ${LISTEN_ADDR:-0.0.0.0} # Listen for connections on all interfaces
|
||||
PORT: ${PORT:-20211} # Application port
|
||||
GRAPHQL_PORT: ${GRAPHQL_PORT:-20212} # GraphQL API port (passed into APP_CONF_OVERRIDE at runtime)
|
||||
NETALERTX_DEBUG: ${NETALERTX_DEBUG:-0} # 0=kill all services and restart if any dies. 1 keeps running dead services.
|
||||
# NETALERTX_DEBUG: ${NETALERTX_DEBUG:-0} # 0=kill all services and restart if any dies. 1 keeps running dead services.
|
||||
|
||||
# Resource limits to prevent resource exhaustion
|
||||
mem_limit: 2048m # Maximum memory usage
|
||||
@@ -96,10 +86,8 @@ services:
|
||||
# Always restart the container unless explicitly stopped
|
||||
restart: unless-stopped
|
||||
|
||||
volumes: # Persistent volumes for configuration and database storage
|
||||
netalertx_config: # Configuration files
|
||||
netalertx_db: # Database files
|
||||
netalertx_data: # For future config/db upgrade
|
||||
volumes: # Persistent volume for configuration and database storage
|
||||
netalertx_data:
|
||||
```
|
||||
|
||||
Run or re-run it:
|
||||
@@ -158,8 +146,8 @@ However, if you prefer to have direct, file-level access to your configuration f
|
||||
```yaml
|
||||
...
|
||||
volumes:
|
||||
- netalertx_config:/app/config:rw #short-form volume (no /path is a short volume)
|
||||
- netalertx_db:/app/db:rw
|
||||
- netalertx_config:/data/config:rw #short-form volume (no /path is a short volume)
|
||||
- netalertx_db:/data/db:rw
|
||||
...
|
||||
```
|
||||
|
||||
@@ -169,14 +157,14 @@ Make sure to replace `/home/adam/netalertx-files` with your actual path. The for
|
||||
```yaml
|
||||
...
|
||||
volumes:
|
||||
# - netalertx_config:/app/config:rw
|
||||
# - netalertx_db:/app/db:rw
|
||||
- /home/adam/netalertx-files/config:/app/config:rw
|
||||
- /home/adam/netalertx-files/db:/app/db:rw
|
||||
# - netalertx_config:/data/config:rw
|
||||
# - netalertx_db:/data/db:rw
|
||||
- /home/adam/netalertx-files/config:/data/config:rw
|
||||
- /home/adam/netalertx-files/db:/data/db:rw
|
||||
...
|
||||
```
|
||||
|
||||
Now, any files created by NetAlertX in `/app/config` will appear in your `/home/adam/netalertx-files/config` folder.
|
||||
Now, any files created by NetAlertX in `/data/config` will appear in your `/home/adam/netalertx-files/config` folder.
|
||||
|
||||
This same method works for mounting other things, like custom plugins or enterprise NGINX files, as shown in the commented-out examples in the baseline file.
|
||||
|
||||
@@ -243,4 +231,4 @@ networks:
|
||||
outside:
|
||||
external:
|
||||
name: "host"
|
||||
```
|
||||
```
|
||||
|
||||
18
docs/INSTALLATION_DOCKER.md → docs/DOCKER_INSTALLATION.md
Executable file → Normal file
18
docs/INSTALLATION_DOCKER.md → docs/DOCKER_INSTALLATION.md
Executable file → Normal file
@@ -6,7 +6,7 @@
|
||||
|
||||
# NetAlertX - Network scanner & notification framework
|
||||
|
||||
| [📑 Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://jokob-sk.github.io/NetAlertX/) | [🔌 Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md) | [🤖 Ask AI](https://gurubase.io/g/netalertx)
|
||||
| [📑 Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_INSTALLATION.md) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://jokob-sk.github.io/NetAlertX/) | [🔌 Plugins](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md) | [🤖 Ask AI](https://gurubase.io/g/netalertx)
|
||||
|----------------------| ----------------------| ----------------------| ----------------------| ----------------------|
|
||||
|
||||
<a href="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" target="_blank">
|
||||
@@ -25,9 +25,9 @@ Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and scree
|
||||
|
||||
```yaml
|
||||
docker run -d --rm --network=host \
|
||||
-v local_path/config:/app/config \
|
||||
-v local_path/db:/app/db \
|
||||
--mount type=tmpfs,target=/app/api \
|
||||
-v local_path/config:/data/config \
|
||||
-v local_path/db:/data/db \
|
||||
--mount type=tmpfs,target=/tmp/api \
|
||||
-e PUID=200 -e PGID=300 \
|
||||
-e TZ=Europe/Berlin \
|
||||
-e PORT=20211 \
|
||||
@@ -58,10 +58,10 @@ See alternative [docked-compose examples](https://github.com/jokob-sk/NetAlertX/
|
||||
|
||||
| Required | Path | Description |
|
||||
| :------------- | :------------- | :-------------|
|
||||
| ✅ | `:/app/config` | Folder which will contain the `app.conf` & `devices.csv` ([read about devices.csv](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)) files |
|
||||
| ✅ | `:/app/db` | Folder which will contain the `app.db` database file |
|
||||
| | `:/app/log` | Logs folder useful for debugging if you have issues setting up the container |
|
||||
| | `:/app/api` | A simple [API endpoint](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md) containing static (but regularly updated) json and other files. |
|
||||
| ✅ | `:/data/config` | Folder which will contain the `app.conf` & `devices.csv` ([read about devices.csv](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DEVICES_BULK_EDITING.md)) files |
|
||||
| ✅ | `:/data/db` | Folder which will contain the `app.db` database file |
|
||||
| | `:/tmp/log` | Logs folder useful for debugging if you have issues setting up the container |
|
||||
| | `:/tmp/api` | A simple [API endpoint](https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md) containing static (but regularly updated) json and other files. Path configurable via `NETALERTX_API` environment variable. |
|
||||
| | `:/app/front/plugins/<plugin>/ignore_plugin` | Map a file `ignore_plugin` to ignore a plugin. Plugins can be soft-disabled via settings. More in the [Plugin docs](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md). |
|
||||
| | `:/etc/resolv.conf` | Use a custom `resolv.conf` file for [better name resolution](https://github.com/jokob-sk/NetAlertX/blob/main/docs/REVERSE_DNS.md). |
|
||||
|
||||
@@ -70,7 +70,7 @@ See alternative [docked-compose examples](https://github.com/jokob-sk/NetAlertX/
|
||||
### Initial setup
|
||||
|
||||
- If unavailable, the app generates a default `app.conf` and `app.db` file on the first run.
|
||||
- The preferred way is to manage the configuration via the Settings section in the UI, if UI is inaccessible you can modify [app.conf](https://github.com/jokob-sk/NetAlertX/tree/main/back) in the `/app/config/` folder directly
|
||||
- The preferred way is to manage the configuration via the Settings section in the UI, if UI is inaccessible you can modify [app.conf](https://github.com/jokob-sk/NetAlertX/tree/main/back) in the `/data/config/` folder directly
|
||||
|
||||
#### Setting up scanners
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# The NetAlertX Container Operator's Guide
|
||||
|
||||
> [!WARNING]
|
||||
> ⚠️ **Important:** The documentation has been recently updated and some instructions may have changed.
|
||||
> If you are using the currently live production image, please follow the instructions on [Docker Hub](https://hub.docker.com/r/jokobsk/netalertx) for building and running the container.
|
||||
> These docs reflect the latest development version and may differ from the production image.
|
||||
|
||||
This guide assumes you are starting with the official `docker-compose.yml` file provided with the project. We strongly recommend you start with or migrate to this file as your baseline and modify it to suit your specific needs (e.g., changing file paths). While there are many ways to configure NetAlertX, the default file is designed to meet the mandatory security baseline with layer-2 networking capabilities while operating securely and without startup warnings.
|
||||
|
||||
This guide provides direct, concise solutions for common NetAlertX administrative tasks. It is structured to help you identify a problem, implement the solution, and understand the details.
|
||||
@@ -46,13 +51,13 @@ You want to edit your `app.conf` and other configuration files directly from you
|
||||
volumes:
|
||||
# - type: volume
|
||||
# source: netalertx_config
|
||||
# target: /app/config
|
||||
# target: /data/config
|
||||
# read_only: false
|
||||
...
|
||||
# Example custom local folder called /data/netalertx_config
|
||||
- type: bind
|
||||
source: /data/netalertx_config
|
||||
target: /app/config
|
||||
target: /data/config
|
||||
read_only: false
|
||||
...
|
||||
```
|
||||
@@ -65,7 +70,7 @@ You want to edit your `app.conf` and other configuration files directly from you
|
||||
|
||||
### About This Method
|
||||
|
||||
This replaces the Docker-managed volume with a "bind mount." This is a direct mapping between a folder on your host computer (`/data/netalertx_config`) and a folder inside the container (`/app/config`), allowing you to edit the files directly.
|
||||
This replaces the Docker-managed volume with a "bind mount." This is a direct mapping between a folder on your host computer (`/data/netalertx_config`) and a folder inside the container (`/data/config`), allowing you to edit the files directly.
|
||||
|
||||
---
|
||||
|
||||
@@ -92,13 +97,13 @@ You are currently using a local folder (bind mount) for your configuration (e.g.
|
||||
volumes:
|
||||
- type: volume
|
||||
source: netalertx_config
|
||||
target: /app/config
|
||||
target: /data/config
|
||||
read_only: false
|
||||
...
|
||||
# Example custom local folder called /data/netalertx_config
|
||||
# - type: bind
|
||||
# source: /data/netalertx_config
|
||||
# target: /app/config
|
||||
# target: /data/config
|
||||
# read_only: false
|
||||
...
|
||||
```
|
||||
@@ -144,7 +149,7 @@ You need to override the default Nginx configuration to add features like LDAP,
|
||||
```yaml
|
||||
...
|
||||
# Use a custom Enterprise-configured nginx config for ldap or other settings
|
||||
- /data/my-netalertx.conf:/services/config/nginx/conf.active/netalertx.conf:ro
|
||||
- /data/my-netalertx.conf:/tmp/nginx/active-config/netalertx.conf:ro
|
||||
...
|
||||
```
|
||||
4. Restart the container:
|
||||
|
||||
@@ -45,18 +45,18 @@ services:
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
- ${APP_FOLDER}/netalertx/config:/app/config
|
||||
- ${APP_FOLDER}/netalertx/db:/app/db
|
||||
- ${APP_FOLDER}/netalertx/config:/data/config
|
||||
- ${APP_FOLDER}/netalertx/db:/data/db
|
||||
# Optional: logs (useful for debugging setup issues, comment out for performance)
|
||||
- ${APP_FOLDER}/netalertx/log:/app/log
|
||||
- ${APP_FOLDER}/netalertx/log:/tmp/log
|
||||
|
||||
# API storage options:
|
||||
# (Option 1) tmpfs (default, best performance)
|
||||
- type: tmpfs
|
||||
target: /app/api
|
||||
target: /tmp/api
|
||||
|
||||
# (Option 2) bind mount (useful for debugging)
|
||||
# - ${APP_FOLDER}/netalertx/api:/app/api
|
||||
# - ${APP_FOLDER}/netalertx/api:/tmp/api
|
||||
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
|
||||
@@ -44,9 +44,9 @@ services:
|
||||
ports:
|
||||
- 20211:20211
|
||||
volumes:
|
||||
- /mnt/YOUR_SERVER/netalertx/config:/app/config:rw
|
||||
- /mnt/YOUR_SERVER/netalertx/db:/netalertx/app/db:rw
|
||||
- /mnt/YOUR_SERVER/netalertx/logs:/netalertx/app/log:rw
|
||||
- /mnt/YOUR_SERVER/netalertx/config:/data/config:rw
|
||||
- /mnt/YOUR_SERVER/netalertx/db:/netalertx/data/db:rw
|
||||
- /mnt/YOUR_SERVER/netalertx/logs:/netalertx/tmp/log:rw
|
||||
environment:
|
||||
- TZ=Europe/London
|
||||
- PORT=20211
|
||||
|
||||
@@ -11,13 +11,15 @@ NetAlertX requires certain paths to be writable at runtime. These paths should b
|
||||
|
||||
| Path | Purpose | Notes |
|
||||
| ------------------------------------ | ----------------------------------- | ------------------------------------------------------ |
|
||||
| `/app/config` | Application configuration | Persistent volume recommended |
|
||||
| `/app/db` | Database files | Persistent volume recommended |
|
||||
| `/app/log` | Logs | Can be `tmpfs` for speed or host volume to retain logs |
|
||||
| `/app/api` | API cache | Use `tmpfs` for faster access |
|
||||
| `/services/config/nginx/conf.active` | Active nginx configuration override | `tmpfs` recommended or customized file mounted |
|
||||
| `/services/run` | Runtime directories for nginx & PHP | `tmpfs` required |
|
||||
| `/tmp` | PHP session save directory | `tmpfs` required |
|
||||
| `/data/config` | Application configuration | Persistent volume recommended |
|
||||
| `/data/db` | Database files | Persistent volume recommended |
|
||||
| `/tmp/log` | Logs | Lives under `/tmp`; optional host bind to retain logs |
|
||||
| `/tmp/api` | API cache | Subdirectory of `/tmp` |
|
||||
| `/tmp/nginx/active-config` | Active nginx configuration override | Mount `/tmp` (or override specific file) |
|
||||
| `/tmp/run` | Runtime directories for nginx & PHP | Subdirectory of `/tmp` |
|
||||
| `/tmp` | PHP session save directory | Backed by `tmpfs` for runtime writes |
|
||||
|
||||
> Mounting `/tmp` as `tmpfs` automatically covers all of its subdirectories (`log`, `api`, `run`, `nginx/active-config`, etc.).
|
||||
|
||||
> All these paths will have **UID 20211 / GID 20211** inside the container. Files on the host will appear owned by `20211:20211`.
|
||||
|
||||
@@ -33,8 +35,8 @@ Sometimes, permission issues arise if your existing host directories were create
|
||||
|
||||
```bash
|
||||
docker run -it --rm --name netalertx --user "0" \
|
||||
-v local/path/config:/app/config \
|
||||
-v local/path/db:/app/db \
|
||||
-v local/path/config:/data/config \
|
||||
-v local/path/db:/data/db \
|
||||
ghcr.io/jokob-sk/netalertx:latest
|
||||
```
|
||||
|
||||
@@ -60,16 +62,12 @@ services:
|
||||
- NET_BIND_SERVICE
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
- local/path/config:/data/config
|
||||
- local/path/db:/data/db
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
tmpfs:
|
||||
- "/app/log:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
- "/app/api:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,sync,noatime,nodiratime"
|
||||
- "/services/config/nginx/conf.active:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
- "/services/run:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
tmpfs:
|
||||
- "/tmp:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
```
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
NetAlertX can be installed several ways. The best supported option is Docker, followed by a supervised Home Assistant instance, as an Unraid app, and lastly, on bare metal.
|
||||
|
||||
- [[Installation] Docker (recommended)](./INSTALLATION_DOCKER.md)
|
||||
- [[Installation] Docker (recommended)](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_INSTALLATION.md)
|
||||
- [[Installation] Home Assistant](https://github.com/alexbelgium/hassio-addons/tree/master/netalertx)
|
||||
- [[Installation] Unraid App](https://unraid.net/community/apps)
|
||||
- [[Installation] Bare metal (experimental - looking for maintainers)](./HW_INSTALL.md)
|
||||
- [[Installation] Bare metal (experimental - looking for maintainers)](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md)
|
||||
|
||||
|
||||
## Help
|
||||
|
||||
@@ -9,7 +9,7 @@ NetAlertX comes with several logs that help to identify application issues. Thes
|
||||
|
||||
You can find most of the logs exposed in the UI under _Maintenance -> Logs_.
|
||||
|
||||
If the UI is inaccessible, you can access them under `/app/log`.
|
||||
If the UI is inaccessible, you can access them under `/tmp/log`.
|
||||
|
||||

|
||||
|
||||
@@ -52,18 +52,18 @@ The default logs are erased every time the container restarts because they are s
|
||||
|
||||
2. Edit your `docker-compose.yml` file:
|
||||
|
||||
* **Comment out** the `/app/log` line under the `tmpfs:` section.
|
||||
* **Comment out** the `/tmp/log` line under the `tmpfs:` section.
|
||||
* **Uncomment** the "Retain logs" line under the `volumes:` section and set your desired host path.
|
||||
|
||||
```yaml
|
||||
...
|
||||
tmpfs:
|
||||
# - "/app/log:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# - "/tmp/log:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
...
|
||||
volumes:
|
||||
...
|
||||
# Retain logs - comment out tmpfs /app/log if you want to retain logs between container restarts
|
||||
- /home/adam/netalertx_logs:/app/log
|
||||
# Retain logs - comment out tmpfs /tmp/log if you want to retain logs between container restarts
|
||||
- /home/adam/netalertx_logs:/tmp/log
|
||||
...
|
||||
```
|
||||
3. Restart the container:
|
||||
@@ -72,4 +72,4 @@ The default logs are erased every time the container restarts because they are s
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
This change stops Docker from mounting a temporary in-memory volume at `/app/log`. Instead, it "bind mounts" a persistent folder from your host computer (e.g., `/data/netalertx_logs`) to that *same location* inside the container.
|
||||
This change stops Docker from mounting a temporary in-memory volume at `/tmp/log`. Instead, it "bind mounts" a persistent folder from your host computer (e.g., `/data/netalertx_logs`) to that *same location* inside the container.
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Migration
|
||||
|
||||
> [!WARNING]
|
||||
> ⚠️ **Important:** The documentation has been recently updated and some instructions may have changed.
|
||||
> If you are using the currently live production image, please follow the instructions on [Docker Hub](https://hub.docker.com/r/jokobsk/netalertx) for building and running the container.
|
||||
> These docs reflect the latest development version and may differ from the production image.
|
||||
|
||||
|
||||
When upgrading from older versions of NetAlertX (or PiAlert by jokob-sk), follow the migration steps below to ensure your data and configuration are properly transferred.
|
||||
|
||||
> [!TIP]
|
||||
@@ -37,7 +43,7 @@ A banner message will appear at the top of the web UI reminding you to update yo
|
||||
|
||||
|
||||
> [!TIP]
|
||||
> If you have trouble accessing past backups, config or database files you can copy them into the newly mapped directories, for example by running this command in the container: `cp -r /app/config /home/pi/pialert/config/old_backup_files`. This should create a folder in the `config` directory called `old_backup_files` containing all the files in that location. Another approach is to map the old location and the new one at the same time to copy things over.
|
||||
> If you have trouble accessing past backups, config or database files you can copy them into the newly mapped directories, for example by running this command in the container: `cp -r /data/config /home/pi/pialert/config/old_backup_files`. This should create a folder in the `config` directory called `old_backup_files` containing all the files in that location. Another approach is to map the old location and the new one at the same time to copy things over.
|
||||
|
||||
#### New Docker mount locations
|
||||
|
||||
@@ -45,8 +51,8 @@ The internal application path in the container has changed from `/home/pi/pialer
|
||||
|
||||
| Old mount point | New mount point |
|
||||
|----------------------|---------------|
|
||||
| `/home/pi/pialert/config` | `/app/config` |
|
||||
| `/home/pi/pialert/db` | `/app/db` |
|
||||
| `/home/pi/pialert/config` | `/data/config` |
|
||||
| `/home/pi/pialert/db` | `/data/db` |
|
||||
|
||||
|
||||
If you were mounting files directly, please note the file names have changed:
|
||||
@@ -98,10 +104,10 @@ services:
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config # 🆕 This has changed
|
||||
- local/path/db:/app/db # 🆕 This has changed
|
||||
- local/path/config:/data/config # 🆕 This has changed
|
||||
- local/path/db:/data/db # 🆕 This has changed
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local/path/logs:/app/log # 🆕 This has changed
|
||||
- local/path/logs:/tmp/log # 🆕 This has changed
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
@@ -144,10 +150,10 @@ services:
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config/app.conf:/app/config/app.conf # 🆕 This has changed
|
||||
- local/path/db/app.db:/app/db/app.db # 🆕 This has changed
|
||||
- local/path/config/app.conf:/data/config/app.conf # 🆕 This has changed
|
||||
- local/path/db/app.db:/data/db/app.db # 🆕 This has changed
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local/path/logs:/app/log # 🆕 This has changed
|
||||
- local/path/logs:/tmp/log # 🆕 This has changed
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
@@ -184,10 +190,10 @@ services:
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
- local/path/config:/data/config
|
||||
- local/path/db:/data/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local/path/logs:/app/log
|
||||
- local/path/logs:/tmp/log
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
@@ -201,10 +207,10 @@ services:
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
- local/path/config:/data/config
|
||||
- local/path/db:/data/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local/path/logs:/app/log
|
||||
- local/path/logs:/tmp/log
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
@@ -228,10 +234,10 @@ services:
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
- local/path/config:/data/config
|
||||
- local/path/db:/data/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local/path/logs:/app/log
|
||||
- local/path/logs:/tmp/log
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
@@ -247,8 +253,8 @@ services:
|
||||
|
||||
```sh
|
||||
docker run -it --rm --name netalertx --user "0" \
|
||||
-v local/path/config:/app/config \
|
||||
-v local/path/db:/app/db \
|
||||
-v local/path/config:/data/config \
|
||||
-v local/path/db:/data/db \
|
||||
ghcr.io/jokob-sk/netalertx:latest
|
||||
```
|
||||
|
||||
@@ -267,24 +273,16 @@ services:
|
||||
- NET_BIND_SERVICE # 🆕 New line
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
- local/path/config:/data/config
|
||||
- local/path/db:/data/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
#- local/path/logs:/app/log
|
||||
#- local/path/logs:/tmp/log
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
# 🆕 New "tmpfs" section START 🔽
|
||||
tmpfs:
|
||||
# Speed up logging. This can be commented out to retain logs between container restarts
|
||||
- "/app/log:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# Speed up API access as frontend/backend API is very chatty
|
||||
- "/app/api:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,sync,noatime,nodiratime"
|
||||
# Required for customization of the nginx listen addr/port without rebuilding the container
|
||||
- "/services/config/nginx/conf.active:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# /services/config/nginx/conf.d is required for nginx and php to start
|
||||
- "/services/run:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# /tmp is required by php for session save this should be reworked to /services/run/tmp
|
||||
tmpfs:
|
||||
# All writable runtime state resides under /tmp; comment out to persist logs between restarts
|
||||
- "/tmp:uid=20211,gid=20211,mode=1700,rw,noexec,nosuid,nodev,async,noatime,nodiratime"
|
||||
# 🆕 New "tmpfs" section END 🔼
|
||||
```
|
||||
|
||||
@@ -44,14 +44,19 @@ In Notification Processing settings, you can specify blanket rules. These allow
|
||||
|
||||
1. Notify on (`NTFPRCS_INCLUDED_SECTIONS`) allows you to specify which events trigger notifications. Usual setups will have `new_devices`, `down_devices`, and possibly `down_reconnected` set. Including `plugin` (dependenton the Plugin `<plugin>_WATCH` and `<plugin>_REPORT_ON` settings) and `events` (dependent on the on-device **Alert Events** setting) might be too noisy for most setups. More info in the [NTFPRCS plugin](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/notification_processing/README.md) on what events these selections include.
|
||||
2. Alert down after (`NTFPRCS_alert_down_time`) is useful if you want to wait for some time before the system sends out a down notification for a device. This is related to the on-device **Alert down** setting and only devices with this checked will trigger a down notification.
|
||||
3. A filter to allow you to set device-specific exceptions to New devices being added to the app.
|
||||
4. A filter to allow you to set device-specific exceptions to generated Events.
|
||||
|
||||
## Ignoring devices 🔕
|
||||
You can filter out unwanted notifications globally. This could be because of a misbehaving device (GoogleNest/GoogleHub (See also [ARPSAN docs and the `--exclude-broadcast` flag](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/arp_scan#ip-flipping-on-google-nest-devices))) which flips between IP addresses, or because you want to ignore new device notifications of a certain pattern.
|
||||
|
||||
1. Events Filter (`NTFPRCS_event_condition`) - Filter out Events from notifications.
|
||||
2. New Devices Filter (`NTFPRCS_new_dev_condition`) - Filter out New Devices from notifications, but log and keep a new device in the system.
|
||||
|
||||
## Ignoring devices 💻
|
||||
|
||||

|
||||
|
||||
You can completely ignore detected devices globally. This could be because your instance detects docker containers, you want to ignore devices from a specific manufacturer via MAC rules or you want to ignore devices on a specific IP range.
|
||||
|
||||
1. Ignored MACs (`NEWDEV_ignored_MACs`) - List of MACs to ignore.
|
||||
2. Ignored IPs (`NEWDEV_ignored_IPs`) - List of IPs to ignore.
|
||||
2. Ignored IPs (`NEWDEV_ignored_IPs`) - List of IPs to ignore.
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ For example, the **ICMP plugin** allows you to specify a regular expression to s
|
||||
|
||||
## Storing Temporary Files in Memory
|
||||
|
||||
On systems with slower I/O speeds, you can optimize performance by storing temporary files in memory. This primarily applies to the `/app/api` and `/app/log` folders.
|
||||
On systems with slower I/O speeds, you can optimize performance by storing temporary files in memory. This primarily applies to the API directory (default: `/tmp/api`, configurable via `NETALERTX_API`) and `/tmp/log` folders.
|
||||
|
||||
Using `tmpfs` reduces disk writes and improves performance. However, it should be **disabled** if persistent logs or API data storage are required.
|
||||
|
||||
@@ -80,15 +80,15 @@ services:
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
- local/path/config:/data/config
|
||||
- local/path/db:/data/db
|
||||
# (Optional) Useful for debugging setup issues
|
||||
- local/path/logs:/app/log
|
||||
- local/path/logs:/tmp/log
|
||||
# (API: OPTION 1) Store temporary files in memory (recommended for performance)
|
||||
- type: tmpfs # ◀ 🔺
|
||||
target: /app/api # ◀ 🔺
|
||||
target: /tmp/api # ◀ 🔺
|
||||
# (API: OPTION 2) Store API data on disk (useful for debugging)
|
||||
# - local/path/api:/app/api
|
||||
# - local/path/api:/tmp/api
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
|
||||
@@ -1,146 +1,192 @@
|
||||
## config.json Lifecycle in NetAlertX
|
||||
# Plugins Implementation Details
|
||||
|
||||
This document describes on a high level how `config.json` is read, processed, and used by the NetAlertX core and plugins. It also outlines the plugin output contract and the main plugin types.
|
||||
Plugins provide data to the NetAlertX core, which processes it to detect changes, discover new devices, raise alerts, and apply heuristics.
|
||||
|
||||
> [!NOTE]
|
||||
> For a deep-dive on the specific configuration options and sections of the `config.json` plugin manifest, consult the [Plugins Development Guide](PLUGINS_DEV.md).
|
||||
---
|
||||
|
||||
## Overview: Plugin Data Flow
|
||||
|
||||
1. Each plugin runs on a defined schedule.
|
||||
2. Aligning all plugin schedules is recommended so they execute in the same loop.
|
||||
3. During execution, all plugins write their collected data into the **`CurrentScan`** table.
|
||||
4. After all plugins complete, the `CurrentScan` table is evaluated to detect **new devices**, **changes**, and **triggers**.
|
||||
|
||||
Although plugins run independently, they contribute to the shared `CurrentScan` table.
|
||||
To inspect its contents, set `LOG_LEVEL=trace` and check for the log section:
|
||||
|
||||
```
|
||||
================ CurrentScan table content ================
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `config.json` Lifecycle
|
||||
|
||||
This section outlines how each plugin’s `config.json` manifest is read, validated, and used by the core and plugins.
|
||||
It also describes plugin output expectations and the main plugin categories.
|
||||
|
||||
> [!TIP]
|
||||
> For detailed schema and examples, see the [Plugin Development Guide](PLUGINS_DEV.md).
|
||||
|
||||
---
|
||||
|
||||
### 1. Loading
|
||||
|
||||
* On startup, the app core loads `config.json` for each plugin.
|
||||
* The `config.json` represents a plugin manifest, that contains metadata and runtime settings.
|
||||
* On startup, the core loads `config.json` for each plugin.
|
||||
* The file acts as a **plugin manifest**, defining metadata, runtime configuration, and database mappings.
|
||||
|
||||
---
|
||||
|
||||
### 2. Validation
|
||||
|
||||
* The core checks that each required settings key (such as `RUN`) for a plugin exists.
|
||||
* Invalid or missing values may be replaced with defaults, or the plugin may be disabled.
|
||||
* The core validates required keys (for example, `RUN`).
|
||||
* Missing or invalid entries may be replaced with defaults or cause the plugin to be disabled.
|
||||
|
||||
---
|
||||
|
||||
### 3. Preparation
|
||||
|
||||
* The plugin’s settings (paths, commands, parameters) are prepared.
|
||||
* Database mappings (`mapped_to_table`, `database_column_definitions`) for data ingestion into the core app are parsed.
|
||||
* Plugin parameters (paths, commands, and options) are prepared for execution.
|
||||
* Database mappings (`mapped_to_table`, `database_column_definitions`) are parsed to define how data integrates with the main app.
|
||||
|
||||
---
|
||||
|
||||
### 4. Execution
|
||||
|
||||
* Plugins can be run at different core app execution points, such as on schedule, once on start, after a notification, etc.
|
||||
* At runtime, the scheduler triggers plugins according to their `interval`.
|
||||
* The plugin executes its command or script.
|
||||
* Plugins may run:
|
||||
|
||||
* On a fixed schedule.
|
||||
* Once at startup.
|
||||
* After a notification or other trigger.
|
||||
* The scheduler executes plugins according to their `interval`.
|
||||
|
||||
---
|
||||
|
||||
### 5. Parsing
|
||||
|
||||
* Plugin output is expected in **pipe (`|`)-delimited format**.
|
||||
* The core parses lines into fields, matching the **plugin interface contract**.
|
||||
* Plugin output must be **pipe-delimited (`|`)**.
|
||||
* The core parses each output line following the **Plugin Interface Contract**, splitting and mapping fields accordingly.
|
||||
|
||||
---
|
||||
|
||||
### 6. Mapping
|
||||
|
||||
* Each parsed field is moved into the `Plugins_` database tables and can be mapped into a configured database table.
|
||||
* Controlled by `database_column_definitions` and `mapped_to_table`.
|
||||
* Example: `Object_PrimaryID → Devices.MAC`.
|
||||
* Parsed fields are inserted into the plugin’s `Plugins_*` table.
|
||||
* Data can be mapped into other tables (e.g., `Devices`, `CurrentScan`) as defined by:
|
||||
|
||||
* `database_column_definitions`
|
||||
* `mapped_to_table`
|
||||
|
||||
**Example:** `Object_PrimaryID → devMAC`
|
||||
|
||||
---
|
||||
|
||||
### 6a. Plugin Output Contract
|
||||
|
||||
Each plugin must output results in the **plugin interface contract format**, pipe (`|`)-delimited values, in the column order described under [Plugin Interface Contract](PLUGINS_DEV.md)
|
||||
All plugins must follow the **Plugin Interface Contract** defined in `PLUGINS_DEV.md`.
|
||||
Output values are pipe-delimited in a fixed order.
|
||||
|
||||
#### IDs
|
||||
#### Identifiers
|
||||
|
||||
* `Object_PrimaryID` and `Object_SecondaryID` identify the record (e.g. `MAC|IP`).
|
||||
* `Object_PrimaryID` and `Object_SecondaryID` uniquely identify records (for example, `MAC|IP`).
|
||||
|
||||
#### **Watched values (`Watched_Value1–4`)**
|
||||
#### Watched Values (`Watched_Value1–4`)
|
||||
|
||||
* Used by the core to detect changes between runs.
|
||||
* Changes here can trigger **notifications**.
|
||||
* Used by the core to detect changes between runs.
|
||||
* Changes in these fields can trigger notifications.
|
||||
|
||||
#### **Extra value (`Extra`)**
|
||||
#### Extra Field (`Extra`)
|
||||
|
||||
* Optional, extra field.
|
||||
* Stored in the database but **not used for alerts**.
|
||||
* Optional additional value.
|
||||
* Stored in the database but not used for alerts.
|
||||
|
||||
#### **Helper values (`Helper_Value1–3`)**
|
||||
#### Helper Values (`Helper_Value1–3`)
|
||||
|
||||
* Added for cases where more than IDs + watched + extra are needed.
|
||||
* Can be made visible in the UI.
|
||||
* Stored in the database but **not used for alerts**.
|
||||
* Optional auxiliary data (for display or plugin logic).
|
||||
* Stored but not alert-triggering.
|
||||
|
||||
#### **Mapping matters**
|
||||
#### Mapping
|
||||
|
||||
* While the plugin output is free-form, the `database_column_definitions` and `mapped_to_table` settings in `config.json` determine the **target columns and data types** in NetAlertX.
|
||||
* While the output format is flexible, the plugin’s manifest determines the destination and type of each field.
|
||||
|
||||
---
|
||||
|
||||
### 7. Persistence
|
||||
|
||||
* Data is upserted into the database.
|
||||
* Conflicts are resolved using `Object_PrimaryID` + `Object_SecondaryID`.
|
||||
* Parsed data is **upserted** into the database.
|
||||
* Conflicts are resolved using the combined key: `Object_PrimaryID + Object_SecondaryID`.
|
||||
|
||||
---
|
||||
|
||||
### 8. Plugin Types and Expected Outputs
|
||||
## Plugin Categories
|
||||
|
||||
Beyond the `data_source` setting, plugins fall into functional categories. Each has its own input requirements and output expectations:
|
||||
Plugins fall into several functional categories depending on their purpose and expected outputs.
|
||||
|
||||
#### **Device discovery plugins**
|
||||
### 1. Device Discovery Plugins
|
||||
|
||||
* **Inputs:** `N/A`, subnet, or API for discovery service, or similar.
|
||||
* **Outputs:** At minimum `MAC` and `IP` that results in a new or updated device records in the `Devices` table.
|
||||
* **Mapping:** Must be mapped to the `CurrentScan` table via `database_column_definitions` and `data_filters`.
|
||||
* **Examples:** ARP-scan, NMAP device discovery (e.g., `ARPSCAN`, `NMAPDEV`).
|
||||
|
||||
#### **Device-data enrichment plugins**
|
||||
|
||||
* **Inputs:** Device identifier (usually `MAC`, `IP`).
|
||||
* **Outputs:** Additional data for that device (e.g. open ports).
|
||||
* **Mapping:** Controlled via `database_column_definitions` and `data_filters`.
|
||||
* **Examples:** Ports, MQTT messages (e.g., `NMAP`, `MQTT`)
|
||||
|
||||
#### **Name resolver plugins**
|
||||
|
||||
* **Inputs:** Device identifiers (MAC, IP, or hostname).
|
||||
* **Outputs:** Updated `devName` and `devFQDN` fields.
|
||||
* **Mapping:** Not expected.
|
||||
* **Note:** Currently requires **core app modification** to add new plugins, not fully driven by the plugins’ `config.json`.
|
||||
* **Examples:** Avahiscan (e.g., `NBTSCAN`, `NSLOOKUP`).
|
||||
|
||||
#### **Generic plugins**
|
||||
|
||||
* **Inputs:** Whatever the script or query provides.
|
||||
* **Outputs:** Data shown only in **Integrations → Plugins**, not tied to devices.
|
||||
* **Mapping:** Not expected.
|
||||
* **Examples:** External monitoring data (e.g., `INTRSPD`)
|
||||
|
||||
#### **Configuration-only plugins**
|
||||
|
||||
* **Inputs/Outputs:** None at runtime.
|
||||
* **Mapping:** Not expected.
|
||||
* **Examples:** Used to provide additional settings or execute scripts (e.g., `MAINT`, `CSVBCKP`).
|
||||
* **Inputs:** None, subnet, or discovery API.
|
||||
* **Outputs:** `MAC` and `IP` for new or updated device records in `Devices`.
|
||||
* **Mapping:** Required – usually into `CurrentScan`.
|
||||
* **Examples:** `ARPSCAN`, `NMAPDEV`.
|
||||
|
||||
---
|
||||
|
||||
### 9. Post-Processing
|
||||
### 2. Device Data Enrichment Plugins
|
||||
|
||||
* Notifications are generated if watched values change.
|
||||
* UI is updated with new or updated records.
|
||||
* All values that are configured to be shown in teh UI appear in the Plugins section.
|
||||
* **Inputs:** Device identifiers (`MAC`, `IP`).
|
||||
* **Outputs:** Additional metadata (for example, open ports or sensors).
|
||||
* **Mapping:** Controlled via manifest definitions.
|
||||
* **Examples:** `NMAP`, `MQTT`.
|
||||
|
||||
---
|
||||
|
||||
### 10. Summary
|
||||
### 3. Name Resolver Plugins
|
||||
|
||||
The lifecycle of `config.json` entries is:
|
||||
* **Inputs:** Device identifiers (`MAC`, `IP`, hostname`).
|
||||
* **Outputs:** Updated `devName` and `devFQDN`.
|
||||
* **Mapping:** Typically none.
|
||||
* **Note:** Adding new resolvers currently requires a core change.
|
||||
* **Examples:** `NBTSCAN`, `NSLOOKUP`.
|
||||
|
||||
---
|
||||
|
||||
### 4. Generic Plugins
|
||||
|
||||
* **Inputs:** Custom, based on the plugin logic or script.
|
||||
* **Outputs:** Data displayed under **Integrations → Plugins** only.
|
||||
* **Mapping:** Not required.
|
||||
* **Examples:** `INTRSPD`, custom monitoring scripts.
|
||||
|
||||
---
|
||||
|
||||
### 5. Configuration-Only Plugins
|
||||
|
||||
* **Inputs/Outputs:** None at runtime.
|
||||
* **Purpose:** Used for configuration or maintenance tasks.
|
||||
* **Examples:** `MAINT`, `CSVBCKP`.
|
||||
|
||||
---
|
||||
|
||||
## Post-Processing
|
||||
|
||||
After persistence:
|
||||
|
||||
* The core generates notifications for any watched value changes.
|
||||
* The UI updates with new or modified data.
|
||||
* Plugins with UI-enabled data display under **Integrations → Plugins**.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The lifecycle of a plugin configuration is:
|
||||
|
||||
**Load → Validate → Prepare → Execute → Parse → Map → Persist → Post-process**
|
||||
|
||||
Plugins must follow the **output contract**, and their category (discovery, specific, resolver, generic, config-only) defines what inputs they require and what outputs are expected.
|
||||
Each plugin must:
|
||||
|
||||
* Follow the **output contract**.
|
||||
* Declare its type and expected output structure.
|
||||
* Define mappings and watched values clearly in `config.json`.
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ There is also an in-app Help / FAQ section that should be answering frequently a
|
||||
|
||||
#### 🐳 Docker (Fully supported)
|
||||
|
||||
- The main installation method is as a [docker container - follow these instructions here](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md).
|
||||
- The main installation method is as a [docker container - follow these instructions here](./DOCKER_INSTALLATION.md).
|
||||
|
||||
#### 💻 Bare-metal / On-server (Experimental/community supported 🧪)
|
||||
|
||||
|
||||
@@ -42,9 +42,9 @@ services:
|
||||
image: "ghcr.io/jokob-sk/netalertx:latest"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /home/netalertx/config:/app/config
|
||||
- /home/netalertx/db:/app/db
|
||||
- /home/netalertx/log:/app/log
|
||||
- /home/netalertx/config:/data/config
|
||||
- /home/netalertx/db:/data/db
|
||||
- /home/netalertx/log:/tmp/log
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
@@ -68,9 +68,9 @@ services:
|
||||
image: "ghcr.io/jokob-sk/netalertx:latest"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./config/app.conf:/app/config/app.conf
|
||||
- ./db:/app/db
|
||||
- ./log:/app/log
|
||||
- ./config/app.conf:/data/config/app.conf
|
||||
- ./db:/data/db
|
||||
- ./log:/tmp/log
|
||||
- ./config/resolv.conf:/etc/resolv.conf # Mapping the /resolv.conf file for better name resolution
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
|
||||
@@ -499,8 +499,8 @@ Mapping the updated file (on the local filesystem at `/appl/docker/netalertx/def
|
||||
```bash
|
||||
docker run -d --rm --network=host \
|
||||
--name=netalertx \
|
||||
-v /appl/docker/netalertx/config:/app/config \
|
||||
-v /appl/docker/netalertx/db:/app/db \
|
||||
-v /appl/docker/netalertx/config:/data/config \
|
||||
-v /appl/docker/netalertx/db:/data/db \
|
||||
-v /appl/docker/netalertx/default:/etc/nginx/sites-available/default \
|
||||
-e TZ=Europe/Amsterdam \
|
||||
-e PORT=20211 \
|
||||
|
||||
@@ -48,7 +48,7 @@ Here’s a breakdown of the defensive layers you get, right out of the box using
|
||||
|
||||
**Methodology:** All writable locations are treated as untrusted, temporary, and non-executable by default.
|
||||
|
||||
* **In-Memory Volatile Storage:** The `docker-compose.yml` configuration maps all temporary directories (e.g., `/app/log`, `/app/api`, `/tmp`) to in-memory `tmpfs` filesystems. They do not exist on the host's disk.
|
||||
* **In-Memory Volatile Storage:** The `docker-compose.yml` configuration maps all temporary directories (e.g., `/tmp/log`, `/tmp/api`, `/tmp`) to in-memory `tmpfs` filesystems. They do not exist on the host's disk.
|
||||
|
||||
* **Volatile Data:** Because these locations exist only in RAM, their contents are **instantly and irrevocably erased** when the container is stopped. This provides a "self-cleaning" mechanism that purges any attacker-dropped files or payloads on every single restart.
|
||||
|
||||
|
||||
@@ -40,10 +40,10 @@ services:
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
- local/path/config:/data/config
|
||||
- local/path/db:/data/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local/path/logs:/app/log
|
||||
- local/path/logs:/tmp/log
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
@@ -57,10 +57,10 @@ services:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- /volume1/app_storage/netalertx/config:/app/config
|
||||
- /volume1/app_storage/netalertx/db:/app/db
|
||||
- /volume1/app_storage/netalertx/config:/data/config
|
||||
- /volume1/app_storage/netalertx/db:/data/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
# - local/path/logs:/app/log <- commented out with # ⚠
|
||||
# - local/path/logs:/tmp/log <- commented out with # ⚠
|
||||
```
|
||||
|
||||

|
||||
|
||||
@@ -15,7 +15,7 @@ The **Web UI** is served by an **nginx** server, while the **API backend** runs
|
||||
APP_CONF_OVERRIDE={"GRAPHQL_PORT":"20212"}
|
||||
```
|
||||
|
||||
For more information, check the [Docker installation guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md).
|
||||
For more information, check the [Docker installation guide](./DOCKER_INSTALLATION.md).
|
||||
|
||||
## Possible issues and troubleshooting
|
||||
|
||||
@@ -62,11 +62,11 @@ In the container execute and investigate:
|
||||
|
||||
`cat /var/log/nginx/error.log`
|
||||
|
||||
`cat /app/log/app.php_errors.log`
|
||||
`cat /tmp/log/app.php_errors.log`
|
||||
|
||||
### 8. Make sure permissions are correct
|
||||
|
||||
> [!TIP]
|
||||
> You can try to start the container without mapping the `/app/config` and `/app/db` dirs and if the UI shows up then the issue is most likely related to your file system permissions or file ownership.
|
||||
> You can try to start the container without mapping the `/data/config` and `/data/db` dirs and if the UI shows up then the issue is most likely related to your file system permissions or file ownership.
|
||||
|
||||
Please read the [Permissions troubleshooting guide](./FILE_PERMISSIONS.md) and provide a screesnhot of the permissions and ownership in the `/app/db` and `app/config` directories.
|
||||
Please read the [Permissions troubleshooting guide](./FILE_PERMISSIONS.md) and provide a screesnhot of the permissions and ownership in the `/data/db` and `app/config` directories.
|
||||
32
docs/docker-troubleshooting/excessive-capabilities.md
Normal file
32
docs/docker-troubleshooting/excessive-capabilities.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Excessive Capabilities
|
||||
|
||||
## Issue Description
|
||||
|
||||
Excessive Linux capabilities are detected beyond the necessary NET_ADMIN, NET_BIND_SERVICE, and NET_RAW. This may indicate overly permissive container configuration.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
While the detected capabilities might not directly harm operation, running with more privileges than necessary increases the attack surface. If the container is compromised, additional capabilities could allow broader system access or privilege escalation.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This occurs when your Docker configuration grants more capabilities than required for network monitoring. The application only needs specific network-related capabilities for proper function.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Limit capabilities to only those required:
|
||||
|
||||
- In docker-compose.yml, specify only needed caps:
|
||||
```yaml
|
||||
cap_add:
|
||||
- NET_RAW
|
||||
- NET_ADMIN
|
||||
- NET_BIND_SERVICE
|
||||
```
|
||||
- Remove any unnecessary `--cap-add` or `--privileged` flags from docker run commands
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
27
docs/docker-troubleshooting/file-permissions.md
Normal file
27
docs/docker-troubleshooting/file-permissions.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# File Permission Issues
|
||||
|
||||
## Issue Description
|
||||
|
||||
NetAlertX cannot read from or write to critical configuration and database files. This prevents the application from saving data, logs, or configuration changes.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
Incorrect file permissions can expose sensitive configuration data or database contents to unauthorized access. Network monitoring tools handle sensitive information about devices on your network, and improper permissions could lead to information disclosure.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This occurs when the mounted volumes for configuration and database files don't have proper ownership or permissions set for the netalertx user (UID 20211). The container expects these files to be accessible by the service account, not root or other users.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Fix permissions on the host system for the mounted directories:
|
||||
|
||||
- Ensure the config and database directories are owned by the netalertx user: `chown -R 20211:20211 /path/to/config /path/to/db`
|
||||
- Set appropriate permissions: `chmod -R 755 /path/to/config /path/to/db` for directories, `chmod 644` for files
|
||||
- Alternatively, restart the container with root privileges temporarily to allow automatic permission fixing, then switch back to the default user
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
28
docs/docker-troubleshooting/incorrect-user.md
Normal file
28
docs/docker-troubleshooting/incorrect-user.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Incorrect Container User
|
||||
|
||||
## Issue Description
|
||||
|
||||
NetAlertX is running as UID:GID other than the expected 20211:20211. This bypasses hardened permissions, file ownership, and runtime isolation safeguards.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
The application is designed with security hardening that depends on running under a dedicated, non-privileged service account. Using a different user account can silently fail future upgrades and removes crucial isolation between the container and host system.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This occurs when you override the container's default user with custom `user:` directives in docker-compose.yml or `--user` flags in docker run commands. The container expects to run as the netalertx user for proper security isolation.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Restore the container to the default user:
|
||||
|
||||
- Remove any `user:` overrides from docker-compose.yml
|
||||
- Avoid `--user` flags in docker run commands
|
||||
- Allow the container to run with its default UID:GID 20211:20211
|
||||
- Recreate the container so volume ownership is reset automatically
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
32
docs/docker-troubleshooting/missing-capabilities.md
Normal file
32
docs/docker-troubleshooting/missing-capabilities.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Missing Network Capabilities
|
||||
|
||||
## Issue Description
|
||||
|
||||
Raw network capabilities (NET_RAW, NET_ADMIN, NET_BIND_SERVICE) are missing. Tools that rely on these capabilities (e.g., nmap -sS, arp-scan, nbtscan) will not function.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
Network scanning and monitoring requires low-level network access that these capabilities provide. Without them, the application cannot perform essential functions like ARP scanning, port scanning, or passive network discovery, severely limiting its effectiveness.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This occurs when the container doesn't have the necessary Linux capabilities granted. Docker containers run with limited capabilities by default, and network monitoring tools need elevated network privileges.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Add the required capabilities to your container:
|
||||
|
||||
- In docker-compose.yml:
|
||||
```yaml
|
||||
cap_add:
|
||||
- NET_RAW
|
||||
- NET_ADMIN
|
||||
- NET_BIND_SERVICE
|
||||
```
|
||||
- For docker run: `--cap-add=NET_RAW --cap-add=NET_ADMIN --cap-add=NET_BIND_SERVICE`
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
36
docs/docker-troubleshooting/mount-configuration-issues.md
Normal file
36
docs/docker-troubleshooting/mount-configuration-issues.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Mount Configuration Issues
|
||||
|
||||
## Issue Description
|
||||
|
||||
NetAlertX has detected configuration issues with your Docker volume mounts. These may include write permission problems, data loss risks, or performance concerns marked with ❌ in the table.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
Improper mount configurations can lead to data loss, performance degradation, or security vulnerabilities. For persistent data (database and configuration), using non-persistent storage like tmpfs can result in complete data loss on container restart. For temporary data, using persistent storage may unnecessarily expose sensitive logs or cache data.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This occurs when your Docker Compose or run configuration doesn't properly map host directories to container paths, or when the mounted volumes have incorrect permissions. The application requires specific paths to be writable for operation, and some paths should use persistent storage while others should be temporary.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Review and correct your volume mounts in docker-compose.yml:
|
||||
|
||||
- Ensure `${NETALERTX_DB}` and `${NETALERTX_CONFIG}` use persistent host directories
|
||||
- Ensure `${NETALERTX_API}`, `${NETALERTX_LOG}` have appropriate permissions
|
||||
- Avoid mounting sensitive paths to non-persistent filesystems like tmpfs for critical data
|
||||
- Use bind mounts with proper ownership (netalertx user: 20211:20211)
|
||||
|
||||
Example volume configuration:
|
||||
```yaml
|
||||
volumes:
|
||||
- ./data/db:/data/db
|
||||
- ./data/config:/data/config
|
||||
- ./data/log:/tmp/log
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
27
docs/docker-troubleshooting/network-mode.md
Normal file
27
docs/docker-troubleshooting/network-mode.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Network Mode Configuration
|
||||
|
||||
## Issue Description
|
||||
|
||||
NetAlertX is not running with `--network=host`. Bridge networking blocks passive discovery (ARP, NBNS, mDNS) and active scanning accuracy.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
Host networking is required for comprehensive network monitoring. Bridge mode isolates the container from raw network access needed for ARP scanning, passive discovery protocols, and accurate device detection. Without host networking, the application cannot fully monitor your network.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This occurs when your Docker configuration uses bridge networking instead of host networking. Network monitoring requires direct access to the host's network interfaces to perform passive discovery and active scanning.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Enable host networking mode:
|
||||
|
||||
- In docker-compose.yml, add: `network_mode: host`
|
||||
- For docker run, use: `--network=host`
|
||||
- Ensure the container has required capabilities: `--cap-add=NET_RAW --cap-add=NET_ADMIN --cap-add=NET_BIND_SERVICE`
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
36
docs/docker-troubleshooting/nginx-configuration-mount.md
Normal file
36
docs/docker-troubleshooting/nginx-configuration-mount.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Nginx Configuration Mount Issues
|
||||
|
||||
## Issue Description
|
||||
|
||||
You've configured a custom port for NetAlertX, but the required nginx configuration mount is missing or not writable. Without this mount, the container cannot apply your port changes and will fall back to the default port 20211.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
Running in read-only mode (as recommended) prevents the container from modifying its own nginx configuration. Without a writable mount, custom port configurations cannot be applied, potentially exposing the service on unintended ports or requiring fallback to defaults.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This occurs when you set a custom PORT environment variable (other than 20211) but haven't provided a writable mount for nginx configuration. The container needs to write custom nginx config files when running in read-only mode.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
If you want to use a custom port, create a bind mount for the nginx configuration:
|
||||
|
||||
- Create a directory on your host: `mkdir -p /path/to/nginx-config`
|
||||
- Add to your docker-compose.yml:
|
||||
```yaml
|
||||
volumes:
|
||||
- /path/to/nginx-config:/tmp/nginx/active-config
|
||||
environment:
|
||||
- PORT=your_custom_port
|
||||
```
|
||||
- Ensure it's owned by the netalertx user: `chown -R 20211:20211 /path/to/nginx-config`
|
||||
- Set permissions: `chmod -R 700 /path/to/nginx-config`
|
||||
|
||||
If you don't need a custom port, simply omit the PORT environment variable and the container will use 20211 by default.
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
86
docs/docker-troubleshooting/port-conflicts.md
Normal file
86
docs/docker-troubleshooting/port-conflicts.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Port Conflicts
|
||||
|
||||
## Issue Description
|
||||
|
||||
The configured application port (default 20211) or GraphQL API port (default 20212) is already in use by another service. This commonly occurs when you already have another NetAlertX instance running.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
Port conflicts prevent the application from starting properly, leaving network monitoring services unavailable. Running multiple instances on the same ports can also create configuration confusion and potential security issues if services are inadvertently exposed.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This error typically occurs when:
|
||||
|
||||
- **You already have NetAlertX running** - Another Docker container or devcontainer instance is using the default ports 20211 and 20212
|
||||
- **Port conflicts with other services** - Other applications on your system are using these ports
|
||||
- **Configuration error** - Both PORT and GRAPHQL_PORT environment variables are set to the same value
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
### Check for Existing NetAlertX Instances
|
||||
|
||||
First, check if you already have NetAlertX running:
|
||||
|
||||
```bash
|
||||
# Check for running NetAlertX containers
|
||||
docker ps | grep netalertx
|
||||
|
||||
# Check for devcontainer processes
|
||||
ps aux | grep netalertx
|
||||
|
||||
# Check what services are using the ports
|
||||
netstat -tlnp | grep :20211
|
||||
netstat -tlnp | grep :20212
|
||||
```
|
||||
|
||||
### Stop Conflicting Instances
|
||||
|
||||
If you find another NetAlertX instance:
|
||||
|
||||
```bash
|
||||
# Stop specific container
|
||||
docker stop <container_name>
|
||||
|
||||
# Stop all NetAlertX containers
|
||||
docker stop $(docker ps -q --filter ancestor=jokob-sk/netalertx)
|
||||
|
||||
# Stop devcontainer services
|
||||
# Use VS Code command palette: "Dev Containers: Rebuild Container"
|
||||
```
|
||||
|
||||
### Configure Different Ports
|
||||
|
||||
If you need multiple instances, configure unique ports:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- PORT=20211 # Main application port
|
||||
- GRAPHQL_PORT=20212 # GraphQL API port
|
||||
```
|
||||
|
||||
For a second instance, use different ports:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- PORT=20213 # Different main port
|
||||
- GRAPHQL_PORT=20214 # Different API port
|
||||
```
|
||||
|
||||
### Alternative: Use Different Container Names
|
||||
|
||||
When running multiple instances, use unique container names:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
netalertx-primary:
|
||||
# ... existing config
|
||||
netalertx-secondary:
|
||||
# ... config with different ports
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
27
docs/docker-troubleshooting/read-only-filesystem.md
Normal file
27
docs/docker-troubleshooting/read-only-filesystem.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Read-Only Filesystem Mode
|
||||
|
||||
## Issue Description
|
||||
|
||||
The container is running as read-write instead of read-only mode. This reduces the security hardening of the appliance.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
Read-only root filesystem is a security best practice that prevents malicious modifications to the container's filesystem. Running read-write allows potential attackers to modify system files or persist malware within the container.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This occurs when the Docker configuration doesn't mount the root filesystem as read-only. The application is designed as a security appliance that should prevent filesystem modifications.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Enable read-only mode:
|
||||
|
||||
- In docker-compose.yml, add: `read_only: true`
|
||||
- For docker run, use: `--read-only`
|
||||
- Ensure necessary directories are mounted as writable volumes (tmp, logs, etc.)
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
29
docs/docker-troubleshooting/running-as-root.md
Normal file
29
docs/docker-troubleshooting/running-as-root.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Running as Root User
|
||||
|
||||
## Issue Description
|
||||
|
||||
NetAlertX has detected that the container is running with root privileges (UID 0). This configuration bypasses all built-in security hardening measures designed to protect your system.
|
||||
|
||||
## Security Ramifications
|
||||
|
||||
Running security-critical applications like network monitoring tools as root grants unrestricted access to your host system. A successful compromise here could jeopardize your entire infrastructure, including other containers, host services, and potentially your network.
|
||||
|
||||
## Why You're Seeing This Issue
|
||||
|
||||
This typically occurs when you've explicitly overridden the container's default user in your Docker configuration, such as using `user: root` or `--user 0:0` in docker-compose.yml or docker run commands. The application is designed to run under a dedicated, non-privileged service account for security.
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Switch to the dedicated 'netalertx' user by removing any custom user directives:
|
||||
|
||||
- Remove `user:` entries from your docker-compose.yml
|
||||
- Avoid `--user` flags in docker run commands
|
||||
- Ensure the container runs with the default UID 20211:20211
|
||||
|
||||
After making these changes, restart the container. The application will automatically adjust ownership of required directories.
|
||||
|
||||
## Additional Resources
|
||||
|
||||
Docker Compose setup can be complex. We recommend starting with the default docker-compose.yml as a base and modifying it incrementally.
|
||||
|
||||
For detailed Docker Compose configuration guidance, see: [DOCKER_COMPOSE.md](https://github.com/jokob-sk/NetAlertX/blob/main/docs/DOCKER_COMPOSE.md)
|
||||
0
install/production-filesystem/app/log/IP_changes.log → docs/docker-troubleshooting/troubleshooting.md
Executable file → Normal file
0
install/production-filesystem/app/log/IP_changes.log → docs/docker-troubleshooting/troubleshooting.md
Executable file → Normal file
BIN
docs/img/@eaDir/device_details.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/device_details.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/devices_dark.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/devices_dark.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/devices_light.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/devices_light.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/devices_split.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/devices_split.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/events.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/events.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/help_faq.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/help_faq.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/maintenance.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/maintenance.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/network.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/network.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/presence.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/presence.png@SynoEAStream
Executable file
Binary file not shown.
BIN
docs/img/@eaDir/settings.png@SynoEAStream
Executable file
BIN
docs/img/@eaDir/settings.png@SynoEAStream
Executable file
Binary file not shown.
@@ -21,7 +21,7 @@ The app can be installed different ways, with the best support of the docker-bas
|
||||
|
||||
NetAlertX is fully supported in Docker environments, allowing for easy setup and configuration. Follow the official guide to get started:
|
||||
|
||||
- [Docker Installation Guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md)
|
||||
- [Docker Installation Guide](./DOCKER_INSTALLATION.md)
|
||||
|
||||
This guide will take you through the process of setting up NetAlertX using Docker Compose or standalone Docker commands.
|
||||
|
||||
|
||||
@@ -15,9 +15,22 @@
|
||||
<?php
|
||||
|
||||
require 'php/templates/header.php';
|
||||
|
||||
// check permissions
|
||||
$dbPath = "../db/app.db";
|
||||
$confPath = "../config/app.conf";
|
||||
// Use environment-aware paths with fallback to legacy locations
|
||||
$dbFolderPath = rtrim(getenv('NETALERTX_DB') ?: '/data/db', '/');
|
||||
$configFolderPath = rtrim(getenv('NETALERTX_CONFIG') ?: '/data/config', '/');
|
||||
|
||||
$dbPath = $dbFolderPath . '/app.db';
|
||||
$confPath = $configFolderPath . '/app.conf';
|
||||
|
||||
// Fallback to legacy paths if new locations don't exist
|
||||
if (!file_exists($dbPath) && file_exists('../db/app.db')) {
|
||||
$dbPath = '../db/app.db';
|
||||
}
|
||||
if (!file_exists($confPath) && file_exists('../config/app.conf')) {
|
||||
$confPath = '../config/app.conf';
|
||||
}
|
||||
|
||||
checkPermissions([$dbPath, $confPath]);
|
||||
?>
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
|
||||
// Size and last mod of DB ------------------------------------------------------
|
||||
|
||||
$nax_db = str_replace('front', 'db', getcwd()).'/app.db';
|
||||
$nax_wal = str_replace('front', 'db', getcwd()).'/app.db-wal';
|
||||
$nax_db_size = number_format((filesize($nax_db) / 1000000),2,",",".") . ' MB';
|
||||
$nax_wal_size = number_format((filesize($nax_wal) / 1000000),2,",",".") . ' MB';
|
||||
$nax_db_mod = date ("F d Y H:i:s", filemtime($nax_db));
|
||||
$dbBasePath = rtrim(getenv('NETALERTX_DB') ?: '/data/db', '/');
|
||||
$nax_db = $dbBasePath . '/app.db';
|
||||
$nax_wal = $dbBasePath . '/app.db-wal';
|
||||
$nax_db_size = file_exists($nax_db) ? number_format((filesize($nax_db) / 1000000),2,",",".") . ' MB' : '0 MB';
|
||||
$nax_wal_size = file_exists($nax_wal) ? number_format((filesize($nax_wal) / 1000000),2,",",".") . ' MB' : '0 MB';
|
||||
$nax_db_mod = file_exists($nax_db) ? date ("F d Y H:i:s", filemtime($nax_db)) : 'N/A';
|
||||
|
||||
|
||||
// Table sizes -----------------------------------------------------------------
|
||||
@@ -334,7 +335,7 @@ $db->close();
|
||||
var emptyArr = ['undefined', "", undefined, null];
|
||||
var selectedTab = 'tab_DBTools_id';
|
||||
|
||||
initializeTabs();
|
||||
// initializeTabs() is called in window.onload
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// delete devices with emty macs
|
||||
@@ -704,7 +705,7 @@ function renderLogs(customData) {
|
||||
window.onload = function asyncFooter() {
|
||||
renderLogs();
|
||||
|
||||
// initializeTabs();
|
||||
initializeTabs();
|
||||
|
||||
try {
|
||||
$("#lastCommit").append('<a href="https://github.com/jokob-sk/NetAlertX/commits" target="_blank"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/jokob-sk/netalertx/main?logo=github"></a>');
|
||||
|
||||
@@ -2,30 +2,60 @@
|
||||
|
||||
require '../server/init.php';
|
||||
|
||||
$logBasePath = rtrim(getenv('NETALERTX_LOG') ?: '/tmp/log', '/');
|
||||
|
||||
function resolveLogPath($path)
|
||||
{
|
||||
global $logBasePath;
|
||||
|
||||
if ($path === null || $path === '') {
|
||||
return $path;
|
||||
}
|
||||
|
||||
$placeholder = '__NETALERTX_LOG__';
|
||||
if (strpos($path, $placeholder) === 0) {
|
||||
return $logBasePath . substr($path, strlen($placeholder));
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
|
||||
// Function to render the log area component
|
||||
function renderLogArea($params) {
|
||||
global $logBasePath;
|
||||
|
||||
$fileName = isset($params['fileName']) ? $params['fileName'] : '';
|
||||
$filePath = isset($params['filePath']) ? $params['filePath'] : '';
|
||||
$textAreaCssClass = isset($params['textAreaCssClass']) ? $params['textAreaCssClass'] : '';
|
||||
$buttons = isset($params['buttons']) ? $params['buttons'] : [];
|
||||
$content = "";
|
||||
$fileSize = 0;
|
||||
|
||||
if (filesize($filePath) > 2000000) {
|
||||
$filePath = resolveLogPath($filePath);
|
||||
|
||||
if (!is_file($filePath)) {
|
||||
$content = "";
|
||||
$fileSizeMb = 0.0;
|
||||
} elseif (filesize($filePath) > 2000000) {
|
||||
$content = file_get_contents($filePath, false, null, -2000000);
|
||||
$fileSizeMb = filesize($filePath) / 1000000;
|
||||
} else {
|
||||
$content = file_get_contents($filePath);
|
||||
$fileSizeMb = filesize($filePath) / 1000000;
|
||||
}
|
||||
|
||||
// Prepare the download button HTML if filePath starts with /app
|
||||
// Prepare the download button HTML if filePath resides under the active log base path
|
||||
$downloadButtonHtml = '';
|
||||
if (strpos($filePath, '/app') === 0) {
|
||||
$logPrefix = $logBasePath . '/';
|
||||
if ($logPrefix !== '/' && strpos($filePath, $logPrefix) === 0) {
|
||||
$downloadName = basename($filePath);
|
||||
$downloadButtonHtml = '
|
||||
<span class="span-padding">
|
||||
<a href="' . htmlspecialchars(str_replace('/app/log/', '/php/server/query_logs.php?file=', $filePath)) . '" target="_blank">
|
||||
<a href="' . htmlspecialchars('/php/server/query_logs.php?file=' . rawurlencode($downloadName)) . '" target="_blank">
|
||||
<i class="fa fa-download"></i>
|
||||
</a>
|
||||
</span>';
|
||||
@@ -34,13 +64,7 @@ function renderLogArea($params) {
|
||||
// Prepare buttons HTML
|
||||
$buttonsHtml = '';
|
||||
$totalButtons = count($buttons);
|
||||
if ($totalButtons > 0) {
|
||||
$colClass = 12 / $totalButtons;
|
||||
// Use $colClass in your HTML generation or further logic
|
||||
} else {
|
||||
// Handle case where $buttons array is empty
|
||||
$colClass = 12;
|
||||
}
|
||||
$colClass = $totalButtons > 0 ? (12 / $totalButtons) : 12;
|
||||
|
||||
foreach ($buttons as $button) {
|
||||
$labelStringCode = isset($button['labelStringCode']) ? $button['labelStringCode'] : '';
|
||||
@@ -52,8 +76,7 @@ function renderLogArea($params) {
|
||||
</div>';
|
||||
}
|
||||
|
||||
|
||||
// Render the log area HTML
|
||||
// Render HTML
|
||||
$html = '
|
||||
<div class="log-area box box-solid box-primary">
|
||||
<div class="row logs-row col-sm-12 col-xs-12">
|
||||
@@ -63,7 +86,7 @@ function renderLogArea($params) {
|
||||
</div>
|
||||
<div class="row logs-row">
|
||||
<div class="log-file col-sm-6 col-xs-12">' . htmlspecialchars($filePath) . '
|
||||
<div class="logs-size">' . number_format((filesize($filePath) / 1000000), 2, ",", ".") . ' MB'
|
||||
<div class="logs-size">' . number_format($fileSizeMb, 2, ",", ".") . ' MB'
|
||||
. $downloadButtonHtml .
|
||||
'</div>
|
||||
</div>
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
"event": "askRestartBackend()"
|
||||
}
|
||||
],
|
||||
"fileName": "app.log",
|
||||
"filePath": "/app/log/app.log",
|
||||
"fileName": "app.log",
|
||||
"filePath": "__NETALERTX_LOG__/app.log",
|
||||
"textAreaCssClass": "logs"
|
||||
|
||||
},
|
||||
@@ -22,8 +22,8 @@
|
||||
"event": "logManage('app_front.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "app_front.log",
|
||||
"filePath": "/app/log/app_front.log",
|
||||
"fileName": "app_front.log",
|
||||
"filePath": "__NETALERTX_LOG__/app_front.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
@@ -33,8 +33,8 @@
|
||||
"event": "logManage('app.php_errors.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "app.php_errors.log",
|
||||
"filePath": "/app/log/app.php_errors.log",
|
||||
"fileName": "app.php_errors.log",
|
||||
"filePath": "__NETALERTX_LOG__/app.php_errors.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
@@ -44,15 +44,19 @@
|
||||
"event": "logManage('execution_queue.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "execution_queue.log",
|
||||
"filePath": "/app/log/execution_queue.log",
|
||||
"fileName": "execution_queue.log",
|
||||
"filePath": "__NETALERTX_LOG__/execution_queue.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('nginx-error.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "nginx/error.log",
|
||||
"filePath": "/var/log/nginx/error.log",
|
||||
"fileName": "nginx-error.log",
|
||||
"filePath": "__NETALERTX_LOG__/nginx-error.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
@@ -62,8 +66,8 @@
|
||||
"event": "logManage('db_is_locked.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "db_is_locked.log",
|
||||
"filePath": "/app/log/db_is_locked.log",
|
||||
"fileName": "db_is_locked.log",
|
||||
"filePath": "__NETALERTX_LOG__/db_is_locked.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
@@ -73,8 +77,8 @@
|
||||
"event": "logManage('stdout.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "stdout.log",
|
||||
"filePath": "/app/log/stdout.log",
|
||||
"fileName": "stdout.log",
|
||||
"filePath": "__NETALERTX_LOG__/stdout.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
@@ -84,8 +88,30 @@
|
||||
"event": "logManage('stderr.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "stderr.log",
|
||||
"filePath": "/app/log/stderr.log",
|
||||
"fileName": "stderr.log",
|
||||
"filePath": "__NETALERTX_LOG__/stderr.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('IP_changes.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "IP_changes.log",
|
||||
"filePath": "__NETALERTX_LOG__/IP_changes.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
},
|
||||
{
|
||||
"buttons": [
|
||||
{
|
||||
"labelStringCode": "Maint_PurgeLog",
|
||||
"event": "logManage('crond.log', 'cleanLog')"
|
||||
}
|
||||
],
|
||||
"fileName": "crond.log",
|
||||
"filePath": "__NETALERTX_LOG__/crond.log",
|
||||
"textAreaCssClass": "logs logs-small"
|
||||
}
|
||||
]
|
||||
@@ -13,8 +13,35 @@
|
||||
// $DBFILE = dirname(__FILE__).'/../../../db/app.db';
|
||||
// $DBFILE_LOCKED_FILE = dirname(__FILE__).'/../../../log/db_is_locked.log';
|
||||
$scriptDir = realpath(dirname(__FILE__)); // Resolves symlinks to the actual physical path
|
||||
$DBFILE = $scriptDir . '/../../../db/app.db';
|
||||
$DBFILE_LOCKED_FILE = $scriptDir . '/../../../log/db_is_locked.log';
|
||||
$legacyDbPath = $scriptDir . '/../../../db/app.db';
|
||||
$legacyLogDir = $scriptDir . '/../../../log';
|
||||
|
||||
$dbFolderPath = rtrim(getenv('NETALERTX_DB') ?: '/data/db', '/');
|
||||
$logFolderPath = rtrim(getenv('NETALERTX_LOG') ?: '/tmp/log', '/');
|
||||
|
||||
// Fallback to legacy layout if the new location is missing but the legacy file still exists
|
||||
if (!is_dir($dbFolderPath) && file_exists($legacyDbPath)) {
|
||||
$dbFolderPath = dirname($legacyDbPath);
|
||||
}
|
||||
|
||||
if (!is_dir($dbFolderPath)) {
|
||||
@mkdir($dbFolderPath, 0775, true);
|
||||
}
|
||||
|
||||
$DBFILE = rtrim($dbFolderPath, '/') . '/app.db';
|
||||
if (!file_exists($DBFILE) && file_exists($legacyDbPath)) {
|
||||
$DBFILE = $legacyDbPath;
|
||||
}
|
||||
|
||||
if (!is_dir($logFolderPath) && is_dir($legacyLogDir)) {
|
||||
$logFolderPath = $legacyLogDir;
|
||||
}
|
||||
|
||||
if (!is_dir($logFolderPath)) {
|
||||
@mkdir($logFolderPath, 0775, true);
|
||||
}
|
||||
|
||||
$DBFILE_LOCKED_FILE = rtrim($logFolderPath, '/') . '/db_is_locked.log';
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -39,8 +66,10 @@ function SQLite3_connect($trytoreconnect = true, $retryCount = 0) {
|
||||
if (!file_exists($DBFILE)) {
|
||||
die("Database file not found: $DBFILE");
|
||||
}
|
||||
if (!file_exists(dirname($DBFILE_LOCKED_FILE))) {
|
||||
die("Log directory not found: " . dirname($DBFILE_LOCKED_FILE));
|
||||
|
||||
$lockDir = dirname($DBFILE_LOCKED_FILE);
|
||||
if (!is_dir($lockDir) && !@mkdir($lockDir, 0775, true)) {
|
||||
die("Log directory not found and could not be created: $lockDir");
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +159,7 @@ class CustomDatabaseWrapper {
|
||||
$message = 'Error executing query (attempts: ' . $attempts . '), query: ' . $query;
|
||||
// write_notification($message);
|
||||
error_log("Query failed after {$this->maxRetries} attempts: " . $this->sqlite->lastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
public function query_log_add($query)
|
||||
@@ -187,7 +217,7 @@ function OpenDB($DBPath = null) {
|
||||
|
||||
if (strlen($DBFILE) == 0) {
|
||||
$message = 'Database not available';
|
||||
echo '<script>alert('.$message.')</script>';
|
||||
echo '<script>alert("'.$message.'")</script>';
|
||||
write_notification($message);
|
||||
|
||||
die('<div style="padding-left:150px">'.$message.'</div>');
|
||||
@@ -197,7 +227,7 @@ function OpenDB($DBPath = null) {
|
||||
$db = new CustomDatabaseWrapper($DBFILE);
|
||||
} catch (Exception $e) {
|
||||
$message = "Error connecting to the database";
|
||||
echo '<script>alert('.$message.'": ' . $e->getMessage() . '")</script>';
|
||||
echo '<script>alert("'.$message.': '.$e->getMessage().'")</script>';
|
||||
write_notification($message);
|
||||
die('<div style="padding-left:150px">'.$message.'</div>');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
ini_set('error_log', '../../log/app.php_errors.log'); // initializing the app.php_errors.log file for the maintenance section
|
||||
$logPath = rtrim(getenv('NETALERTX_LOG') ?: '/tmp/log', '/') . '/app.php_errors.log';
|
||||
ini_set('error_log', $logPath); // initializing the app.php_errors.log file for the maintenance section
|
||||
require dirname(__FILE__).'/../templates/globals.php';
|
||||
require dirname(__FILE__).'/db.php';
|
||||
require dirname(__FILE__).'/util.php';
|
||||
|
||||
@@ -18,7 +18,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
// Check if file parameter is provided
|
||||
if ($file) {
|
||||
// Define the folder where files are located
|
||||
$filePath = "/app/config/" . basename($file);
|
||||
$configRoot = getenv('NETALERTX_CONFIG') ?: '/data/config';
|
||||
$filePath = rtrim($configRoot, '/') . "/" . basename($file);
|
||||
|
||||
// Check if the file exists and is readable
|
||||
if (file_exists($filePath) && is_readable($filePath)) {
|
||||
|
||||
@@ -11,6 +11,8 @@ require dirname(__FILE__).'/../server/init.php';
|
||||
//------------------------------------------------------------------------------
|
||||
// Handle incoming requests
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
$configRoot = getenv('NETALERTX_CONFIG') ?: '/data/config';
|
||||
$apiRoot = getenv('NETALERTX_API') ?: '/tmp/api';
|
||||
// Get query string parameter ?file=settings_table.json
|
||||
$file = isset($_GET['file']) ? $_GET['file'] : null;
|
||||
|
||||
@@ -19,10 +21,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
// Define the folder where files are located
|
||||
if ($file == "workflows.json")
|
||||
{
|
||||
$filePath = "/app/config/" . basename($file);
|
||||
$filePath = rtrim($configRoot, '/') . "/" . basename($file);
|
||||
} else
|
||||
{
|
||||
$filePath = "/app/api/" . basename($file);
|
||||
$filePath = rtrim($apiRoot, '/') . "/" . basename($file);
|
||||
}
|
||||
|
||||
// Check if the file exists
|
||||
@@ -59,7 +61,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
|
||||
$file = $_GET['file'];
|
||||
$filePath = "/app/config/" . basename($file);
|
||||
$configRoot = getenv('NETALERTX_CONFIG') ?: '/data/config';
|
||||
$filePath = rtrim($configRoot, '/') . "/" . basename($file);
|
||||
|
||||
// Save new workflows.json (replace existing content)
|
||||
if (file_put_contents($filePath, json_encode($decodedData, JSON_PRETTY_PRINT))) {
|
||||
|
||||
@@ -16,8 +16,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
|
||||
// Check if file parameter is provided
|
||||
if ($file) {
|
||||
// Define the folder where files are located
|
||||
$filePath = "/app/log/" . basename($file);
|
||||
// Define the folder where files are located
|
||||
$logBasePath = rtrim(getenv('NETALERTX_LOG') ?: '/tmp/log', '/');
|
||||
$filePath = $logBasePath . '/' . basename($file);
|
||||
|
||||
// Check if the file exists
|
||||
if (file_exists($filePath)) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
require dirname(__FILE__).'/../templates/globals.php';
|
||||
require dirname(__FILE__).'/../templates/skinUI.php';
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
@@ -176,7 +177,10 @@ function checkPermissions($files)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
// check server/api_server/api_server_start.py for equivalents
|
||||
// equivalent: /messaging/in-app/write
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
function displayMessage($message, $logAlert = FALSE, $logConsole = TRUE, $logFile = TRUE, $logEcho = FALSE)
|
||||
{
|
||||
global $logFolderPath, $log_file, $timestamp;
|
||||
@@ -234,7 +238,10 @@ function displayMessage($message, $logAlert = FALSE, $logConsole = TRUE, $logFil
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
// check server/api_server/api_server_start.py for equivalents
|
||||
// equivalent: /logs/add-to-execution-queue
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Adds an action to perform into the execution_queue.log file
|
||||
function addToExecutionQueue($action)
|
||||
@@ -257,13 +264,17 @@ function addToExecutionQueue($action)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
// check server/api_server/api_server_start.py for equivalents
|
||||
// equivalent: /logs DELETE
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
function cleanLog($logFile)
|
||||
{
|
||||
global $logFolderPath, $timestamp;
|
||||
|
||||
$path = "";
|
||||
|
||||
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', 'app.php_errors.log', 'execution_queue.log', 'db_is_locked.log'];
|
||||
$allowedFiles = ['app.log', 'app_front.log', 'IP_changes.log', 'stdout.log', 'stderr.log', 'app.php_errors.log', 'execution_queue.log', 'db_is_locked.log', 'nginx-error.log', 'crond.log'];
|
||||
|
||||
if(in_array($logFile, $allowedFiles))
|
||||
{
|
||||
@@ -312,7 +323,7 @@ function saveSettings()
|
||||
|
||||
$txt = $txt."#-----------------AUTOGENERATED FILE-----------------#\n";
|
||||
$txt = $txt."# #\n";
|
||||
$txt = $txt."# Generated: ".$timestamp." #\n";
|
||||
$txt = $txt."# Generated: ".$timestamp." #\n";
|
||||
$txt = $txt."# #\n";
|
||||
$txt = $txt."# Config file for the LAN intruder detection app: #\n";
|
||||
$txt = $txt."# https://github.com/jokob-sk/NetAlertX #\n";
|
||||
@@ -321,7 +332,12 @@ function saveSettings()
|
||||
|
||||
// collect all groups
|
||||
|
||||
$decodedSettings = json_decode($SETTINGS, true);
|
||||
$decodedSettings = json_decode((string)$SETTINGS, true);
|
||||
|
||||
if ($decodedSettings === null) {
|
||||
echo "Error: Invalid JSON in settings data.";
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($decodedSettings as $setting) {
|
||||
if( in_array($setting[0] , $groups) == false) {
|
||||
@@ -418,6 +434,10 @@ function saveSettings()
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
// check server/api_server/api_server_start.py for equivalents
|
||||
// equivalent: /graphql LangStrings endpoint
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
function getString ($setKey, $default) {
|
||||
|
||||
$result = lang($setKey);
|
||||
@@ -430,9 +450,14 @@ function getString ($setKey, $default) {
|
||||
return $default;
|
||||
}
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
// check server/api_server/api_server_start.py for equivalents
|
||||
// equivalent: /settings/<key>
|
||||
// 🔺----- API ENDPOINTS SUPERSEDED -----🔺
|
||||
function getSettingValue($setKey) {
|
||||
// Define the JSON endpoint URL
|
||||
$url = dirname(__FILE__).'/../../../api/table_settings.json';
|
||||
// Define the JSON endpoint URL
|
||||
$apiRoot = rtrim(getenv('NETALERTX_API') ?: '/tmp/api', '/');
|
||||
$url = $apiRoot . '/table_settings.json';
|
||||
|
||||
// Fetch the JSON data
|
||||
$json = file_get_contents($url);
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
|
||||
require dirname(__FILE__).'/../templates/globals.php';
|
||||
|
||||
function get_notification_store_path(): string {
|
||||
$apiRoot = getenv('NETALERTX_API') ?: '/tmp/api';
|
||||
return rtrim($apiRoot, '/') . '/user_notifications.json';
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
@@ -69,7 +74,7 @@ function generate_guid() {
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Logs a notification in in-app notification system
|
||||
function write_notification($content, $level = "interrupt") {
|
||||
$NOTIFICATION_API_FILE = '/app/api/user_notifications.json';
|
||||
$NOTIFICATION_API_FILE = get_notification_store_path();
|
||||
|
||||
// Generate GUID
|
||||
$guid = generate_guid();
|
||||
@@ -102,7 +107,7 @@ function write_notification($content, $level = "interrupt") {
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Removes a notification based on GUID
|
||||
function remove_notification($guid) {
|
||||
$NOTIFICATION_API_FILE = '/app/api/user_notifications.json';
|
||||
$NOTIFICATION_API_FILE = get_notification_store_path();
|
||||
|
||||
// Read existing notifications
|
||||
$notifications = json_decode(file_get_contents($NOTIFICATION_API_FILE), true);
|
||||
@@ -119,7 +124,7 @@ function remove_notification($guid) {
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Deletes all notifications
|
||||
function notifications_clear() {
|
||||
$NOTIFICATION_API_FILE = '/app/api/user_notifications.json';
|
||||
$NOTIFICATION_API_FILE = get_notification_store_path();
|
||||
|
||||
// Clear notifications by writing an empty array to the file
|
||||
file_put_contents($NOTIFICATION_API_FILE, json_encode(array()));
|
||||
@@ -128,7 +133,7 @@ function notifications_clear() {
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Mark a notification read based on GUID
|
||||
function mark_notification_as_read($guid) {
|
||||
$NOTIFICATION_API_FILE = '/app/api/user_notifications.json';
|
||||
$NOTIFICATION_API_FILE = get_notification_store_path();
|
||||
$max_attempts = 3;
|
||||
$attempts = 0;
|
||||
|
||||
@@ -177,7 +182,7 @@ function notifications_mark_all_read() {
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
function get_unread_notifications() {
|
||||
$NOTIFICATION_API_FILE = '/app/api/user_notifications.json';
|
||||
$NOTIFICATION_API_FILE = get_notification_store_path();
|
||||
|
||||
// Read existing notifications
|
||||
if (file_exists($NOTIFICATION_API_FILE) && is_readable($NOTIFICATION_API_FILE)) {
|
||||
|
||||
@@ -15,7 +15,19 @@ if (isset($_SESSION["login"]) && $_SESSION["login"] == 1) {
|
||||
|
||||
// Check if a valid cookie is present
|
||||
$CookieSaveLoginName = "NetAlertX_SaveLogin";
|
||||
$config_file = "../../../config/app.conf"; // depends on where this file is called from
|
||||
|
||||
// Use environment-aware config path
|
||||
$configFolderPath = rtrim(getenv('NETALERTX_CONFIG') ?: '/data/config', '/');
|
||||
$config_file = $configFolderPath . '/app.conf';
|
||||
|
||||
// Fallback to legacy path if new location doesn't exist
|
||||
if (!file_exists($config_file)) {
|
||||
$legacyPath = "../../../config/app.conf";
|
||||
if (file_exists($legacyPath)) {
|
||||
$config_file = $legacyPath;
|
||||
}
|
||||
}
|
||||
|
||||
$config_file_lines = file($config_file);
|
||||
$config_file_lines = array_values(preg_grep('/^SETPWD_password.*=/', $config_file_lines));
|
||||
$password_line = explode("'", $config_file_lines[0]);
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
// ## Global constants and TimeZone processing
|
||||
// ######################################################################
|
||||
|
||||
$configFolderPath = "/app/config/";
|
||||
$logFolderPath = "/app/log/";
|
||||
$configFolderPath = rtrim(getenv('NETALERTX_CONFIG') ?: '/data/config', '/') . '/';
|
||||
$logFolderPath = rtrim(getenv('NETALERTX_LOG') ?: '/tmp/log', '/') . '/';
|
||||
|
||||
$config_file = "app.conf";
|
||||
$workflows_file = "workflows.json";
|
||||
|
||||
@@ -674,7 +674,7 @@
|
||||
"Systeminfo_System_Uptime": "Uptime:",
|
||||
"Systeminfo_This_Client": "Aquest Client",
|
||||
"Systeminfo_USB_Devices": "Dispositius USB",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ S'han detectat punts muntatge antics. Ves a <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">aquesta guia</a> per migrar les noves <code>/app/config</code> i <code>/app/db</code> carpetes i al <code>netalertx</code> contenidor.",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ S'han detectat punts muntatge antics. Ves a <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">aquesta guia</a> per migrar les noves <code>/data/config</code> i <code>/data/db</code> carpetes i al <code>netalertx</code> contenidor.",
|
||||
"TIMEZONE_description": "Fus horari per mostrar les estadístiques correctament. <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" rel=\"nofollow\">aquí</a>.",
|
||||
"TIMEZONE_name": "Fus horari",
|
||||
"UI_DEV_SECTIONS_description": "Seleccioneu quins elements de la interfície d'usuari per ocultar a les pàgines de dispositius.",
|
||||
|
||||
16
front/php/templates/language/cs_cz.json
Executable file → Normal file
16
front/php/templates/language/cs_cz.json
Executable file → Normal file
@@ -9,7 +9,7 @@
|
||||
"About_Exit": "Odhlásit",
|
||||
"About_Title": "Scanner síťové bezpečnosti a framework pro upozornění",
|
||||
"AppEvents_AppEventProcessed": "Zpracováno",
|
||||
"AppEvents_DateTimeCreated": "Objeveno",
|
||||
"AppEvents_DateTimeCreated": "Zaznamenáno",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "",
|
||||
"AppEvents_Helper1": "",
|
||||
@@ -25,8 +25,8 @@
|
||||
"AppEvents_ObjectStatus": "",
|
||||
"AppEvents_ObjectStatusColumn": "",
|
||||
"AppEvents_ObjectType": "",
|
||||
"AppEvents_Plugin": "",
|
||||
"AppEvents_Type": "",
|
||||
"AppEvents_Plugin": "Zásuvný modul",
|
||||
"AppEvents_Type": "Typ",
|
||||
"BackDevDetail_Actions_Ask_Run": "",
|
||||
"BackDevDetail_Actions_Not_Registered": "",
|
||||
"BackDevDetail_Actions_Title_Run": "Spustit akci",
|
||||
@@ -74,7 +74,7 @@
|
||||
"DevDetail_DisplayFields_Title": "",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "",
|
||||
"DevDetail_EveandAl_AlertDown": "",
|
||||
"DevDetail_EveandAl_Archived": "",
|
||||
"DevDetail_EveandAl_Archived": "Archivováno",
|
||||
"DevDetail_EveandAl_NewDevice": "",
|
||||
"DevDetail_EveandAl_NewDevice_Tooltip": "",
|
||||
"DevDetail_EveandAl_RandomMAC": "",
|
||||
@@ -85,10 +85,10 @@
|
||||
"DevDetail_EveandAl_Title": "",
|
||||
"DevDetail_Events_CheckBox": "",
|
||||
"DevDetail_GoToNetworkNode": "",
|
||||
"DevDetail_Icon": "",
|
||||
"DevDetail_Icon": "Ikona",
|
||||
"DevDetail_Icon_Descr": "",
|
||||
"DevDetail_Loading": "",
|
||||
"DevDetail_MainInfo_Comments": "",
|
||||
"DevDetail_Loading": "Načítání…",
|
||||
"DevDetail_MainInfo_Comments": "Komentáře",
|
||||
"DevDetail_MainInfo_Favorite": "",
|
||||
"DevDetail_MainInfo_Group": "",
|
||||
"DevDetail_MainInfo_Location": "",
|
||||
@@ -761,4 +761,4 @@
|
||||
"settings_system_label": "",
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_tooltip": ""
|
||||
}
|
||||
}
|
||||
|
||||
4
front/php/templates/language/de_de.json
Executable file → Normal file
4
front/php/templates/language/de_de.json
Executable file → Normal file
@@ -9,7 +9,7 @@
|
||||
"About_Exit": "Abmelden",
|
||||
"About_Title": "Netzwerksicherheitsscanner und Benachrichtigungsframework",
|
||||
"AppEvents_AppEventProcessed": "Verarbeitet",
|
||||
"AppEvents_DateTimeCreated": "Entdeckt am",
|
||||
"AppEvents_DateTimeCreated": "Protokolliert",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "Anwendungsereignis-GUID",
|
||||
"AppEvents_Helper1": "Helfer 1",
|
||||
@@ -834,4 +834,4 @@
|
||||
"settings_system_label": "System",
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_tooltip": "Speichere die Änderungen, bevor Sie die Einstellungen testen."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@
|
||||
"Systeminfo_System_Uptime": "Uptime:",
|
||||
"Systeminfo_This_Client": "This Client",
|
||||
"Systeminfo_USB_Devices": "USB devices",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Old mount locations detected. Follow <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">this guide</a> to migrate to the new <code>/app/config</code> and <code>/app/db</code> folders and the <code>netalertx</code> container.",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Old mount locations detected. Follow <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">this guide</a> to migrate to the new <code>/data/config</code> and <code>/data/db</code> folders and the <code>netalertx</code> container.",
|
||||
"TIMEZONE_description": "Time zone to display stats correctly. Find your time zone <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" rel=\"nofollow\">here</a>.",
|
||||
"TIMEZONE_name": "Time zone",
|
||||
"UI_DEV_SECTIONS_description": "Select which UI elements to hide in the devices pages.",
|
||||
|
||||
@@ -734,7 +734,7 @@
|
||||
"Systeminfo_System_Uptime": "Tiempo de actividad:",
|
||||
"Systeminfo_This_Client": "Este cliente",
|
||||
"Systeminfo_USB_Devices": "Dispositivos USB",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Ubicaciones de montaje antiguas detectadas. Siga <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">esta guía</a> para migrar a las nuevas carpetas <code>/app/config</code> y <code>/app/db</code> y el contenedor <code>netalertx</code>.",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Ubicaciones de montaje antiguas detectadas. Siga <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">esta guía</a> para migrar a las nuevas carpetas <code>/data/config</code> y <code>/data/db</code> y el contenedor <code>netalertx</code>.",
|
||||
"TIMEZONE_description": "La zona horaria para mostrar las estadísticas correctamente. Encuentra tu zona horaria <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" rel=\"nofollow\">aquí</a>.",
|
||||
"TIMEZONE_name": "Zona horaria",
|
||||
"UI_DEV_SECTIONS_description": "Seleccione los elementos de la interfaz de usuario que desea ocultar en las páginas de dispositivos.",
|
||||
|
||||
4
front/php/templates/language/fa_fa.json
Executable file → Normal file
4
front/php/templates/language/fa_fa.json
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "",
|
||||
"API_CUSTOM_SQL_name": "",
|
||||
"API_CUSTOM_SQL_name": "مقصده سفارشی",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "",
|
||||
@@ -761,4 +761,4 @@
|
||||
"settings_system_label": "",
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_tooltip": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@
|
||||
"Systeminfo_System_Uptime": "Durée d'activité :",
|
||||
"Systeminfo_This_Client": "Ce client",
|
||||
"Systeminfo_USB_Devices": "Appareils USB",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Emplacement de point de montage obsolète détecté. Suivez <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">ce guide</a> pour migrer vers les nouveaux dossiers <code>/app/config</code> and <code>/app/db</code> et le container <code>netalertx</code>.",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Emplacement de point de montage obsolète détecté. Suivez <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">ce guide</a> pour migrer vers les nouveaux dossiers <code>/data/config</code> and <code>/data/db</code> et le container <code>netalertx</code>.",
|
||||
"TIMEZONE_description": "Fuseau horaire pour afficher correctement les statistiques. Trouvez votre fuseau horaire <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" rel=\"nofollow\">ici</a>.",
|
||||
"TIMEZONE_name": "Fuseau horaire",
|
||||
"UI_DEV_SECTIONS_description": "Slecetionnez quels éléments de l'interface graphique masquer dans les pages des appareils.",
|
||||
|
||||
@@ -674,7 +674,7 @@
|
||||
"Systeminfo_System_Uptime": "Tempo di attività:",
|
||||
"Systeminfo_This_Client": "Questo client",
|
||||
"Systeminfo_USB_Devices": "Dispositivi USB",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Rilevate vecchie posizioni di montaggio. Segui <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">questa guida</a> per migrare alle nuove cartelle <code> /app/config</code> e <code>/app/db</code> e al contenitore <code>netalertx</code>.",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Rilevate vecchie posizioni di montaggio. Segui <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">questa guida</a> per migrare alle nuove cartelle <code> /data/config</code> e <code>/data/db</code> e al contenitore <code>netalertx</code>.",
|
||||
"TIMEZONE_description": "Fuso orario per visualizzare correttamente le statistiche. Trova il tuo fuso orario <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" rel=\"nofollow\">qui</a>.",
|
||||
"TIMEZONE_name": "Fuso orario",
|
||||
"UI_DEV_SECTIONS_description": "Seleziona quali elementi della UI nascondere nella pagina dei dispositivi.",
|
||||
|
||||
@@ -674,7 +674,7 @@
|
||||
"Systeminfo_System_Uptime": "Oppetid:",
|
||||
"Systeminfo_This_Client": "Denne klienten",
|
||||
"Systeminfo_USB_Devices": "USB-enheter",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Eldre Mount-lokasjoner oppdaget. Følg <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">denne guiden</a> for å migrere til den nye <code>/app/config</code> og <code>/app/db </code> mappene og <code>netalertx</code> containeren.",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Eldre Mount-lokasjoner oppdaget. Følg <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">denne guiden</a> for å migrere til den nye <code>/data/config</code> og <code>/data/db </code> mappene og <code>netalertx</code> containeren.",
|
||||
"TIMEZONE_description": "Tidssone for å vise statistikk riktig. Finn din tidssone <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" rel=\"nofollow\">her</a>.",
|
||||
"TIMEZONE_name": "Tidssone",
|
||||
"UI_DEV_SECTIONS_description": "Velg hvilke UI -elementer du vil skjule på enhetssiden.",
|
||||
|
||||
@@ -674,7 +674,7 @@
|
||||
"Systeminfo_System_Uptime": "Czas pracy:",
|
||||
"Systeminfo_This_Client": "Ten klient",
|
||||
"Systeminfo_USB_Devices": "Urządzenia USB",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Wykryto stare lokalizacje montowania. Skorzystaj z <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">tego przewodnika</a>, aby przeprowadzić migrację do nowych folderów <code>/app/config</code> i <code>/app/db</code> oraz kontenera <code>netalertx</code>.",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Wykryto stare lokalizacje montowania. Skorzystaj z <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\">tego przewodnika</a>, aby przeprowadzić migrację do nowych folderów <code>/data/config</code> i <code>/data/db</code> oraz kontenera <code>netalertx</code>.",
|
||||
"TIMEZONE_description": "Ustaw strefę czasową, aby statystyki były wyświetlane poprawnie. Znajdź swoją strefę czasową <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" rel=\"nofollow\">tutaj</a>.",
|
||||
"TIMEZONE_name": "Strefa czasowa",
|
||||
"UI_DEV_SECTIONS_description": "Wybierz elementy interfejsu użytkownika (UI), które chcesz ukryć na stronach Urządzeń.",
|
||||
|
||||
14
front/php/templates/language/ru_ru.json
Executable file → Normal file
14
front/php/templates/language/ru_ru.json
Executable file → Normal file
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Вы можете указать собственный SQL-запрос, который будет генерировать файл JSON, а затем предоставлять его через конечную точку файла <a href=\"/php/server/query_json.php?file=table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code></a>.",
|
||||
"API_CUSTOM_SQL_name": "Пользовательская конечная точка",
|
||||
"API_TOKEN_description": "API-токен для безопасной связи. Сгенерируйте его или введите любое значение. Он передается в заголовке запроса и используется в плагине <code>SYNC</code>, сервере GraphQL и других конечных точках API. Вы можете использовать конечные точки API для создания пользовательских интеграций, как описано в <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">документации по API</a>.",
|
||||
"API_TOKEN_name": "API токен",
|
||||
"API_TOKEN_description": "API-токен для безопасной связи. Сгенерируйте его или введите любое значение. Он передаётся в заголовке запроса и используется в плагине <code>SYNC</code>, сервере GraphQL и других конечных точках API. Вы можете использовать конечные точки API для создания пользовательских интеграций, как описано в <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/API.md\" target=\"_blank\">документации по API</a>.",
|
||||
"API_TOKEN_name": "API-токен",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Разработан для:",
|
||||
@@ -57,8 +57,8 @@
|
||||
"BackDevices_Restore_CopError": "Исходную базу данных сохранить не удалось.",
|
||||
"BackDevices_Restore_Failed": "Восстановление не удалось. Пожалуйста, восстановите резервную копию вручную.",
|
||||
"BackDevices_Restore_okay": "Восстановление выполнено успешно.",
|
||||
"BackDevices_darkmode_disabled": "Темный режим отключен",
|
||||
"BackDevices_darkmode_enabled": "Темный режим включен",
|
||||
"BackDevices_darkmode_disabled": "Тёмный режим отключён",
|
||||
"BackDevices_darkmode_enabled": "Тёмный режим включен",
|
||||
"CLEAR_NEW_FLAG_description": "Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, станут неотмеченными, если лимит времени, указанный в часах, превышает время их <b>первой сессии</b>.",
|
||||
"CLEAR_NEW_FLAG_name": "Удалить новый флаг",
|
||||
"CustProps_cant_remove": "Невозможно удалить, необходимо хотя бы одно свойство.",
|
||||
@@ -127,7 +127,7 @@
|
||||
"DevDetail_Run_Actions_Tooltip": "Выполнить действие на текущем устройстве из раскрывающегося списка.",
|
||||
"DevDetail_SessionInfo_FirstSession": "Первый сеанс",
|
||||
"DevDetail_SessionInfo_LastIP": "Последний IP",
|
||||
"DevDetail_SessionInfo_LastSession": "Последний оффлайн",
|
||||
"DevDetail_SessionInfo_LastSession": "Посл. не в сети",
|
||||
"DevDetail_SessionInfo_StaticIP": "Статический IP",
|
||||
"DevDetail_SessionInfo_Status": "Статус",
|
||||
"DevDetail_SessionInfo_Title": "Информация о сеансе",
|
||||
@@ -674,7 +674,7 @@
|
||||
"Systeminfo_System_Uptime": "Время работы:",
|
||||
"Systeminfo_This_Client": "Этот клиент",
|
||||
"Systeminfo_USB_Devices": "USB-устройства",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Обнаружены устаревшие местоположения. Следуйте этому руководству <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\"></a>, чтобы перейти на новые <code>/app/config</code> и <code>/app/db</code> папки и контейнер <code>netalertx</code>.",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "⚠ Обнаружены устаревшие местоположения. Следуйте этому руководству <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/MIGRATION.md\" target=\"_blank\"></a>, чтобы перейти на новые <code>/data/config</code> и <code>/data/db</code> папки и контейнер <code>netalertx</code>.",
|
||||
"TIMEZONE_description": "Часовой пояс для корректного отображения статистики. Найдите свой часовой пояс <a target=\"_blank\" href=\"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\" rel=\"nofollow\">здесь</a>.",
|
||||
"TIMEZONE_name": "Часовой пояс",
|
||||
"UI_DEV_SECTIONS_description": "Выберите, какие элементы интерфейса нужно скрыть на страницах «Устройства».",
|
||||
@@ -761,4 +761,4 @@
|
||||
"settings_system_label": "Система",
|
||||
"settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. <b>Проверка не выполняется.</b>",
|
||||
"test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки."
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user