From 9e6a3f26c2b61158f1044280ef593c049b6d9879 Mon Sep 17 00:00:00 2001 From: Raj Nandan Sharma Date: Wed, 12 Mar 2025 21:30:06 +0530 Subject: [PATCH 1/3] refactor: clean up Dockerfile and improve security practices --- Dockerfile | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index dde01a6..31d5ef8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,10 +58,10 @@ COPY . . # TODO: Reevaluate permissions (possibly reduce?)... # Remove docs directory and ensure required directories exist RUN rm -rf src/routes/\(docs\) \ - static/documentation \ - static/fonts/lato/full && \ - mkdir -p uploads database && \ - # TODO: Consider changing below to `chmod -R u-rwX,g=rX,o= uploads database` + static/documentation \ + static/fonts/lato/full && \ + mkdir -p uploads database && \ + # TODO: Consider changing below to `chmod -R u-rwX,g=rX,o= uploads database` chmod -R 750 uploads database # Build the application and remove `devDependencies` @@ -78,15 +78,15 @@ RUN apt-get update && apt-get install -y \ iputils-ping=3:20221126-1+deb12u1 \ sqlite3=3.40.1-2+deb12u1 \ tzdata=2024b-0+deb12u1 \ - # TODO: Is it ok to change to `curl` here so that we don't have to maintain `wget` version mismatch between Debian architectures? (`curl` is only used for the container healthcheck and because there is an Alpine variant (best!) we probably don't care if the Debian image ends up building bigger due to `curl`.) - curl=7.88.1-10+deb12u8 && \ + # TODO: Is it ok to change to `curl` here so that we don't have to maintain `wget` version mismatch between Debian architectures? (`curl` is only used for the container healthcheck and because there is an Alpine variant (best!) we probably don't care if the Debian image ends up building bigger due to `curl`.) + curl=7.88.1-10+deb12u8 && \ rm -rf /var/lib/apt/lists/* FROM node:${ALPINE_VERSION} AS final-alpine RUN apk add --no-cache --update \ - iputils=20240905-r0 \ - sqlite=3.48.0-r0 \ - tzdata + iputils=20240905-r0 \ + sqlite=3.48.0-r0 \ + tzdata FROM final-${VARIANT} AS final @@ -120,25 +120,34 @@ COPY --chown=node:node --from=builder /app/main.js ./main.js COPY --chown=node:node --from=builder /app/openapi.json ./openapi.json COPY --chown=node:node --from=builder /app/openapi.yaml ./openapi.yaml +# Set capabilities for ping (before changing to non-root user) +RUN if [ -f "/etc/alpine-release" ]; then \ + # Alpine path + setcap cap_net_raw+ep /bin/ping; \ + else \ + # Debian path + setcap cap_net_raw+ep /usr/bin/ping; \ + fi + # Ensure necessary directories are writable VOLUME ["/uploads", "/database"] # Set container timezone and make entrypoint script executable RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \ chmod +x ./entrypoint.sh - # TODO: To improve security, consider dropping unnecessary capabilities instead of granting image all network capabilities of host. (Maybe `setcap cap_net_raw+p /usr/bin/ping`, etc.) Could also drop all and then grant only the capabilities that are explicitly needed. Some examples are commented out below... - # setcap cap_net_bind_service=+ep /usr/local/bin/node - # setcap cap_net_bind_service=+ep /usr/bin/ping - # setcap cap_net_bind_service=+ep /usr/bin/ping6 - # setcap cap_net_bind_service=+ep /usr/bin/tracepath - # setcap cap_net_bind_service=+ep /usr/bin/clockdiff + # TODO: To improve security, consider dropping unnecessary capabilities instead of granting image all network capabilities of host. (Maybe `setcap cap_net_raw+p /usr/bin/ping`, etc.) Could also drop all and then grant only the capabilities that are explicitly needed. Some examples are commented out below... + # setcap cap_net_bind_service=+ep /usr/local/bin/node + # setcap cap_net_bind_service=+ep /usr/bin/ping + # setcap cap_net_bind_service=+ep /usr/bin/ping6 + # setcap cap_net_bind_service=+ep /usr/bin/tracepath + # setcap cap_net_bind_service=+ep /usr/bin/clockdiff # Expose the application port EXPOSE $PORT # Add a healthcheck to the container; `wget` vs. `curl` depending on base image. Using this approach because `wget` does not actually maintain versioning across architectures, so we cannot pin a `wget` version (in above `final-debian` base, `apt-get install`) between differing architectures (e.g. arm64, amd64) HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ - CMD sh -c 'if [ -f "/etc/alpine-release" ]; then wget --quiet --spider http://localhost:$HEALTHCHECK_PORT$HEALTHCHECK_PATH || exit 1; else curl --silent --head --fail http://localhost:$HEALTHCHECK_PORT$HEALTHCHECK_PATH || exit 1; fi' + CMD sh -c 'if [ -f "/etc/alpine-release" ]; then wget --quiet --spider http://localhost:$HEALTHCHECK_PORT$HEALTHCHECK_PATH || exit 1; else curl --silent --head --fail http://localhost:$HEALTHCHECK_PORT$HEALTHCHECK_PATH || exit 1; fi' # TODO: Revisit letting user define $PUID & $PGID overrides (e.g. `addgroup -g $PGID newgroup && adduser -D -G newgroup -u $PUID node`) as well as potentially ensure no root user exists. (Make sure no processes are running as root, first!) # Use a non-root user (recommended for security) From 57d32197cf5a45ed3e225e3800a6715e76e7ea39 Mon Sep 17 00:00:00 2001 From: Raj Nandan Sharma Date: Wed, 12 Mar 2025 22:05:25 +0530 Subject: [PATCH 2/3] chore: update version to 3.2.3 and reflect changes in documentation and headers --- package.json | 2 +- src/lib/server/notification/webhook.js | 2 +- src/lib/server/startup.js | 24 ++++++++++++++++++++---- src/routes/(docs)/+layout.svelte | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 15b2213..27f8117 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kener", - "version": "3.2.2", + "version": "3.2.3", "private": false, "license": "MIT", "description": "Kener: An open-source Node.js status page application for real-time service monitoring, incident management, and customizable reporting. Simplify service outage tracking, enhance incident communication, and ensure a seamless user experience.", diff --git a/src/lib/server/notification/webhook.js b/src/lib/server/notification/webhook.js index c747de7..74b3ab3 100644 --- a/src/lib/server/notification/webhook.js +++ b/src/lib/server/notification/webhook.js @@ -13,7 +13,7 @@ class Webhook { constructor(trigger_meta, method, siteData, monitorData) { const kenerHeader = { "Content-Type": "application/json", - "User-Agent": "Kener/3.2.2", + "User-Agent": "Kener/3.2.3", }; let headers = trigger_meta.headers; this.trigger_meta = trigger_meta; diff --git a/src/lib/server/startup.js b/src/lib/server/startup.js index 0f53758..f7cd592 100644 --- a/src/lib/server/startup.js +++ b/src/lib/server/startup.js @@ -1,19 +1,32 @@ // @ts-nocheck import figlet from "figlet"; - import { Cron } from "croner"; - import { Minuter } from "./cron-minute.js"; import db from "./db/db.js"; import { GetAllSiteData, GetMonitorsParsed, HashString } from "./controllers/controller.js"; import { fileURLToPath } from "url"; -import { dirname } from "path"; +import { dirname, resolve } from "path"; +import fs from "fs"; const jobs = []; process.env.TZ = "UTC"; let isStartUP = true; +// Get the version from package.json +const getVersion = () => { + try { + const __filename = fileURLToPath(import.meta.url); + const __dirname = dirname(__filename); + const packagePath = resolve(__dirname, "../../../package.json"); + const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8")); + return packageJson.version; + } catch (error) { + console.error("Error reading version:", error); + return "unknown"; + } +}; + const scheduleCronJobs = async () => { // Fetch and map all active monitors, creating a unique hash for each const activeMonitors = (await GetMonitorsParsed({ status: "ACTIVE" })).map((monitor) => ({ @@ -72,12 +85,15 @@ async function Startup() { mainJob.trigger(); - figlet("Kener is UP!", function (err, data) { + const version = getVersion(); + + figlet("Kener v" + version, function (err, data) { if (err) { console.log("Something went wrong..."); return; } console.log(data); + console.log(`Kener version ${version} is running!`); }); } diff --git a/src/routes/(docs)/+layout.svelte b/src/routes/(docs)/+layout.svelte index 37e55f2..cc014c9 100644 --- a/src/routes/(docs)/+layout.svelte +++ b/src/routes/(docs)/+layout.svelte @@ -110,7 +110,7 @@ Kener Documentation - 3.2.2 + 3.2.3 From 3f9716b0a4abe9c66015a747f471bb9be24bd2fb Mon Sep 17 00:00:00 2001 From: Raj Nandan Sharma Date: Wed, 12 Mar 2025 22:48:53 +0530 Subject: [PATCH 3/3] fix: update donation links from GitHub Sponsors to Buy Me a Coffee --- src/routes/(docs)/+layout.svelte | 2 +- src/routes/(manage)/manage/(app)/+layout.svelte | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/routes/(docs)/+layout.svelte b/src/routes/(docs)/+layout.svelte index cc014c9..68eaaf3 100644 --- a/src/routes/(docs)/+layout.svelte +++ b/src/routes/(docs)/+layout.svelte @@ -202,7 +202,7 @@