p1.1: dynamic self-IP deny (DDNS/trace, keep previous, atomic swap)
Discover WAN via ddns:<host> then trace:<url> before listen. Persist to self_ip.json. Previous addresses stay denied for keep_previous. Failure keeps the last known set. /healthz reports age and source.
This commit is contained in:
+51
-4
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log/slog"
|
||||
"net"
|
||||
@@ -12,8 +13,10 @@ import (
|
||||
|
||||
"git.wntrmute.dev/kyle/sift/internal/api"
|
||||
"git.wntrmute.dev/kyle/sift/internal/auth"
|
||||
"git.wntrmute.dev/kyle/sift/internal/config"
|
||||
"git.wntrmute.dev/kyle/sift/internal/fetch"
|
||||
"git.wntrmute.dev/kyle/sift/internal/guard"
|
||||
"git.wntrmute.dev/kyle/sift/internal/selfip"
|
||||
)
|
||||
|
||||
type denyFlags []netip.Prefix
|
||||
@@ -54,12 +57,30 @@ func serveMain() {
|
||||
registerTestFlags(fs, g)
|
||||
_ = fs.Parse(os.Args[1:])
|
||||
|
||||
g.DenyPrefixes = deny
|
||||
log := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||
cfg, err := config.Load(*configPath)
|
||||
if err != nil {
|
||||
log.Error("config", "err", err, "path", *configPath)
|
||||
os.Exit(1)
|
||||
}
|
||||
if *listen == "127.0.0.1:8890" && cfg.Listen != "" {
|
||||
*listen = cfg.Listen
|
||||
}
|
||||
if *ua == "sift/"+version && cfg.UserAgent != "" {
|
||||
*ua = cfg.UserAgent
|
||||
}
|
||||
for _, s := range cfg.DenyPrefixes {
|
||||
p, err := netip.ParsePrefix(s)
|
||||
if err != nil {
|
||||
log.Error("deny_prefixes", "err", err, "value", s)
|
||||
os.Exit(1)
|
||||
}
|
||||
deny = append(deny, p)
|
||||
}
|
||||
g.DenyPrefixes = deny
|
||||
if n := len(deny); n > 0 {
|
||||
log.Info("deny prefixes loaded", "count", n)
|
||||
}
|
||||
_ = configPath
|
||||
|
||||
store, err := auth.Load(*keysPath)
|
||||
if err != nil {
|
||||
@@ -68,9 +89,33 @@ func serveMain() {
|
||||
}
|
||||
|
||||
fetcher := &fetch.Fetcher{Guard: g, UA: *ua}
|
||||
srv := api.New(version, g, fetcher, store, log)
|
||||
hs := srv.HTTPServer(*listen)
|
||||
parent, stop := context.WithCancel(context.Background())
|
||||
defer stop()
|
||||
|
||||
srv := api.New(version, g, fetcher, store, log)
|
||||
if len(cfg.SelfIP.Sources) > 0 {
|
||||
disc := &selfip.Discoverer{
|
||||
Cfg: selfip.Config{
|
||||
Sources: cfg.SelfIP.Sources,
|
||||
Interval: config.ParseDuration(cfg.SelfIP.Interval, selfip.DefaultInterval),
|
||||
KeepPrevious: config.ParseDuration(cfg.SelfIP.KeepPrevious, selfip.DefaultKeepPrevious),
|
||||
Path: cfg.SelfIP.Path,
|
||||
},
|
||||
Guard: g,
|
||||
Log: log,
|
||||
Get: func(ctx context.Context, u string) ([]byte, error) {
|
||||
res, err := fetcher.Fetch(ctx, u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Body, nil
|
||||
},
|
||||
}
|
||||
disc.Start(parent)
|
||||
srv.SelfIP = disc
|
||||
}
|
||||
|
||||
hs := srv.HTTPServer(*listen)
|
||||
ln, err := net.Listen("tcp", *listen)
|
||||
if err != nil {
|
||||
log.Error("listen", "err", err)
|
||||
@@ -96,8 +141,10 @@ func serveMain() {
|
||||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
||||
select {
|
||||
case <-sig:
|
||||
stop()
|
||||
_ = hs.Close()
|
||||
case err := <-errCh:
|
||||
stop()
|
||||
if err != nil {
|
||||
log.Error("serve", "err", err)
|
||||
os.Exit(1)
|
||||
|
||||
Reference in New Issue
Block a user