Add LubeLogger app

This commit is contained in:
okxlin
2026-07-28 04:08:52 +08:00
parent 218c0c1f1d
commit 1b5b413ced
11 changed files with 394 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
PANEL_APP_PORT_HTTP=8080
LUBELOGGER_ROOT_USERNAME=admin
LUBELOGGER_ROOT_PASSWORD=LubeLogger_Admin_2026!
TIME_ZONE=Etc/UTC
APP_DATA_DIR=./data
CONTAINER_NAME=
+86
View File
@@ -0,0 +1,86 @@
additionalProperties:
formFields:
- default: 8080
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: Port
labelZh: 端口
label:
en: Port
zh: 端口
zh-Hant:
ja: ポート
ko: 포트
ru: Порт
ms: Port
pt-br: Porta
required: true
rule: paramPort
type: number
- default: admin
edit: true
envKey: LUBELOGGER_ROOT_USERNAME
labelEn: Root Username
labelZh: 根管理员用户名
label:
en: Root Username
zh: 根管理员用户名
zh-Hant: 根管理員使用者名稱
ja: ルート管理者ユーザー名
ko: 루트 관리자 사용자 이름
ru: Имя корневого администратора
ms: Nama Pengguna Pentadbir Root
pt-br: Nome do Administrador Raiz
required: true
rule: paramCommon
type: text
- default: LubeLogger_Admin_2026!
edit: true
envKey: LUBELOGGER_ROOT_PASSWORD
labelEn: Root Password
labelZh: 根管理员密码
label:
en: Root Password
zh: 根管理员密码
zh-Hant: 根管理員密碼
ja: ルート管理者パスワード
ko: 루트 관리자 비밀번호
ru: Пароль корневого администратора
ms: Kata Laluan Pentadbir Root
pt-br: Senha do Administrador Raiz
random: true
required: true
rule: paramComplexity
type: password
- default: Etc/UTC
edit: true
envKey: TIME_ZONE
labelEn: Time Zone
labelZh: 时区
label:
en: Time Zone
zh: 时区
zh-Hant: 時區
ja: タイムゾーン
ko: 시간대
ru: Часовой пояс
ms: Zon Masa
pt-br: Fuso Horario
required: true
type: text
- default: ./data
edit: true
envKey: APP_DATA_DIR
labelEn: Data Directory
labelZh: 数据目录
label:
en: Data Directory
zh: 数据目录
zh-Hant: 資料目錄
ja: データディレクトリ
ko: 데이터 디렉터리
ru: Каталог данных
ms: Direktori Data
pt-br: Diretorio de Dados
required: true
type: text
+1
View File
@@ -0,0 +1 @@
+46
View File
@@ -0,0 +1,46 @@
services:
lubelogger:
image: "ghcr.io/hargata/lubelogger:v1.7.0@sha256:01bdb486af71e641c3ae41499e0412a21f2e04fa31b25c5c6531b42c112938e5"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
init: true
user: "1000:1000"
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:8080"
env_file:
- path: "${APP_DATA_DIR}/.lubelogger-auth.env"
required: false
environment:
- HOME=/App/data
- TZ=${TIME_ZONE}
- ASPNETCORE_HTTP_PORTS=8080
- Kestrel__EndpointDefaults__Protocols=Http1
- DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2SUPPORT=false
- LUBELOGGER_LOCALE_OVERRIDE=en_US
- LUBELOGGER_LOCALE_DT_OVERRIDE=en_US
read_only: true
tmpfs:
- /tmp:size=64m,mode=1777
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
healthcheck:
test:
- CMD-SHELL
- >-
bash -lc 'exec 3<>/dev/tcp/127.0.0.1/8080; exec 3>&-; exec 3<&-'
interval: 30s
timeout: 5s
start_period: 15s
retries: 3
volumes:
- "${APP_DATA_DIR}:/App/data"
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
+123
View File
@@ -0,0 +1,123 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}"
read_env_value() {
local key="$1"
[[ -f "$ENV_FILE" ]] || return 0
local value
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
case "$value" in
\"*\") value="${value#\"}"; value="${value%\"}" ;;
\'*\') value="${value#\'}"; value="${value%\'}" ;;
esac
printf '%s\n' "$value"
}
configured_value() {
local key="$1"
local default_value="$2"
local value="${!key:-}"
if [[ -z "$value" ]]; then
value="$(read_env_value "$key")"
fi
printf '%s\n' "${value:-$default_value}"
}
reject_control_characters() {
local name="$1"
local value="$2"
if [[ "$value" == *$'\n'* || "$value" == *$'\r'* ]]; then
printf '%s must not contain line breaks\n' "$name" >&2
exit 1
fi
}
prepare_lubelogger() {
local raw path username password username_hash password_hash auth_file temp_file
raw="$(configured_value APP_DATA_DIR ./data)"
username="$(configured_value LUBELOGGER_ROOT_USERNAME admin)"
password="$(configured_value LUBELOGGER_ROOT_PASSWORD '')"
[[ -n "$raw" ]] || {
printf '%s\n' 'APP_DATA_DIR must not be empty' >&2
exit 1
}
if [[ "$raw" = /* ]]; then
printf '%s\n' 'APP_DATA_DIR must be relative to the application version directory' >&2
exit 1
fi
path="$(realpath -m -- "$ROOT_DIR/${raw#./}")"
case "$path" in
"$ROOT_DIR"/*) ;;
*)
printf '%s\n' 'APP_DATA_DIR must remain inside the application version directory' >&2
exit 1
;;
esac
install -d -m 0750 "$path"
path="$(realpath -e -- "$path")"
case "$path" in
"$ROOT_DIR"/*) ;;
*)
printf '%s\n' 'APP_DATA_DIR resolves outside the application version directory' >&2
exit 1
;;
esac
[[ -n "$username" && ${#username} -le 128 ]] || {
printf '%s\n' 'LUBELOGGER_ROOT_USERNAME must contain 1 to 128 characters' >&2
exit 1
}
[[ ${#password} -ge 12 && ${#password} -le 256 ]] || {
printf '%s\n' 'LUBELOGGER_ROOT_PASSWORD must contain 12 to 256 characters' >&2
exit 1
}
reject_control_characters LUBELOGGER_ROOT_USERNAME "$username"
reject_control_characters LUBELOGGER_ROOT_PASSWORD "$password"
username_hash="$(printf '%s' "$username" | sha256sum | cut -d ' ' -f 1)"
password_hash="$(printf '%s' "$password" | sha256sum | cut -d ' ' -f 1)"
[[ "$username_hash" =~ ^[0-9a-f]{64}$ && "$password_hash" =~ ^[0-9a-f]{64}$ ]] || {
printf '%s\n' 'Failed to generate LubeLogger credential hashes' >&2
exit 1
}
auth_file="$path/.lubelogger-auth.env"
if [[ -L "$auth_file" ]]; then
printf '%s\n' 'LubeLogger authentication file must not be a symbolic link' >&2
exit 1
fi
if [[ -e "$auth_file" && ! -f "$auth_file" ]]; then
printf '%s\n' 'LubeLogger authentication path must be a regular file' >&2
exit 1
fi
umask 077
temp_file="$(mktemp "$path/.lubelogger-auth.env.tmp.XXXXXX")"
trap 'rm -f -- "${temp_file:-}"' EXIT
printf '%s\n' \
'EnableAuth=true' \
"UserNameHash=$username_hash" \
"UserPasswordHash=$password_hash" \
'DisableRegistration=true' \
'LUBELOGGER_OPEN_REGISTRATION=false' >"$temp_file"
chmod 0600 "$temp_file"
chown 1000:1000 "$temp_file"
mv -f -- "$temp_file" "$auth_file"
trap - EXIT
chown 1000:1000 "$path"
chmod 0750 "$path"
[[ "$(stat -c '%a' -- "$auth_file")" = 600 ]] || {
printf '%s\n' 'LubeLogger authentication file permissions must be 0600' >&2
exit 1
}
}
prepare_lubelogger
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
docker-compose down --volumes
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
"$(dirname "$0")/init.sh"
+71
View File
@@ -0,0 +1,71 @@
# LubeLogger
## 产品介绍
LubeLogger 是一个自托管的车辆管理工具,用于记录车辆保养、维修、加油、里程、提醒、升级、税费、碰撞和相关文档。
## 主要功能
- 管理多辆车辆及其里程、燃油和费用记录
- 维护保养计划、提醒和历史记录
- 保存车辆图片、票据和其他文档
- 支持 CSV 导入导出、报表和可选的通知集成
## 访问说明
安装后通过 `http://<服务器 IP>:<端口>` 访问,并使用安装时设置的根管理员用户名和密码登录。安装脚本只把凭据的 SHA-256 哈希传给应用,默认启用认证并关闭开放注册和邀请注册页面。
上游根用户认证使用普通 SHA-256,而不是专用密码哈希算法;必须保留 1Panel 自动生成的高强度随机密码,不要使用短密码或复用密码。LubeLogger 1.7.0 的登录接口没有请求限速,认证 Cookie 也没有显式设置 `Secure``HttpOnly``SameSite`。明文 HTTP 端口只适合可信局域网;公网访问必须使用可信 HTTPS 反向代理、阻止公网直接访问应用端口,并在代理层增加登录限速。
## 数据持久化
`APP_DATA_DIR` 挂载到 `/App/data`,保存 LiteDB 数据库、图片、文档、配置和会话 DataProtection 密钥。该路径必须位于应用版本目录内,默认值为 `./data`;初始化脚本拒绝绝对路径、目录逃逸和认证文件符号链接,并把目录交给 UID/GID `1000:1000`。卸载脚本不会删除绑定目录中的用户数据,升级或迁移前仍应单独备份。
## 安全与漏洞说明
- 容器以 UID/GID `1000:1000` 运行,根文件系统只读,丢弃全部 Linux capabilities,并启用 `no-new-privileges`;CPU、内存和进程上限由 1Panel 的应用资源设置统一管理。应用只监听内部明文 HTTP/1;TLS 应由 1Panel 或其他可信反向代理终止。可选 WebHook、OIDC、SMTP 和通知集成默认未配置,包内同时禁用 .NET HTTP 客户端的 HTTP/2 支持。
- 对固定镜像执行的 2026-07-28 Trivy 扫描发现 `0` 个 Critical 和 `5` 个 High,均来自镜像中的 .NET 10.0.9,修复版本为 10.0.10。当前上游 v1.7.0 镜像尚未包含修复,应在上游发布使用 .NET 10.0.10 或更高版本的镜像后尽快更新。
- `CVE-2026-47302` 是 XML 加密解析导致的资源耗尽。LubeLogger 源码和默认依赖路径没有使用 `System.Security.Cryptography.Xml``System.Xml``EncryptedXml`,默认部署未发现可达入口。
- `CVE-2026-50524` 是畸形 TLS 握手导致的拒绝服务,`CVE-2026-50528``SslStream` 授权绕过。此包内 Kestrel 只提供 HTTP/1 明文服务,不处理入站 TLS;默认也未配置 OIDC、Webhook、SMTP 或通知等外部 TLS 集成。用户启用这些集成后应把远端视为额外风险边界。
- `CVE-2026-50651` 是 .NET HTTP/2 客户端处理 SETTINGS/PING ACK flood 时可能内存耗尽。LubeLogger 有可选的出站 HTTP 客户端路径,但此包通过 `DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2SUPPORT=false` 禁用 HTTP/2,并默认不配置相关集成。
- `CVE-2026-57108` 是解析特制 X.509 证书时的类型混淆拒绝服务。默认内部 HTTP 服务不解析入站证书;打开 Sponsors 页面或启用外部 TLS 集成时会产生出站证书解析路径,因此该项不能视为完全不可达。只连接可信端点,并在修复镜像可用后立即升级。
## Introduction
LubeLogger is a self-hosted vehicle management application for tracking maintenance, repairs, fuel, mileage, reminders, upgrades, taxes, collisions, and related documents.
## Features
- Manage multiple vehicles and their mileage, fuel, and cost records
- Track maintenance plans, reminders, and service history
- Store vehicle images, receipts, and other documents
- Import and export CSV data, generate reports, and configure optional notifications
## Access And Authentication
Access the service at `http://<server-ip>:<port>` and sign in with the root username and password selected during installation. The initialization script passes only SHA-256 credential hashes to the application. Authentication is enabled by default, while open registration and the invitation registration page are disabled.
Upstream root authentication uses plain SHA-256 rather than a password-specific KDF. Keep the high-entropy password generated by 1Panel; do not use a short or reused password. LubeLogger 1.7.0 does not rate-limit login requests, and its authentication cookie does not explicitly set `Secure`, `HttpOnly`, or `SameSite`. Direct plain-HTTP access is suitable only on a trusted LAN. For public access, use a trusted HTTPS reverse proxy, block public access to the application port, and add login rate limiting at the proxy.
## Data Persistence
`APP_DATA_DIR` is mounted at `/App/data` and stores the LiteDB database, images, documents, configuration, and DataProtection session keys. It must remain inside the application version directory and defaults to `./data`. The initializer rejects absolute paths, directory escapes, and a symlinked authentication file, then assigns the directory to UID/GID `1000:1000`. Uninstall does not remove bind-mounted user data; back it up before upgrades or migration.
## Security And Vulnerability Notes
- The container runs as UID/GID `1000:1000`, uses a read-only root filesystem, drops all Linux capabilities, and enables `no-new-privileges`. CPU, memory, and process limits are managed through 1Panel's application resource settings. The application serves internal plain HTTP/1 only; terminate TLS at 1Panel or another trusted reverse proxy. Optional webhook, OIDC, SMTP, and notification integrations are not configured, and .NET HTTP client HTTP/2 support is disabled.
- A 2026-07-28 Trivy scan of the pinned image found 0 Critical and 5 High findings, all in .NET 10.0.9. The fixes are in .NET 10.0.10. Upstream v1.7.0 has not yet published an image with those fixes; update promptly when it does.
- `CVE-2026-47302` is an XML-encryption parsing resource-exhaustion issue. LubeLogger source and default dependencies do not use `System.Security.Cryptography.Xml`, `System.Xml`, or `EncryptedXml`, so no default reachable entry point was found.
- `CVE-2026-50524` is a malformed TLS-handshake denial of service, and `CVE-2026-50528` is an `SslStream` authorization bypass. Kestrel serves only internal plain HTTP/1 in this package and does not process inbound TLS. OIDC, webhook, SMTP, and notification integrations are also unconfigured by default. Enabling them adds a separate outbound TLS risk boundary.
- `CVE-2026-50651` is an HTTP/2 client SETTINGS/PING ACK flood that may cause an out-of-memory condition. LubeLogger has optional outbound HTTP client paths, but this package sets `DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP2SUPPORT=false` and leaves those integrations unconfigured.
- `CVE-2026-57108` is a type-confusion denial of service while parsing a crafted X.509 certificate. The internal HTTP service does not parse inbound certificates. Opening the Sponsors view or enabling outbound TLS integrations does create certificate-parsing paths, so this finding is not considered completely unreachable. Connect only to trusted endpoints and upgrade as soon as a fixed image is available.
## References
- Project: <https://github.com/hargata/lubelog>
- Release: <https://github.com/hargata/lubelog/releases/tag/v1.7.0>
- Container source: <https://github.com/hargata/lubelog/blob/v1.7.0/Dockerfile>
- Deployment documentation: <https://docs.lubelogger.com/Installation/Getting%20Started>
- Configuration documentation: <https://docs.lubelogger.com/Advanced/Environment%20Variables>
- License: <https://github.com/hargata/lubelog/blob/v1.7.0/LICENSE> (MIT)
- .NET advisories: <https://github.com/advisories/GHSA-cvvh-rhrc-wg4q>, <https://github.com/advisories/GHSA-w7cw-xp7h-6j5j>, <https://github.com/advisories/GHSA-qvw7-jm5c-6hqw>, <https://github.com/advisories/GHSA-wp74-jgxh-gv4q>, <https://github.com/advisories/GHSA-rp2p-6cmp-jxj9>
+30
View File
@@ -0,0 +1,30 @@
name: LubeLogger
tags:
- Tool
title: 车辆维护、保养与油耗记录工具
description: 车辆维护、保养与油耗记录工具
additionalProperties:
key: lubelogger
name: LubeLogger
tags:
- Tool
shortDescZh: 车辆维护、保养与油耗记录工具
shortDescEn: Vehicle maintenance, service, and fuel mileage tracking
description:
en: Vehicle maintenance, service, and fuel mileage tracking
zh: 车辆维护、保养与油耗记录工具
zh-Hant: 車輛維護、保養與油耗記錄工具
ja: 車両の整備、サービス、燃費を記録するツール
ko: 차량 정비, 서비스 및 연비 기록 도구
ru: Учет обслуживания, ремонта и расхода топлива автомобилей
ms: Penjejakan penyelenggaraan, servis dan penggunaan bahan api kenderaan
pt-br: Controle de manutencao, servicos e consumo de veiculos
type: website
crossVersionUpdate: true
limit: 0
website: https://lubelogger.com/
github: https://github.com/hargata/lubelog
document: https://docs.lubelogger.com/
architectures:
- amd64
- arm64
+25
View File
@@ -0,0 +1,25 @@
LubeLogger logo
Source: https://github.com/hargata/lubelog/blob/v1.7.0/wwwroot/defaults/lubelogger_icon_192.png
License: MIT
Copyright (c) 2024 Hargata Softworks
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB