Remote Console Network Path¶
The remote console lets an operator open a shell, serial console, KVM or VM console on a machine from the portal with no network path of their own to it. This page lists every connection that makes that work: who opens it, to what, on which port, and with which credential. It is the page to read before writing firewall rules for the feature, and the place to start when a console fails to connect.
The connections¶
| From | To | Port | Opened by | Used for |
|---|---|---|---|---|
| Operator browser | Endpoint API | 8092 | Browser | Every streamed console |
| Operator browser | BMC web UI | 443 | Browser | BMC KVM link-out. DRP is not on this path. |
| Endpoint | BMC Redfish | ipmi/port-redfish, default 443 |
ipmi plugin | console-info for the two BMC consoles |
| Endpoint | guacd | 4822 on host loopback | dr-provision | Every streamed console |
| guacd | Machine sshd | 22 | guacd | SSH console |
| guacd | BMC sshd | 22 | guacd | BMC serial console |
| guacd | BMC VNC | ipmi/console-vnc-port |
guacd | BMC KVM, streamed |
| guacd | Hyper-V host | 2179 | guacd | Hyper-V console |
Only the first two rows leave the operator's network. Everything else originates on the endpoint host, and the last four rows leave it from inside the guacd container. See Container networking for what that crossing looks like on each runtime.
Browser to endpoint¶
The portal opens a websocket to the endpoint's API port:
wss://<endpoint>:8092/api/v3/guac/websocket-tunnel?console=<type>&machine=<uuid>&token=<token>
The query names the console type, the machine and the user's token. The portal adds
plugin for a BMC or Hyper-V console and the display size. Nothing else the browser sends
is honored: for a console request the endpoint drops every other parameter, so the browser
cannot name a host or supply a credential.
The endpoint checks that the token grants the guac action on that machine and that the
machine is in the caller's tenant, then resolves the console server side. No port other
than the API port needs to be open toward the operator.
Endpoint to the plugin: console-info¶
Before the endpoint dials guacd it asks the plugin that owns the console type what to
connect to, by running the machine's console-info action.
For the BMC consoles the ipmi plugin connects to the BMC over Redfish at ipmi/address
on ipmi/port-redfish and reads the Manager's serial console and graphical console
services. This is the one network dependency that exists before a console opens. If Redfish
is unreachable both BMC consoles come back unavailable with the reason
"unable to reach the BMC over Redfish at https://
For the Hyper-V console the hyper-v plugin composes the descriptor from hyper-v/uuid and
hyper-v/console-host. It does not probe the host.
The SSH console has no plugin. The endpoint connects to the machine's Address, which
means the machine must have been discovered or hold a lease. Without one the tunnel is
refused with "machine
Endpoint to guacd¶
guacd runs in the guacd-runner context as the guacd-service resource broker, which the
bootstrap-guacd task creates. The context is a container that the docker-context plugin
starts with the port publish rule 127.0.0.1:4822:4822, so port 4822 is reachable from the
host's loopback only. It is never opened on the host firewall and nothing off the host can
reach guacd.
dr-provision finds the address to dial from the broker's context/publish-ports param,
falling back to the context's publish-ports meta and then to 127.0.0.1:4822. It opens
a TCP connection, completes the guacd handshake with the protocol and target from the
descriptor and the credentials from the machine's params, and then relays bytes between
the websocket and guacd for the life of the session.
If the broker does not exist the portal hides the Remote button, and a tunnel request
is refused with "the guacd-service resource broker does not exist". If the broker exists
but the container is down the request fails with "cannot reach guacd at 127.0.0.1:4822";
the guacd-run job on the broker shows why.
Container networking¶
The container has its own network namespace, so guacd's last hop to the target crosses the container runtime's network on the way out of the host. Which network that is depends on the runtime and on who runs dr-provision.
The runtime. The docker-context plugin uses podman if it is on the path and
docker otherwise. It runs as the same user as dr-provision, because it is a child
process of it. dr-provision normally runs as root, which makes the containers rootful. A
non-root install, as described in the install guide, gets rootless containers.
What the plugin asks for. The container is created with the publish rule above and no
--network flag, so it lands on the runtime's default network. Any extra flags come from
the docker-context/startup-options param on the context. Inside, guacd-run starts
guacd with -b 0.0.0.0: it listens on every address in the container's namespace, and the
loopback-only property comes from the publish rule, not from guacd.
| Setup | Container network | What the targets see | Port 4822 on the host |
|---|---|---|---|
| Rootful podman 4 and later | netavark bridge, NAT | The host's address | Loopback only, from the publish rule |
| Rootful podman 3 | CNI bridge, NAT | The host's address | Loopback only |
| Docker | docker0 bridge, masquerade |
The host's address | Loopback only |
| Rootless podman 5 and later | pasta. No NAT: the namespace copies the address of the host's main interface | The host's address | Loopback only, forwarded by rootlessport or pasta |
| Rootless podman 4 | slirp4netns, user-mode NAT | The host's address | Loopback only, forwarded by rootlessport |
--network host through startup-options |
The host's own namespace | The host's address | Every interface. Publish rules are discarded, and guacd's 0.0.0.0 bind lands on the host. |
Two things hold in every row:
- Targets see connections from the endpoint host's address. Firewall rules on a BMC, a machine or a Hyper-V host allow the endpoint host, and nothing about the container is visible to them.
- Name resolution for
ipmi/addressandhyper-v/console-hosthappens inside the container, with the resolvers the runtime hands it from the host.
Host networking is the one setup that changes the security picture. With the
container in the host's namespace, guacd listens on 4822 on every host interface and the
publish rule that kept it on loopback is gone. dr-provision still dials 127.0.0.1:4822
and the consoles work, but 4822 has to be blocked on the host firewall. Do not add
--network host without that.
Targets on the host itself. From a bridge or pasta namespace, 127.0.0.1 is the
container, not the host. A target that listens on the endpoint host's loopback is
unreachable from guacd unless the container is on the host network or the target is
addressed through the runtime's host alias (host.containers.internal on podman). This
only comes up with test fixtures. The console-e2e rig runs as a host-networked pod for
this reason.
Rootless podman 5 and the host's own address. pasta gives the container the same address as the host's main interface, so a connection from inside the container to that address does not leave the namespace. A target that is the endpoint host itself, reached by its LAN address, fails on a rootless podman 5 install where it worked on podman 4. Again a test-fixture concern, not a production one.
To see what a running guacd actually got, inspect the container the plugin created:
podman inspect drp-guacd-runner-<broker-uuid> --format '{{.HostConfig.NetworkMode}} {{.NetworkSettings.Ports}}'
ss -ltnp | grep 4822
The second command should show 4822 bound to 127.0.0.1 only.
guacd to the target¶
guacd opens the last connection from inside its container, and it leaves the host through whichever network the table above describes. The target sees the endpoint host's address. A firewall rule that lets the endpoint host reach the target is what is needed; nothing about the operator's network matters here.
| Console | Target | Protocol | Credential params |
|---|---|---|---|
ssh |
machine Address, port 22 |
SSH | console/ssh-key, console/ssh-user |
bmc-sol |
ipmi/address, port 22 |
SSH | ipmi/username, ipmi/password |
bmc-kvm streamed |
ipmi/address, ipmi/console-vnc-port |
VNC | ipmi/console-vnc-password, falling back to ipmi/password |
hyperv |
hyper-v/console-host, port 2179 |
RDP, VMConnect security | hyper-v/console-username, hyper-v/console-password, hyper-v/console-domain |
The credentials are read from the machine's params on the endpoint, with the same profile and default resolution any task sees, and are handed to guacd in the handshake. They are never sent to the browser, and a secure param is stored encrypted on the endpoint.
For the BMC serial console the target is the BMC's own SSH service, not IPMI-over-LAN.
After login guacd sends the vendor's entry command (console com2 on iDRAC, console 1 on
XCC) to move from the management shell onto the serial port.
The link-out¶
A BMC KVM console with ipmi/console-url set does not use guacd. The portal opens the URL
in a new browser tab, and from there the operator's browser talks to the BMC's web
application directly and logs in with the BMC's own login page. This is the only console
path where the operator needs a route to the target. The endpoint still needs Redfish to
the BMC to offer the item at all, since console-info decides whether it appears.
Where a blocked hop shows up¶
| Blocked | What the operator sees | Where to look |
|---|---|---|
| Browser to endpoint 8092 | The portal cannot reach the endpoint at all | Not console specific |
| Endpoint to BMC Redfish | BMC items disabled with an "unable to reach the BMC over Redfish" reason | drpcli machines runaction <uuid> console-info --plugin ipmi |
| guacd broker missing | No Remote button | drpcli resource_brokers exists Name:guacd-service |
| Endpoint to guacd 4822 | Session refused with "cannot reach guacd" | The guacd-run job on the broker |
| guacd to target | Session opens, then closes | The guacd container log, then reachability of the target from the endpoint host |
| Target on the host's loopback | Session opens, then closes; the target never sees a connection | The container is on its own network. See Container networking. |
Machine has no Address |
Session refused with "has no address to connect to" | The machine's Address; discovery or a lease |
| Browser to BMC web UI | The new tab does not load | The operator's own route to the BMC. DRP logs show nothing. |
A session that opens and then closes with every hop reachable is an authorization problem on the target, not a network one. The Hyper-V per-VM access list is the common case; see Hyper-V VM Console.
High availability¶
The portal talks to the active endpoint, and that is where the plugin actions run and
where the guacd-service broker's container runs. The tunnel therefore terminates on the
active node, and the connections in the table above originate from it.
References¶
- Guacamole Tunnel
- Contexts and Setting Up Docker Contexts for the
docker-contextplugin - Remote Console
- Hyper-V VM Console