Terminal relay: answer Hammerhead's terminal sessions through the agent
CI / test (push) Successful in 3m51s
Release / release (push) Successful in 4m43s

When someone opens a terminal for this site, Hammerhead lists the session in the
site's config. The agent connects out to Hammerhead and joins that connection to
its own SSH server, so no port has to be open on an edge. The agent now reports
where its SSH server listens and that it can relay.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
VeillaxandClaude Sonnet 5.5 committed 2026-10-31 01:38:46 -06:00
1 parent 1fba65fd3e
commit a2403ecf9d
7 files changed
+225 -6

No files matched your search

+4
View File
@@ -37,6 +37,7 @@ type Config struct {
DataDir string // holds this agent's WireGuard key
Docker bool // report local Docker containers so they can be picked as targets
Discover discover.Config // opt-in: report listening services found on this host and configured subnets as suggested targets
SSH string // where this machine's SSH server listens ("" = not running); Hammerhead's terminal reaches it through the agent
// Version, AutoUpdate and UpdateNow work as in blacktip.Config.
Version string
@@ -57,6 +58,7 @@ type Bamboo struct {
tun *wg.Device
edges []model.EdgeRef
lastRep string
terms map[string]time.Time // terminal sessions already answered, by id
updating atomic.Bool
updateMsg string // outcome of the update Hammerhead asked for, reported back
@@ -185,6 +187,7 @@ func (b *Bamboo) apply(cfg *model.SiteConfig) {
b.mu.Unlock()
b.syncPeers()
b.syncMail(cfg.MailEgress)
b.openTerminals(cfg.Terminals)
go b.report()
}
@@ -284,6 +287,7 @@ func (b *Bamboo) report() {
msg, uid, stage, pct, ulog := b.updateMsg, b.updateID, b.updStage, b.updPct, append([]string(nil), b.updLog...)
b.mu.Unlock()
body, _ := json.Marshal(model.SiteReport{PublicKey: b.wgPub, Connected: ids, Containers: containers, Discovered: found, MailEgress: b.mailStatus(),
SSH: b.cfg.SSH, SSHRelay: true,
Version: b.cfg.Version, AutoUpdate: b.cfg.AutoUpdate, UpdateMsg: msg, UpdateID: uid, UpdateStage: stage, UpdatePct: pct, UpdateLog: ulog})
req, _ := http.NewRequest("POST", b.cfg.Hammerhead+"/site/report", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+b.cfg.Token)