Commit Graph
5 Commits
Author SHA1 Message Date
Matt RichardsonandClaude Fable 5.1 f2a8883563 Drop the info API tests that tested the control socket's code twice
The endpoint is one type under both servers, so the info API's copies of
the rebind, failed-rebind and cancellation tests ran the control socket's
code a second time, and in-place access changes were pinned twice more.

- info API: the three endpoint tests, the mode test and the wire test's mode step go
- the control socket's group hand-over test stands for both servers
- registry: one Resolve test with both the typed and the worded assertions, in registry_test

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-21 12:26:57 -04:00
Matt RichardsonandClaude Fable 5.1 613c7e3061 Add the identity command and serve it on an opt-in HTTP info API
Build slackhq/nebula#1821 ("who is this vpn address?" over a local
HTTP+JSON socket) on the command registry, so the lookup is one command
on every surface and the socket is one more local API.

identity
- `identity [-address <vpn addr>[:port]]`: no address reports this node;
  with one, this node or the peer behind an established tunnel
- Certificate fields only: name, vpn addresses, networks, unsafe
  networks, groups, fingerprint, issuer, validity, cert version; a peer's
  fingerprint is the one nebula computed when it verified the cert
- Port accepted and stripped, 4in6 unmapped, so a RemoteAddr passes
  straight through
- No tunnel is a commands.NotFound; an empty -address is refused
- Lighthouse TXT lookup shares the owner and peer lookups, keeps answering
  with the initiating certificate, and no longer panics without a default cert
- Served on ssh and nebula ctl too

Info API
- Off until `local_api.info.enabled` with `socket` and optional quoted
  octal `socket_mode` (default "0600"); nothing derived
- Serves commands declaring Command.Identity plus help; others 403 naming
  their surfaces. TestInfoAPISurface pins the set to identity
- GET /v1 is the schema; GET /v1/<cmd>?<flag>=<value> runs one; body is
  the -json rendering via commands.Render; commands.PresentationFormat
  reads json/pretty from the query the way a line is read
- 400 commands.ParamError, 403 commands.WithheldError (what Resolve now
  returns for a withheld name, so help and dispatch type-check it too),
  404 NotFound or unknown, 500 Run error, refusal with no reason, or
  recovered panic with no detail; no redirects; every miss is JSON
- listen takes a mode: bind under umask 0077 then chmod; "0660" plus a
  searchable dir opens it to a group
- The chmod, at bind and on a mode-only reload, goes through chmodSocket,
  which never follows a link: a user who can write the socket's directory
  could otherwise swap the node for a link and have a root daemon put
  0660 or 0666 on any file. Only a socket we own is chmoded. On linux the
  node is held open O_PATH|O_NOFOLLOW, checked by fstat, and chmoded
  through /proc/self/fd, so the check and the chmod land on one inode;
  fchmodat2 is the fallback without /proc. On darwin and the BSDs it is
  an Lstat check and fchmodat(AT_SYMLINK_NOFOLLOW). clearStale Lstats
  too, so a dangling link is refused rather than followed by bind on
  darwin
- One endpoint type owns bind under mutex, bind-before-release move,
  context watch and stop/unlink; each server supplies what it serves
- Reloadable through the same reconcile shape as the control socket:
  mode applied in place, unparsable section keeps what runs, control
  socket path refused by name
- Wire returns Endpoints{Control, Info} with one Stop
- Windows unsupported for now (a pipe has no mode); warned once

Tests: identity lookups and shapes; API filter, status codes, panic
recovery, socket mode, rebind, cancellation; config parsing incl. bare
0660; Wire transitions; e2e of two nebulas with the info API resolving
the peer by address and port, through shared test.HTTPDo/HTTPGet helpers.
Goldens gain identity.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-21 12:26:09 -04:00
Matt RichardsonandClaude Fable 5.1 0f767ce529 Add a local control socket and nebula ctl (#1975)
Add support for accessing the previously ssh-only debug commands via
`nebula ctl <command>.`

- unix socket (named pipe on windows) for communication
- sockets scoped to the user + an optional group
- in cmd/nebula and cmd/nebula-service, but not nebula.Main

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-21 11:16:00 -04:00
Matt RichardsonandClaude Fable 5.1 8a4bd8b10f Report ssh command failures to the surface (#1959)
smoke-extra / freebsd-amd64 (push) Failing after 14s
smoke-extra / linux-amd64-ipv6disable (push) Failing after 13s
smoke-extra / netbsd-amd64 (push) Failing after 14s
smoke-extra / openbsd-amd64 (push) Failing after 15s
smoke-extra / linux-386 (push) Failing after 14s
smoke / Run multi node smoke test (push) Failing after 1m46s
Build and test / Static checks (push) Successful in 2m38s
Build and test / Test linux (push) Failing after 1m12s
Build and test / Test linux-pkcs11 (push) Failing after 2m6s
Build and test / Test linux-boringcrypto (push) Failing after 3m0s
Build and test / Test linux-fips140 (push) Failing after 2m56s
Build and test / Cross-build linux-arm (push) Successful in 3m10s
Build and test / Cross-build linux-mips (push) Successful in 3m55s
Build and test / Cross-build linux-other (push) Successful in 3m15s
Build and test / Cross-build windows (push) Successful in 1m5s
Build and test / Cross-build freebsd (push) Successful in 1m37s
Build and test / Cross-build netbsd (push) Successful in 1m36s
Build and test / Cross-build openbsd (push) Successful in 1m35s
Build and test / Cross-build mobile (push) Successful in 3m32s
smoke-extra / Run windows smoke test (push) Canceled after 0s
smoke / Run self traffic smoke test on macOS (push) Canceled after 0s
Build and test / Test macos (push) Canceled after 0s
Build and test / Test windows (push) Canceled after 0s
Build and test / CI status (push) Canceled after 0s
Report ssh command failures to the surface (#1959)

The ssh debug commands told the user when something went wrong but
never told the surface that ran them, so `ssh host cmd` always exited 0
and a few failures were not reported at all. A failed command now
returns its error, a failure the user has already heard about is a
commands.Failure, and the ssh exec path exits 1 for either. The command
bodies also lose their ssh prefixes and the duplication they carried
over from ssh.go; both goldens pin that nothing else changed.

- Dispatch returns the callback's error, or shlex's; the ssh session
  logs it at debug, and not at all for a Failure the user already saw
- commands.Fail writes a message and returns it as a Failure in one step;
  an unknown command, `help` for a command that is not there, a failed
  reload and an unbalanced quote are failures
- ssh exec exit-status is 1 for a command, flag or failure error, 0
  otherwise; the e2e golden records the exit status for every case
- Clone rebinds help to the copy, so an ssh session's help lists logout
  and `help logout` and `logout -h` answer; sshd.LogoutCommand is the
  session's logout, exported for tests
- "did not understand" names the first word only, the one looked up;
  DispatchArgs takes just the tokens
- log-format writes its refusal to the user, as log-level does
- print-relays emits the relay error as a string and omits the key when
  there is none, where it printed {} or "Error":null
- list-hostmap and list-lighthouse-addrmap -json return the encode
  error; print-cert reports a certificate that will not marshal
- a flags type that is not the one registered is an internal error, not
  a silent success
- command functions and flag types are <name>Command and <name>Flags;
  parseVpnAddr and listHostMapFlagSet replace the repeated parse block
  and flag set; close-tunnel sends through sendCloseTunnel

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-19 10:48:26 -04:00
Matt RichardsonandClaude Fable 5.1 b426843f88 Extract the ssh debug commands into a transport neutral commands package (#1958)
Migrate commands from ssh into a transport neutral package

 - add golden tests validating that output remains unchanged
 - move commands to commands.go

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-19 10:25:28 -04:00