Add opt-in service discovery: local listeners and rate-limited private subnet scans
Reports identified services (HTTP, HTTPS, SSH, SMTP, FTP, ...) to Hammerhead as suggested targets. Needs a Reef release containing model.DiscoveredService. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
17c222c946
commit
710b101436
8 files changed
+717
-16
No files matched your search
@@ -24,6 +24,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"git.veillax.com/Veillax/bamboo/discover"
|
||||
"git.veillax.com/Veillax/reef/docker"
|
||||
"git.veillax.com/Veillax/reef/model"
|
||||
"git.veillax.com/Veillax/reef/tunnel"
|
||||
@@ -33,8 +34,9 @@ import (
|
||||
type Config struct {
|
||||
Hammerhead string
|
||||
Token string
|
||||
DataDir string // holds this agent's WireGuard key
|
||||
Docker bool // report local Docker containers so they can be picked as targets
|
||||
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
|
||||
|
||||
// Version, AutoUpdate and UpdateNow work as in blacktip.Config.
|
||||
Version string
|
||||
@@ -64,6 +66,8 @@ type Bamboo struct {
|
||||
updLog []string
|
||||
updSent time.Time
|
||||
|
||||
disc *discover.Discoverer // nil unless discovery is switched on
|
||||
|
||||
mail map[string]*mailRun
|
||||
mailErr map[string]string // mail egress ID -> "" (listening) or an error
|
||||
}
|
||||
@@ -80,8 +84,14 @@ func New(cfg Config) (*Bamboo, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Bamboo{cfg: cfg, http: &http.Client{Timeout: 40 * time.Second}, ctx: context.Background(), wgKey: key, wgPub: pub,
|
||||
mail: map[string]*mailRun{}, mailErr: map[string]string{}}, nil
|
||||
b := &Bamboo{cfg: cfg, http: &http.Client{Timeout: 40 * time.Second}, ctx: context.Background(), wgKey: key, wgPub: pub,
|
||||
mail: map[string]*mailRun{}, mailErr: map[string]string{}}
|
||||
if cfg.Discover.Enabled() {
|
||||
if b.disc, err = discover.New(cfg.Discover); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// loadOrCreateKey keeps this agent's WireGuard identity across restarts.
|
||||
@@ -106,6 +116,9 @@ func (b *Bamboo) Run(ctx context.Context) error {
|
||||
log.Printf("bamboo started; WireGuard public key %s", b.wgPub)
|
||||
go b.reportLoop(ctx)
|
||||
go b.refreshLoop(ctx)
|
||||
if b.disc != nil {
|
||||
go b.disc.Run(ctx, log.Printf)
|
||||
}
|
||||
for ctx.Err() == nil {
|
||||
cfg, err := b.fetchConfig(ctx)
|
||||
if err != nil {
|
||||
@@ -263,10 +276,14 @@ func (b *Bamboo) report() {
|
||||
containers, _ = docker.List(ctx)
|
||||
cancel()
|
||||
}
|
||||
var found []model.DiscoveredService
|
||||
if b.disc != nil {
|
||||
found = b.disc.Results()
|
||||
}
|
||||
b.mu.Lock()
|
||||
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, MailEgress: b.mailStatus(),
|
||||
body, _ := json.Marshal(model.SiteReport{PublicKey: b.wgPub, Connected: ids, Containers: containers, Discovered: found, MailEgress: b.mailStatus(),
|
||||
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)
|
||||
|
||||
Reference in new issue
Block a user