Skip to content

Releases

v2.8.0

Choose a tag to compare

@github-actions github-actions released this 04 Nov 08:31
030c6cd

ser2net v2.8.0 — Turkish web UI, Linux arm64, Windows service, Docker image, notifications, Modbus write + Sparkplug B, classic ser2net import (#28–#32)

Upgrading from 2.7.x

Nothing to migrate: replace the program (or pull the new image) and restart. config.json and data/ are used as they are.

  • Backups: the first configuration change keeps the old config.json in data/backups/.
  • Trace paths: a trace path in an old config becomes a file name under data/traces/, and the start-up log names the move. This is a security fix (below).
  • Docker: the image runs as an unprivileged user (uid 10001). A /data volume written by the old root image is taken over on its first start. The image is now on GHCR: ghcr.io/haliskilic/ser2net:2.8.0 (also 2.8 and latest), for amd64 + arm64. docker-compose.yml uses it.
  • Web UI language: English or Turkish, by the browser's language, unless a visitor picks TR / EN or the admin sets Settings → Web UI access → Default language.
  • Import: importing now shows a preview first. Scripts that post the 2.7-style one-step import still replace every mapping, as before.

Security

  • Updating is recommended: v2.7.1 ships dependency versions with known vulnerabilities. They are fixed here:
  • Traces can no longer write outside the data directory. A mapping's trace was a free file path, so an operator (not only an admin) could have network bytes appended to any file the service may write: config.json, a startup script, and as root in Docker. Traces now always go to <data>/traces/<mapping id>-<file name>.
  • The Docker image no longer runs as root.
  • Audit records can't be forged with control characters in a user-supplied name.

Added

  • Turkish web UI next to English. Logs, the audit log and the REST API stay English; notifications use the admin's default language.

  • USB identity: a mapping can find its device by VID:PID + serial number, so re-plugging an adapter as another ttyUSB* / COM* keeps it working.

    • The port list shows /dev/serial/by-id names, and they can be selected.
    • The kernel's placeholder ttyS ports without hardware are hidden.
  • Notifications by webhook (JSON, Slack/Mattermost, Microsoft Teams, Discord, Telegram) and/or e-mail (SMTP) when:

    • a serial device is lost or comes back;
    • a mapping fails to start;
    • clients connect or disconnect;
    • a sign-in fails.

    Repeats are suppressed and the rate is limited; Settings → Notifications can send a test message.

  • Dashboard: search, state filter, sort, and start / stop / restart of the selected mappings. The table is redrawn only when it changed, so it no longer flickers or loses the selection.

  • Traces in the UI: download a mapping's trace files (current + rotated), and a live hex view in the console with both directions and timestamps.

  • Modbus write from MQTT: points with "writable": true take values from <topic>/<point>/set.

    • Coils use FC5/FC15, holding registers FC6/FC16. The result goes to …/set/result.
    • Coils and discrete inputs (FC1/FC2) can be polled too.
  • Sparkplug B: a Modbus-polling mapping can be an edge node whose devices are the Modbus units it polls (unit1, unit2, …).

    • NBIRTH/NDEATH carry bdSeq; DBIRTH/DDATA carry seq.
    • Points are written through DCMD; NCMD triggers a rebirth.
    • No protobuf dependency.
  • Import from the classic ser2net: ser2net.yaml (4.x) and ser2net.conf (3.x) go through the import preview. Options without an equivalent are listed as warnings.

    • ser2net opens a device only while a client is connected, but a mapping here keeps it open. So of several ports on one device, the first comes in enabled and the others disabled.
  • Configuration backups (newest 50, download / restore; a restore can be undone), an import preview (merge or replace) and an audit log viewer (search, filters, CSV) in Settings.

  • Linux arm64 executable (ser2net-linux-arm64, glibc ≥ 2.28): Raspberry Pi 3/4/5 with a 64-bit OS, ARM gateways.

  • Windows service with no extra software: ser2net.exe --install-service / --uninstall-service.

    • It starts at boot and restarts after a failure; --service-name allows several instances.
  • Release integrity: SHA256SUMS, a CycloneDX SBOM per executable, and GitHub build-provenance and SBOM attestations.

  • --about: component versions for bug reports.

  • --licenses: the license texts of every bundled component.

  • --healthcheck: used by the Docker HEALTHCHECK.

  • SER2NET_LIB_OVERRIDE: loads a replacement ldap3 (LGPL).

Fixed

  • The session lifetime setting now takes effect: sessions always lasted 8 hours before. It is under Settings → Web UI access.
  • Writing a trace no longer blocks the event loop, and trace files rotate at a size limit (default 10 MB, 3 old files kept).
  • The Docker HEALTHCHECK no longer reports a fresh container unhealthy while it waits for the first-run setup.

Changed

  • Dependencies updated: starlette 1.10.0, uvicorn 0.54.0, websockets 17.4, python-multipart 0.0.33, anyio 4.16.0.
    • Python 3.10 keeps the last releases that support it.
    • The offline wheels in vendor/wheels/ match.
  • CI adds mypy, pip-audit, coverage and Dependabot, and main is protected.
  • New repository files: SECURITY.md, CONTRIBUTING.md, CHANGELOG.md.

Tested before publishing

  • Every PR runs the test suite on Linux and Windows × Python 3.10–3.13.
  • The executables are built and tested before they are attached. That includes the arm64 one, in 9 clean distributions each, and a real Windows service install / restart-after-crash / stop / uninstall.
  • The dashboard, the mapping views and the settings page are checked in a browser at 1440 → 390 px, in English and Turkish.
  • The Docker image is smoke-tested on amd64 and arm64, including the upgrade from a v2.7.1 volume.

Verify a download

sha256sum -c SHA256SUMS --ignore-missing
gh attestation verify ser2net-linux-x64 --repo haliskilic/ser2net

Türkçe özet

  • Türkçe arayüz: üst menüde TR / EN; seçilmemişse tarayıcının dili ya da admin'in varsayılan dili. Log'lar, audit log ve REST API İngilizce kalıyor.
  • Güncellemen önerilir: v2.7.1'deki starlette ve anyio sürümlerinde bilinen güvenlik açıkları var, bu sürümde kapandı.
  • Trace güvenlik düzeltmesi: trace dosyaları artık yalnızca data/traces/ altına yazılabiliyor. Eskiden bir operator herhangi bir dosyaya yazdırabiliyordu.
  • Yeni özellikler:
    • USB kimliğiyle cihaz bulma;
    • webhook ve e-posta bildirimleri;
    • panoda arama, filtre ve toplu işlem;
    • trace indirme ve canlı hex görünümü;
    • MQTT'den Modbus yazma;
    • Sparkplug B (her Modbus unit'i bir cihaz);
    • klasik ser2net.yaml / ser2net.conf içe aktarma;
    • config yedekleri ve geri yükleme;
    • içe aktarma önizlemesi;
    • audit log ekranı.
  • Dağıtım:
    • Linux arm64 binary'si;
    • ek program gerektirmeyen Windows servisi;
    • GHCR'de amd64 + arm64 Docker imajı (root olmayan kullanıcıyla);
    • SHA256SUMS, SBOM ve build provenance.
  • Yükseltme: v2.7.x'ten geçişte bir şey yapmana gerek yok. config.json ve data/ olduğu gibi kullanılıyor; ilk değişiklikte eski config data/backups/ içine yedekleniyor.

Downloads: ser2net-windows-x64.exe (Windows 10/11, Server 2016+) · ser2net-linux-x64 (x86_64, glibc ≥ 2.28) · ser2net-linux-arm64 (aarch64, glibc ≥ 2.28). They are standalone: nothing else to install. Docker: docker pull ghcr.io/haliskilic/ser2net:2.8.0.

v2.7.1

Choose a tag to compare

@github-actions github-actions released this 03 Nov 19:56
20ebbe7

ser2net v2.7.1 — long names in the web UI, truly standalone executables (#26)

Fixed

  • Long names no longer push the row buttons out of the web panel. Long mapping names, /dev/serial/by-id/… paths, remote host names and error messages used to make the mappings and cluster tables wider than their panel: the Start/Stop/…/Delete buttons sat outside it and the page scrolled sideways.
    • Long text now wraps at separators (/ _ . : -).
    • The row buttons wrap inside their cell in two groups, and stay on one line when there is room.
    • Errors are clamped to 3 lines, with the full text in the tooltip.
    • Below 940 px the lists become cards.
    • The top bar, the log and console headers and the forms also handle long names and phone screens.
  • The Linux executable runs on glibc ≥ 2.28. The v2.7.0 binary needed glibc 2.38 and did not start on Ubuntu 22.04/20.04, Debian 12/11 or RHEL/Alma/Rocky 8–9.
    • It is now built in an AlmaLinux 8 container with a python-build-standalone CPython.
    • It runs on RHEL/AlmaLinux/Rocky 8+, Debian 11+, Ubuntu 20.04+, Fedora and openSUSE Leap 15 (x86_64; not musl/Alpine — use Docker there).
    • It is also smaller: ~24 MB instead of ~34 MB.
  • "Generate self-signed certificate" no longer needs the openssl program; before, it never worked on Windows. The certificate is now made in-process with the bundled cryptography, with SAN localhost / 127.0.0.1 / ::1 / host name.
  • The Linux executable finds the distribution's CA certificates (Debian/Ubuntu, RHEL/Fedora, openSUSE and Alpine layouts) for certificate checks in MQTT over TLS and OIDC sign-in. Set SSL_CERT_FILE to override; the startup log names the bundle in use.
  • Windows hardening: icacls (data-folder permissions) is run by its full System32 path, so an icacls.exe planted next to the exe can't run instead.

Tested before publishing

From this release on, the executables are only attached after these checks pass on every PR and release:

  • the bundle needs nothing but OS-base libraries (glibc ≤ 2.28 / Windows system DLLs), and the VC++ runtime and Python are inside;
  • they run with an empty PATH (no Python, no openssl): web UI, TCP mapping, MQTT/LDAP/OIDC libraries, certificate generation, OIDC over certificate-checked HTTPS;
  • every library the running process loads comes from the bundle or the OS;
  • the Linux binary runs in clean AlmaLinux 8/9, Debian 11/12, Ubuntu 20.04/22.04/24.04, openSUSE Leap 15.6 and Fedora containers.

A browser test (Chromium, 1440 → 390 px) also guards the long-name layout.

Upgrading from 2.7.0

Nothing to migrate: replace the program and restart. config.json and data/ stay as they are. Coming from 2.6.x, see the v2.7.0 notes as well.

  • Linux binary: it unpacks itself to $TMPDIR (default /tmp) at start. If /tmp is mounted noexec, point TMPDIR at a directory that isn't.
  • Web UI: the mappings and cluster tables now have 7 columns: serial parameters under the port, mode/type under the address. Browsers fetch the new CSS by themselves (versioned asset URLs).
  • Log: the Linux binary logs TLS: using the system CA bundle … at start, or a warning when it finds none.

Türkçe özet

  • Web panelinde uzun eşleme adları, /dev/serial/by-id/… yolları ve hata mesajları artık butonları panelin dışına taşırmıyor; dar ekranlarda liste kart görünümüne geçiyor.
  • Linux binary'si artık glibc 2.28 ve üzeri her x86_64 dağıtımda çalışıyor; önceden glibc 2.38 istiyordu.
  • "Self-signed sertifika üret" harici openssl gerektirmiyor.
  • Linux binary'si dağıtımın CA sertifikalarını kendisi buluyor.
  • Binary'ler her PR'da ve her sürümde test ediliyor: boş PATH ile çalıştırma, yüklenen kütüphanelerin kaynağı ve 9 temiz dağıtım konteyneri. Yayın ancak bunlar geçince yapılıyor.

Downloads: ser2net-windows-x64.exe (Windows 10/11, Server 2016+) · ser2net-linux-x64 (x86_64, glibc ≥ 2.28) — standalone, nothing else to install.

v2.7.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 23:21
f19154f

ser2net v2.7.0 — connection lifecycle & optional login (#24)

Fixed

  • Dead TCP clients no longer stay ESTABLISHED forever. A client that vanished without closing (power cut, cable pull, Wi-Fi/VPN/NAT drop) kept its slot on a quiet raw bridge — and with max_connections = 1 every reconnect was refused with Busy. Every TCP data socket (server, connect-out, Modbus gateway) now uses TCP keepalive, on by default: a dead peer is dropped in ≈ 90 s (60 s idle + 3 × 10 s probes; configurable per mapping), also while the device keeps sending (Linux TCP_USER_TIMEOUT, when shorter than the kernel's ~15 min); pre-1709 Windows (e.g. Server 2016) is supported via SIO_KEEPALIVE_VALS. Verified with real half-open connections on Linux and Windows in CI.
  • Viewers can no longer open the mapping edit form or the mappings export, which expose stored MQTT credentials (now operator+); a viewer API token gets the MQTT password redacted.
  • 2.6.x configs with an unvalidated idle_timeout_s (-1, "300") keep booting (Docker/headless re-saves the config on start); such values are normalised.

New

  • Connect timeout for connect-out mappings (default 10 s, 0 = OS default) — covers the TCP and TLS handshake.
  • Max connection time per mapping (0 = unlimited, e.g. 86400 = 24 h).
  • Idle timeout now also applies to the Modbus gateway.
  • Every disconnect is logged with its reason (closed by peer, peer stopped responding, idle timeout, max connection time, kicked, …).
  • Optional web login: Settings → Web UI access — switch "Require login" off on trusted networks and choose the role visitors get (viewer / operator / admin). Signing in still works, the REST API still needs its token, open access applies only when the UI is reached by IP / localhost / its own host name (DNS-rebinding guard; behind a reverse proxy pass X-Forwarded-Host), other cluster nodes still need a real login, and open consoles close when access is revoked. Login stays required by default.
  • All of the above in the mapping form, REST API and JSON import.

Upgrading from 2.6.x

No config migration and no new dependencies: config.json (mappings, users, API token, cluster, TLS) is read as-is; new settings take their defaults. Back up the data/ folder, replace the program, restart:

  • Standalone binary: stop it/the service, replace ser2net(.exe), keep data/ next to it, start.
  • Source install / systemd: git pull (or unpack the new source) over the old one, then systemctl restart ser2net.
  • Docker: git pull && docker compose up -d --build — the /data volume is kept.
  • LAN cluster: upgrade every node; mixed versions keep working meanwhile.

Behaviour changes to be aware of:

  • TCP keepalive is on for every TCP mapping (that is the fix): a vanished peer is dropped after ≈ 90 s. To restore the old behaviour for a mapping, untick TCP keepalive (or "tcp_keepalive": false); for faster detection lower idle/interval/count.
  • Connect-out gives up a hanging attempt after 10 s and retries (was the OS default: ~21 s Windows / ~2 min Linux). For very slow links raise Connect timeout, or set 0.
  • Modbus gateway now honours Idle timeout — it was ignored there before; if a Modbus mapping has one set, masters that stay silent longer get disconnected.
  • Linux: a client that stops reading for longer than idle + interval × count while the device keeps sending is disconnected (TCP_USER_TIMEOUT).
  • Viewer role: no longer opens the mapping form or the export (403); a viewer API token sees the MQTT password as ********.
  • Log format: disconnect lines now end with — <reason>, and the startup line shows the keepalive setting — adjust any log parsers.
  • Login is still required by default; open access only if an admin turns it on.
  • Rolling back to 2.6.x is safe: it ignores the new keys (and drops them on its next save).

Türkçe özet

FIN/RST göndermeden kaybolan istemcilerin bağlantısı artık sonsuza dek ESTABLISHED kalmıyor: tüm TCP soketlerinde TCP keepalive varsayılan olarak açık (~90 sn'de temizlenir). Bunun yanında connect timeout, maksimum bağlantı süresi, Modbus gateway için idle timeout, kopma nedeni loglama ve isteğe bağlı web girişi (Ayarlar → Web UI access) geldi. Ayrıca viewer rolü artık MQTT parolası içeren düzenleme formunu ve dışa aktarmayı göremiyor.

Downloads: ser2net-windows-x64.exe · ser2net-linux-x64 (standalone, no Python needed).

v2.6.3

Choose a tag to compare

@github-actions github-actions released this 11 Jun 22:00
v2.6.3: RS-485 hardware auto-RTS in the mapping UI

v2.6.2

Choose a tag to compare

@github-actions github-actions released this 11 Jun 21:35
v2.6.2: review hardening — admin bind-IP validation, TLS e2e test, do…

v2.6.1

Choose a tag to compare

@github-actions github-actions released this 11 Jun 21:12
v2.6.1: cluster remote edit of a peer's mapping

v2.6.0

Choose a tag to compare

@github-actions github-actions released this 11 Jun 20:49
v2.6.0: cluster remote control + manual peers + per-node health

v2.5.0

Choose a tag to compare

@github-actions github-actions released this 11 Jun 19:36
v2.5.0: LAN cluster — auto-discovery + unified read-only fleet view

v2.4.0

Choose a tag to compare

@github-actions github-actions released this 11 Jun 16:17
v2.4.0: Modbus RTU<->TCP gateway, Modbus->MQTT, RBAC, LDAP/AD, standa…

v2.3.0 — REST API, theme, OIDC SSO

Choose a tag to compare

@haliskilic haliskilic released this 11 Jun 16:16

REST API (/api/v1) with role-scoped bearer tokens, light/dark theme toggle, and OIDC single sign-on (authorization-code flow). Standalone binaries begin at v2.4.0 (packaging landed after this milestone).