A connection that cannot point at the machine it is running on

"Nothing runs on the LLeMbas host" is the sentence the absent sandbox and the
absent local MCP rest on, and an SSH profile aimed at 127.0.0.1 walked straight
past it -- through a real login, with every gate in policy.py still applying,
onto the machine holding the database and the Fernet key. From the SSH layer
down it is indistinguishable from a container on the network, so nothing here
could have noticed.

One switch, three positions: never, one named port, anywhere. The middle one is
the one with a real use -- a container that published its SSH port on the
loopback interface is genuinely somewhere else -- and port 22 is refused even
there, because that one is this host's own sshd.

Enforced in five places, because a row can predate a setting: saving a profile,
`session.resolve` (the control every agent tool, the terminal and the canvas go
through), the composer's picker, browsing, and the draft the panels open against
before a chat exists. Check refuses before it opens its socket rather than after.

And the recognition never resolves a name on the request path. `refusal` runs
several times per page render; the first version of this looked names up inline
and the suite went from two minutes to not finishing. Literal forms are decided
from the string, a name is settled where a network call is already expected, and
the answer lives on the row. The gap that leaves is written down rather than
discovered.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jaroslav Beneš
2026-08-06 10:07:36 +02:00
parent fa8c8ab5e8
commit 14b1428f9f
15 changed files with 731 additions and 12 deletions
+29 -1
View File
@@ -19,7 +19,7 @@ from sqlalchemy import func, select
from lembas.api.deps import AdminUser, Db
from lembas.db.models import SshProfile
from lembas.services import settings_store
from lembas.services.agent import policy
from lembas.services.agent import hosts, policy
from lembas.services.agent import ssh as ssh_service
from lembas.services.agent import terminal as terminal_service
from lembas.web.templating import render
@@ -48,6 +48,18 @@ async def agents_page(request: Request, db: Db, user: AdminUser, saved: bool = F
"profile_count": db.scalar(select(func.count()).select_from(SshProfile)) or 0,
"terminal_count": terminal_service.count(),
"modes": [(m, policy.MODE_LABELS[m], policy.MODE_HINTS[m]) for m in policy.MODES],
"loopback_modes": [
(m, hosts.MODE_LABELS[m], hosts.MODE_HINTS[m]) for m in hosts.MODES
],
# How many of this instance's connections the current position would
# stop. The number is the point of the card: "3 connections" beside
# a switch somebody is about to move is the difference between an
# informed change and a surprise.
"loopback_count": sum(
1
for p in db.scalars(select(SshProfile))
if hosts.is_loopback(p.host) or p.resolves_here
),
"saved": saved,
},
)
@@ -58,6 +70,8 @@ async def save_agents(
db: Db,
user: AdminUser,
enabled: bool = Form(False),
loopback: str = Form("off"),
loopback_port: int = Form(0),
default_timeout: int = Form(60),
max_timeout: int = Form(600),
max_output_bytes: int = Form(64 * 1024),
@@ -88,6 +102,13 @@ async def save_agents(
db,
{
"enabled": enabled,
# Anything unrecognised means off, here as well as on read: the one
# direction safe to get wrong is refusing a connection somebody has
# to re-allow, and the other is a shell on this host.
"loopback": loopback if loopback in hosts.MODES else hosts.MODE_OFF,
# Zero means "none named", which is what `port` needs in order to
# refuse rather than to allow. 22 is refused wherever it is stored.
"loopback_port": loopback_port if 1 <= loopback_port <= 65535 else 0,
# Clamped here as well as on read. A number with no bound is a way
# to break the instance from a form, which is the same reasoning
# the search settings carry.
@@ -124,4 +145,11 @@ async def save_agents(
key=settings_store.AGENTS,
)
log.info("agent execution %s by %s", "enabled" if enabled else "disabled", user.email)
if loopback != hosts.MODE_OFF:
log.warning(
"ssh connections to this machine allowed (%s%s) by %s",
loopback,
f", port {loopback_port}" if loopback == hosts.MODE_PORT else "",
user.email,
)
return RedirectResponse("/admin/agents?saved=1", status_code=status.HTTP_303_SEE_OTHER)