Skip to content

GUACAMOLE-2301: Add serial console protocol - #695

Open
ciroiriarte wants to merge 4 commits into
apache:mainfrom
ciroiriarte:feature/serial-protocol
Open

GUACAMOLE-2301: Add serial console protocol#695
ciroiriarte wants to merge 4 commits into
apache:mainfrom
ciroiriarte:feature/serial-protocol

Conversation

@ciroiriarte

@ciroiriarte ciroiriarte commented Jul 17, 2026

Copy link
Copy Markdown

Summary

Adds a new serial console protocol to guacd, implementing GUACAMOLE-2301. It brings serial-line consoles — network switches/routers, PDUs, out-of-band management ports, and VM virtual serial ports — into the browser using the existing guac_terminal, following the structure of the SSH and telnet protocols.

Capabilities

  • Local mode — guacd opens a local device node directly (e.g. /dev/ttyUSB0), guarded by an allowed-devices allowlist.
  • Network mode — reach a remote serial line over TCP (e.g. via ser2net), with the framing selected by network-protocol:
    • raw — transparent TCP byte pipe
    • rfc2217 — Telnet COM-Port-Option; negotiates baud/parity/etc. and can deliver a Send Break
    • telnet — base RFC 854 Telnet framing (e.g. QEMU telnet:, VMware ESXi telnet://)
  • Reverse (listen) mode — with reverse-connect=true, guacd binds a local port and accepts an inbound connection from the device instead of dialing out (QEMU/VMware virtual serial ports, dial-out console servers). Parameters: reverse-connect, bind-address (default 127.0.0.1), listen-timeout.
  • Serial line settings (baud rate, data/stop bits, parity, flow control); Send Break and DTR/RTS control lines from the browser; automatic reconnection; configurable line ending; local echo; paste pacing; and hangup-on-close.

RFC2217/telnet support is gated on libtelnet at build time and degrades gracefully to raw when it is unavailable.

Testing

Validated end-to-end through the web client against a real Juniper switch console and a QEMU/KVM virtual serial console — local, raw, rfc2217, telnet, and reverse mode — including bidirectional input and reconnection. Full QA evidence (screenshots, typescripts, guacd logs) is attached to GUACAMOLE-2301.

Coordinated PRs

This is one of three coordinated PRs:

…w TCP, RFC2217)

Adds a new "serial" terminal protocol plugin for browser access to serial
consoles (switch/router/PDU administration). Three transports select via the
serial-type/network-protocol parameters: a local tty device configured with
termios, raw TCP to a ser2net endpoint, and RFC2217 (telnet COM-PORT-OPTION,
compiled only when libtelnet is available via ENABLE_SERIAL_RFC2217).

Supports configurable send-break (break-duration) through a client-agnostic
serial-control pipe, paste pacing (paste-delay), and a device-path allowlist,
reusing the shared terminal for recording/typescript/clipboard/color-scheme,
mirroring the telnet/ipmi plugin structure.
…, and diagnostics support

Implements the reviewed serial console feature gaps on top of the initial
serial protocol plugin:

- Auto-reconnect on drop (new "auto-reconnect", default true): the terminal and
  scrollback are kept alive across reconnects; a single stream object persists
  for the session and its fd/telnet context is swapped under write_lock by
  guac_serial_stream_reopen(), so the input thread never touches a stale fd.
- Line-ending translation (new "line-ending": cr|lf|crlf, default cr) applied to
  typed Enter and pasted text via a small cross-buffer state machine.
- Distinct contention/error logging: EBUSY/EACCES/EPERM and TIOCEXCL-busy on
  local devices, ECONNREFUSED/ECONNRESET on network transports.
- Local echo (new "local-echo", default false).
- Structured connect/disconnect reason logging (EOF, EIO, reset, hangup).
- Hangup-on-close (new "hangup-on-close" -> HUPCL) and DTR/RTS control-line
  toggles via the serial-control pipe (dtr-on/off, rts-on/off), using
  TIOCMBIS/TIOCMBIC locally and RFC2217 SET-CONTROL (DTR 8/9, RTS 11/12).
- Connect status banner with an "8N1"-style summary and press-Enter hint.
- Interruptible paste-delay pacing so a long paste cannot stall teardown.

The device allowlist is retained in settings and re-validated (re-realpath) on
every local (re)open.
Add a reverse/listen mode for network serial connections: instead of
dialing out to a gateway, guacd binds a local TCP port and accepts a
single inbound connection from the device (e.g. a QEMU/KVM or VMware
virtual serial port, or a console server configured to dial out).

Network fd acquisition is factored into guac_serial_net_open_fd(), used
by both the raw and RFC2217 backends, which either dials out or, when
reverse-connect is set, binds/listens/accepts. The accepted socket feeds
the existing raw/RFC2217 framing unchanged, and the auto-reconnect path
re-listens for the next inbound connection on drop.

New parameters: reverse-connect, bind-address (default 127.0.0.1),
listen-timeout (default 60s). In reverse mode hostname is optional.
Add network-protocol=telnet: base RFC854 Telnet framing (IAC escaping,
BINARY/SGA/ECHO negotiation) via libtelnet, without the RFC2217 COM-PORT
option. Serial line settings are informational, as with raw. Intended for
endpoints that speak plain Telnet rather than RFC2217 -- QEMU/KVM telnet:
serial ports, VMware ESXi telnet:// virtual serial ports, and telnet-mode
console servers.

Reuses the existing libtelnet event handler and send/recv/free, and
acquires its socket through guac_serial_net_open_fd(), so it works in both
forward and reverse mode. A Send Break is delivered as the Telnet BRK
command. Gated on libtelnet (ENABLE_SERIAL_RFC2217) with no-op stubs when
libtelnet is absent.
@ciroiriarte
ciroiriarte force-pushed the feature/serial-protocol branch from 0e0a581 to 3d70f03 Compare August 9, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant