Repository navigation
v2.8.1
A security release. 2.8.1 fixes 16 security issues in 2.8.0 and earlier, together with the bugs found alongside them. Upgrade every installation, and every node of a LAN cluster. Several fixes change behaviour on purpose: read Before you upgrade first.
Security advisories
| Advisory | Severity | Affected versions | Summary |
|---|---|---|---|
| GHSA-47f5-rwq9-8c9p | High | ≤ 2.8.0 | Unvalidated mapping ids and serial-port URLs allow file writes outside the data directory |
| GHSA-gxrq-f87q-xx96 | High | 2.3.0–2.8.0 | LDAP/OIDC group-to-role mapping matches substrings and can grant unintended roles |
| GHSA-9qqv-mrqj-4fpx | High | ≤ 2.8.0 | Unauthenticated requests can exhaust memory and push all other records out of the audit log |
| GHSA-g2wg-gpfm-g9fp | High | 2.3.0–2.8.0 | The Read-only option is not enforced for Modbus gateway mappings |
| GHSA-jm3r-8jxr-4wh4 | Medium | 2.8.0 | MQTT commands can write beyond the addressed Modbus point and bypass the Read-only option |
| GHSA-p65v-hqq3-cjr9 | High | 2.5.0–2.8.0 | Fleet-view proxies can send the cluster key to a host that is not a cluster node |
| GHSA-5mrw-593x-q839 | High | 2.3.0–2.8.0 | LDAPS and StartTLS connections do not verify the directory server's certificate |
| GHSA-p2cr-p4jh-x4rc | Medium | ≤ 2.8.0 | First-run setup has no host check; sessions survive sign-out, account re-creation and restore |
| GHSA-7f6v-672v-7mjm | Medium | 2.3.0–2.8.0 | LDAP/OIDC sign-ins can take over a same-named local or other-method account; OIDC gaps |
| GHSA-xcxp-4hgp-m666 | Medium | 2.8.0 | Classic ser2net import enables connections without their access protections |
| GHSA-w2p8-66v2-rgr7 | High | 2.5.0–2.8.0 | Cluster key is sent in clear on peer requests and can be redirected by replayed beacons |
| GHSA-wv6x-867g-475q | High | 2.8.0 | Windows service runs as LocalSystem from a location standard users may be able to modify |
| GHSA-cjp3-9g2v-4w69 | Medium | ≤ 2.8.0 | Unauthenticated connections can use up file descriptors or stop the process on Windows |
| GHSA-3wh8-pjmf-qfh5 | Medium | 2.3.0–2.8.0 | Viewers can see data sent to devices, including typed passwords, and download trace files |
| GHSA-jj9j-m939-wmmm | Medium | ≤ 2.8.0 | RFC 2217 clients can make ser2net buffer subnegotiation data without limit |
| GHSA-4wgx-6v57-4r26 | Medium | 2.0–2.8.0 | UDP mappings buffer serial writes without limit and let any allowed source take over output |
2.8.0's note "Traces can no longer write outside the data directory" was incomplete: the mapping id, which is part of the trace and log file names, was not validated. 2.8.1 validates it everywhere it enters (GHSA-47f5-rwq9-8c9p).
Before you upgrade
config.json and data/ are used as they are. Check what applies to you:
- LAN cluster: upgrade every node. Legacy authentication (on by default) keeps older nodes working meanwhile; once all run 2.8.1, turn it off on each node and change the cluster key, which older versions sent in clear text.
- LDAPS / StartTLS now check the directory's certificate. If this system doesn't trust its CA (private, AD CS or self-signed, typical on Linux and in Docker), set Settings → LDAP → CA certificate file (
ldap.ca_file), or LDAP sign-in stops. - LDAP / OIDC group settings match whole group names only; a sign-in under a local account's name is refused, and an LDAP and an OIDC account can no longer share a name (the method used last keeps it). An OIDC sign-in in progress during the upgrade fails once. Locked out?
ser2net --set-password NAMEcreates a local admin. - Viewers no longer see what is sent to devices or download traces; give the operator role to those who need them.
- Read-only Modbus mappings refuse writes from masters and from MQTT / Sparkplug; retained MQTT
/setcommands are no longer replayed (there is an opt-in to keep that). - Backup restore keeps the current accounts, passwords, API token and cluster key unless you choose otherwise.
- First-run setup through a reverse proxy or another host name asks for the code in
data/setup-code.txt. - Request bodies over 2 MB get HTTP 413 (imports: 16 MB).
- One ser2net per data directory: a second instance on the same data directory refuses to start.
- Monitoring:
bytes_in/bytes_outcount at the device now (a one-time level change); some sign-in log lines are worded differently. - Classic ser2net imports done with 2.8.0: re-check those mappings' TLS, allowed client IPs and direction.
- Admin UI connection limits: a connection that sends no complete request within 10 s (or then sends its body slower than about 1 KiB/s, or takes nothing of the response) is closed, and at most 64 connections per address and 256 in all are taken (optional
admin_ui.request_timeout_s,max_connections_per_ip,max_connectionsinconfig.json, 0 = no limit). Behind a reverse proxy everyone shares one address: raise the per-address limit there. - TLS mappings: a handshake must finish within 15 s; hosts not in the allow-list are closed before it; past 32 at once from one address, further connections wait for a slot.
- Windows keeps the selector event loop, which now refuses new connections near its 512-socket limit instead of stopping;
SER2NET_WINDOWS_LOOP=proactoris an opt-in alternative without that limit (not yet soak-tested with serial devices).
How to upgrade
- Standalone executable (Linux): replace the file and restart ser2net.
- Windows service: run the new
ser2net-windows-x64.exe --install-servicefrom an elevated prompt. It copies itself toC:\Program Files\ser2net\and upgrades the service in place, keeping its data directory. - Docker:
docker pull ghcr.io/haliskilic/ser2net:2.8.1and recreate the container; afterwards checkdocker logsforWARNING: config.json:lines (settings the container now leaves off instead of restart-looping). - Source install: update the files, then, with ser2net stopped, refresh the bundled packages in the install folder:
python3 -m pip install --target lib --upgrade --no-index --find-links vendor/wheels -r requirements.txt(an in-place update keeps the old ones inlib/).
Also in this release
- A serial device that stops taking data (CTS low, XOFF, a virtual port nobody reads) no longer freezes ser2net or hangs a mapping's stop.
- The Modbus gateway reopens a lost serial port instead of answering 0x0B until restarted.
- The standalone executables show the Turkish UI again and keep their web UI when temp cleaners run.
- A rejected setting no longer restart-loops Docker or blocks every save; bind-mounted
/datafolders from older images and serial devices on hosts wheredialoutisn't GID 20 work. - Fleet view: remote actions work for peers behind NAT or Docker, by host name or IPv6; non-ASCII cluster keys work.
- Active Directory direct bind with
user@domainorDOMAIN\userreads groups; OIDC tolerates small clock differences. - RFC 2217 clients survive malformed values and a reopened serial port; serial ports and MQTT keep working with more than 1024 files open, and the open-file limit is raised at start.
- Account recovery from the command line (
--set-password,--sign-out-all), session controls, cluster key generation and planned key changes, a fixed UDP reply address. - Dependencies: click 8.5.1, paho-mqtt 2.2.0, authlib 1.9.5.
Everything, with the upgrade notes in full: CHANGELOG.md.
Assets
| File | |
|---|---|
ser2net-linux-x64 |
Linux x86_64 executable (glibc ≥ 2.28) |
ser2net-linux-arm64 |
Linux arm64 executable (glibc ≥ 2.28; Raspberry Pi 3/4/5 with a 64-bit OS) |
ser2net-windows-x64.exe |
Windows x64 executable; --install-service runs it as a service |
*.cdx.json |
CycloneDX SBOM of each executable |
*.THIRD-PARTY-LICENSES.txt |
license texts of the components inside each executable |
SHA256SUMS |
SHA-256 checksums of all of the above |
Docker image: ghcr.io/haliskilic/ser2net:2.8.1 (also 2.8 and latest), linux/amd64 and linux/arm64.
Verify a download: sha256sum -c SHA256SUMS --ignore-missing, and the build provenance with gh attestation verify ser2net-linux-x64 -R haliskilic/ser2net (each executable also has an SBOM attestation; the image: gh attestation verify oci://ghcr.io/haliskilic/ser2net:2.8.1 -R haliskilic/ser2net). The Windows executable is not code-signed yet, so SmartScreen may warn; check it the same way (docs/WINDOWS.md).