SYSLOG-Tools(at)Work consists of two Python programs, SYSLOG Receiver and SYSLOG Sender, each with its own web interface. This document describes the architecture, protocol handling, security mechanisms, installation model and interfaces, and is written for operations, security review and further development.
1. Purpose and scope
Product |
SYSLOG-Tools(at)Work 2.0.0 |
Components |
SYSLOG Receiver ( |
Use |
Testing, troubleshooting, demonstration and training in syslog (UDP and TLS 1.3), and validation of syslog configuration in network equipment and servers |
Not intended for |
Long-term storage, SIEM or log archiving. The receiver keeps messages in memory only. |
Target platforms |
Rocky Linux 9 / RHEL 9 / AlmaLinux 9 (primary), Debian 12, Ubuntu 22.04/24.04, Photon OS – on bare metal, VMware VM, Proxmox VE VM and Proxmox VE LXC |
Runtime model |
Ordinary Linux processes managed by systemd (no containers, no pip, no internet access) |
Languages |
English and Norwegian (Bokmål) in the web interfaces, server messages, manuals and installation scripts |
2. Architecture
2.1. Overview
senders (network equipment, servers, SYSLOG Sender)
│ UDP 514 │ TLS 1.3 / TCP 6514
▼ ▼
┌───────────────────────────── syslog-receiver.service ─────────────────────────────┐
│ UDP thread ─┐ TLS listener ─► one thread per connection │
│ ├─► parse (RFC 3164/5424) ─► ring buffer (deque, 2000) + statistics │
│ │ ▲ │
│ HTTP server (ThreadingHTTPServer, 8080) ───────┘ /api/messages, /api/stats … │
│ ├─ login, CSRF, Host check (WebSecurityMixin) │
│ ├─ certificate API (CertAPIMixin) ──► /opt/syslog-tools/certs │
│ └─ HTML/JS page + manual (EN/NO) │
└────────────────────────────────────────────────────────────────────────────────────┘
┌───────────────────────────── syslog-sender.service ───────────────────────────────┐
│ HTTP server (8000) ─► /send ─► SyslogHTTPConfigurator ─► UDP socket / TLS 1.3 │
│ └─► RepeatJob (background thread, fixed rate, stoppable) │
│ certificate API (shared code) ─► /opt/syslog-tools/certs │
│ command line: python3 sender.py -d … -m … (without web) │
└────────────────────────────────────────────────────────────────────────────────────┘
2.2. Code modules
| File | Lines (approx.) | Contents |
|---|---|---|
|
1,650 |
|
|
1,600 |
|
|
820 |
Network helpers (IPv4/IPv6, dual stack), |
|
700 |
Shared user interface: theme (CSS), navbar, footer, tabs, logout, certificates tab, logs tab, the |
|
540 |
Norwegian dictionary for the user interface ( |
There are no dependencies outside the Python standard library. The minimum Python version is 3.7, checked with vermin.
2.3. Process and thread model
-
Receiver: one process. One thread reads UDP (
recvfromin a loop), one thread accepts TLS connections, and each TLS connection gets its own thread (daemon threads). HTTP is handled byThreadingHTTPServer(one thread per request). Shared data (buffer and statistics) is protected by a singlethreading.Lock. -
Sender: one process with
ThreadingHTTPServer. Single messages are sent in the request thread (serialised withsingle_lock). Repeated sending runs in a separateRepeatJobthread with its own socket. Only one job can run at a time (job_lock).
3. Protocols
3.1. Receiving (Receiver)
UDP (RFC 5426) |
One message per datagram, up to 65,535 bytes. No |
TLS (RFC 5425) |
TLS 1.3 only ( |
Client certificate |
Optional ( |
Limits |
256 concurrent TLS connections, 32 per source address, 15 s to complete the handshake, 600 s idle time ( |
3.1.1. Parsing
-
<PRI>(0–191) gives facility = PRI ÷ 8 and severity = PRI mod 8. If PRI is missing or invalid, USER.NOTICE is used and the message is markedNO-PRI(RFC 3164 §4.3.3). -
RFC 5424:
1 TIMESTAMP HOST APP PROCID MSGID SD [MSG]. Structured data is parsed with quotes and escape characters (\",\],\\), and any BOM in front of the message is removed. -
RFC 3164:
Mmm dd hh:mm:ssor ISO timestamp, then host andTAG[PID]:. In practice all parts are optional.
Fields in a parsed message: id, received_at, source_ip, transport, tls_version, tls_cipher, client_cn, facility, severity, rfc_type, timestamp, hostname, app_name, procid, msgid, structured_data, message, raw.
3.1.2. Buffer and live view
Messages are kept in a collections.deque(maxlen=N) (default 2000, --buffer). The browser polls /api/messages?since=<last id> every second and receives only new messages. An "epoch" (start_token-clear_count) tells the browser whether the buffer was cleared or the service restarted, so that the whole list is reloaded. Statistics are fetched every two seconds. A new request is sent only when the previous one has finished, so requests do not pile up on slow links.
3.2. Sending (Sender)
RFC 3164 |
|
RFC 5424 |
|
MAC address |
RFC 3164: |
UDP |
The address is resolved once per socket. Optional source address ( |
TLS 1.3 |
|
Repeated sending |
Messages are scheduled against the start time ( |
4. Web interface
4.1. Structure
Each page is a single self-contained HTML document, assembled by the program on the first request and then cached. Shared parts from syslog_ui.py are inserted through placeholders: {{THEME_CSS}}, {{NAVBAR}}, {{FOOTER}}, {{I18N_JS}}, {{FETCH_JS}}, {{APP_JS}}, {{CERT_PANEL}}, {{CERT_JS}}, {{LOG_PANEL}}, {{LOG_JS}}, {{APP_TITLE}}, {{APP_ICON}}, {{HOSTNAME}}, {{VERSION}} and {{DEFAULT_LANG}}.
The pages load no external resources and use no JavaScript libraries. The icons are inline SVG drawings, and the arrow in the drop-down lists is an embedded SVG (data: URI).
Design |
The same visual language as SNMP-Trap-Tools(at)Work: navbar |
Tabs |
|
Message table |
One |
Logout |
HTTP Basic has no logout. The Log out button sends an |
Logs |
|
Manual |
|
4.2. Language (i18n)
Source language |
English. All texts are written in English in HTML/JS and translated with |
Static text |
At start-up |
Dynamic text |
|
Language switch |
Listeners ( |
Storage |
|
Server messages |
|
Default language |
|
Local formats |
Time of day with |
4.3. HTTP API
See the User Manual, chapter 8, for all endpoints. All responses are JSON (application/json; charset=utf-8), and state-changing calls are POST.
5. Security
5.1. Access control in the web layer
Login |
HTTP Basic, user |
CSRF |
POST requires the header |
DNS rebinding |
|
Clickjacking etc. |
|
XSS |
All text from the network (syslog messages, file names, certificate fields) is escaped before it is inserted into HTML. |
File selection |
TLS files selected in the browser must be located directly in the certificate directory ( |
Upload |
Max 1 MiB, file names matching |
Download |
Files that contain a private key can never be downloaded. |
Certificate generation |
|
Read-only mode |
|
5.2. Process isolation (systemd)
User |
|
Privileges |
|
Profile |
|
Profile |
|
Profile selection |
|
SELinux |
|
5.3. Known limitations
-
The web interface uses plain HTTP (not HTTPS). Passwords and uploaded keys travel unencrypted over the network. Mitigation: a dedicated management network,
--admin-net, or a reverse proxy with TLS in front. -
HTTP Basic has no logout or session timeout (the browser remembers the login until it is closed).
-
UDP syslog is neither authenticated nor encrypted, and source addresses can be spoofed.
-
Messages are stored in memory only.
6. Installation and file layout
6.1. Installed layout
| Path | Owner/mode | Contents |
|---|---|---|
|
root 755 |
|
|
root 755 |
|
|
syslog-tools 600 |
Password for the web interface |
|
root 755 |
The same for the sender |
|
syslog-tools 750 |
Certificates and keys (600), |
|
root 644 |
Service |
|
root 644 |
Service |
6.2. The installer
install.sh runs through 8 steps: prerequisites, user and directories, program files, certificates, systemd, start (with fallback to basic), firewall and verification. It can be run again as many times as you like (idempotent): choices from install.conf become defaults, passwords and certificates are kept, and the services are restarted.
The verification sends a test message over UDP and looks for it with /api/messages.
Platform detection (lib/common.sh):
-
/etc/os-release(read in a subshell) →OS_FAMILY= rhel / debian / photon / suse / other -
systemd-detect-virt→VIRT= none / vmware / kvm / lxc …, andIS_CONTAINER -
firewall: active
firewalld→firewall-cmd, activeufw→ufw, otherwise no change
6.3. Upgrading from 1.x
When /opt/syslog-infrastructure exists and the new certificate directory is empty, the certificates are copied and the paths in receiver-tls.json are rewritten. The web passwords are copied. The service names are the same as before and are overwritten. The programs also look for the old certificate directory if the new one is missing (LEGACY_ROOT).
7. Configuration
7.1. Receiver – command line
| Option | Default | Description |
|---|---|---|
|
0.0.0.0 |
Listen address ( |
|
514 |
UDP port |
|
8080 / 0.0.0.0 |
Web interface |
|
2000 |
Messages in memory |
|
off |
Do not write every message to the journal |
|
TLS at start-up (overridden by |
|
|
600 |
Seconds before an idle TLS connection is closed |
|
/opt/syslog-tools/certs |
Certificate directory |
|
Read-only / ignore saved TLS settings |
|
|
Create a test PKI and exit |
|
|
Login and host names |
|
|
en |
Default language of the web interface ( |
7.2. Sender – command line
--http, --port, --http-bind, --lang, --auth-file, --no-auth, --allowed-host, --cert-dir and --no-cert-upload control web mode. -d, -s, -t, -p, -m, --rfc, --facility, --severity, --hostname, --app, --mac, --procid, --msgid, --repeat, --duration and --tls- control command-line mode. In web mode --tls- are used as defaults in the form.
7.3. Stored state
|
TLS settings from the web interface ( |
|
The choices from the installation ( |
The browser |
|
8. Operations
-
Log: the Logs tab in the web interface (last 2000 lines), or
journalctl -u syslog-receiver/-u syslog-sender. Every message (unless--quietis used), every TLS connection, every failed handshake and every certificate change is logged in English. -
Monitoring:
GET /api/stats(requires login) returns counters and status (udp_status,tls_status). -
Resource usage: A message typically takes 1–2 KiB of memory, so the default buffer of 2000 messages uses only a few MiB. The whole process typically uses 20–40 MiB RAM. CPU usage grows with the message rate. At high traffic
--quietshould be used, because writing to the journal otherwise dominates. -
Backup:
/opt/syslog-tools/certsand theweb-passwordfiles. Everything else can be reinstalled from the package.
9. Quality assurance
See Revisjonsrapport.md (audit report, Norwegian) for code review, security assessment and test results.