Skip to content

Latest commit

History

27 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

logMaster

A self-hosted systemd journal log viewer with Authentik SSO authentication.

Overview

logMaster consists of two independent Flask/Gunicorn applications:

logMaster/
├── server/ # Web UI — Authentik OIDC auth, service tabs, log rendering
└── daemon/ # Log API — queries journalctl and returns JSON
Browser ──OIDC──► Authentik
│
▼
server (port 5000)
│ POST /logs (shared secret)
▼
daemon (port 5001)
│ subprocess
▼
journalctl

The server authenticates users via Authentik and renders log data in a browser UI. The daemon runs on any systemd host, exposes a single authenticated HTTP endpoint, and pipes requests into journalctl. Multiple daemons can be configured — one per host — each mapped to a set of services in config.json.


Prerequisites

RequirementNotes
Python 3.11+Both components
systemdDaemon host must run systemd (Linux only)
AuthentikAny reachable Authentik instance
rsyncUsed by setup.sh --install-service

Quick Start

1. Daemon

cd daemon
./setup.sh # create venv, install deps, copy .env.example → .env
nano .env # set LOG_API_SHARED_SECRETsource .venv/bin/activate
python daemon.py # dev server on port 5001

2. Server

cd server
./setup.sh # create venv, install deps, copy .env.example → .env
nano .env # fill in Authentik + shared secret values
nano config.json # add your servicessource .venv/bin/activate
python server.py # dev server on port 5000

Service Configuration

server/config.json defines which services appear as tabs in the UI.

{
"services": [
{
"name": "Nginx",
"service_name": "nginx.service",
"address": "http://192.168.1.10:5001"
},
{
"name": "Postgresql",
"service_name": "postgresql.service",
"address": "http://192.168.1.11:5001"
}
]
}
FieldDescription
nameDisplay name shown in the tab bar
service_nameExact systemd unit name passed to journalctl -u
addressURL of the daemon instance that hosts this service

The config is loaded once at server startup. Restart the server after editing it.


Systemd Deployment

Install both components as systemd services on their respective hosts.

Daemon host

cd daemon
sudo ./setup.sh --install-service

Server host

cd server
sudo ./setup.sh --install-service

Both scripts copy files to /root/logMaster/{daemon,server}/, install the service unit, and start it immediately.

After any update, copy the new files and run:

systemctl restart logMasterDaemon # on the daemon host
systemctl restart logMasterServer # on the server host

Tail logs:

journalctl -u logMasterDaemon -f
journalctl -u logMasterServer -f

Authentik Setup

  1. In Authentik, go to Applications → Providers → Create → OAuth2/OpenID Provider.
  2. Set the redirect URI to match AUTHENTIK_REDIRECT_URI in server/.env:
    http://your-host:5000/callback
    
  3. Copy the Client ID and Client Secret into server/.env.
  4. Create an Application linked to the provider and note the application slug — this is the value used in AUTHENTIK_CLIENT_ID.

Environment Variables

See server/.env.example and daemon/.env.example for full reference.

server/.env

VariableRequiredDescription
APP_SECRET_KEYYesFlask session signing key — use a long random string
AUTHENTIK_BASE_URLYesBase URL of your Authentik instance, e.g. https://auth.example.com
AUTHENTIK_CLIENT_IDYesOAuth2 application slug from Authentik
AUTHENTIK_CLIENT_SECRETYesOAuth2 client secret from Authentik
AUTHENTIK_REDIRECT_URIYesMust match the redirect URI registered in Authentik
LOG_API_SHARED_SECRETYesMust match the daemon's value
LOG_API_URLNoFallback daemon URL if a service has no address (default: http://127.0.0.1:5001)
APP_PORTNoPort to bind (default: 5000)
FLASK_DEBUGNoSet true for development only (default: false)

daemon/.env

VariableRequiredDescription
LOG_API_SHARED_SECRETYesShared secret — must match the server's value
LOG_API_PORTNoPort to bind (default: 5001)
FLASK_DEBUGNoSet true for development only (default: false)

Security Notes

  • The shared secret is the only authentication mechanism on the daemon endpoint. Use a strong random value and keep it out of version control.
  • The daemon validates the systemd unit name against a strict regex (^[\w.\-]+$) before passing it to journalctl — no shell interpolation is used.
  • Both systemd services run with NoNewPrivileges, PrivateTmp, and ProtectSystem=strict.
  • The daemon runs as root to access the journal. If you prefer an unprivileged user, add them to the systemd-journal group and remove the User=root line from the service file.

About

journald log daemon and viewer

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages