wgctl/daemon/wgctl-conntrack/main.go
Nuno Duque Nunes d314ba376e feat: wgctl-conntrack Go daemon
- conntrack/event.go: TrafficEvent type
- conntrack/filter.go: WG subnet filter, IsExternal, ProtoName
- conntrack/subscriber.go: netlink conntrack DESTROY subscriber
- writer/log.go: JSON line writer with mutex
- resolver/peers.go: WG IP → peer name from conf files + endpoint index
- resolver/services.go: IP:port → service name from services.json
- config/config.go: reads wgctl.json, sensible defaults
- cmd/root.go: CLI flags
- main.go: wires everything together
- DESTROY events only: full byte/packet counts per connection
- filters to WireGuard subnet, marks external traffic
2026-05-28 02:51:27 +00:00

71 lines
No EOL
1.7 KiB
Go

package main
import (
"log"
"net"
"os"
"os/signal"
"syscall"
"git.krilio.net/nuno/wgctl-conntrack/cmd"
"git.krilio.net/nuno/wgctl-conntrack/config"
ctconn "git.krilio.net/nuno/wgctl-conntrack/conntrack"
"git.krilio.net/nuno/wgctl-conntrack/resolver"
"git.krilio.net/nuno/wgctl-conntrack/writer"
)
func main() {
flags := cmd.Parse()
cfg, err := config.Load(flags.WGDir)
if err != nil {
log.Fatalf("failed to load config: %v", err)
}
if flags.Subnet != "" {
cfg.WGSubnet = flags.Subnet
}
if flags.LogFile != "" {
cfg.AcceptLogFile = flags.LogFile
}
_, wgSubnet, err := net.ParseCIDR(cfg.WGSubnet)
if err != nil {
log.Fatalf("invalid WG subnet %q: %v", cfg.WGSubnet, err)
}
log.Printf("wgctl-conntrack v%s starting (subnet: %s, log: %s)",
cmd.Version, cfg.WGSubnet, cfg.AcceptLogFile)
peerResolver := resolver.NewPeerResolver(flags.WGDir)
svcResolver := resolver.NewServiceResolver(cfg.ServicesFile)
res := &combinedResolver{peers: peerResolver, services: svcResolver}
events := make(chan ctconn.TrafficEvent, 512)
go writer.NewLogWriter(cfg.AcceptLogFile).Run(events)
sub := ctconn.NewSubscriber(wgSubnet, events, res)
go func() {
if err := sub.Run(); err != nil {
log.Fatalf("conntrack subscriber error: %v", err)
}
}()
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
log.Println("wgctl-conntrack shutting down")
}
type combinedResolver struct {
peers *resolver.PeerResolver
services *resolver.ServiceResolver
}
func (r *combinedResolver) PeerForIP(ip net.IP) string {
return r.peers.PeerForIP(ip)
}
func (r *combinedResolver) ServiceForDst(ip net.IP, port uint16, proto string) string {
return r.services.ServiceForDst(ip, port, proto)
}