1
0

udp_bypass_windows.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. //go:build (amd64 || arm64) && !e2e_testing
  2. // +build amd64 arm64
  3. // +build !e2e_testing
  4. package udp
  5. import (
  6. "log/slog"
  7. "sync"
  8. "github.com/slackhq/nebula/config"
  9. "github.com/slackhq/nebula/wfp"
  10. )
  11. // wrapWithWDFBypass wraps a Conn so that the first ReloadConfig consults listen.windows_bypass_wdf
  12. // and installs a WFP PERMIT filter for the listener's bound UDP port. The session is released when Close runs.
  13. func wrapWithWDFBypass(l *slog.Logger, conn Conn) Conn {
  14. return &bypassConn{Conn: conn, l: l}
  15. }
  16. type bypassConn struct {
  17. Conn
  18. l *slog.Logger
  19. installOnce sync.Once
  20. session *wfp.Session
  21. }
  22. func (b *bypassConn) ReloadConfig(c *config.C) {
  23. b.installOnce.Do(func() {
  24. if !c.GetBool("listen.windows_bypass_wdf", true) {
  25. return
  26. }
  27. addr, err := b.Conn.LocalAddr()
  28. if err != nil {
  29. b.l.Warn("Failed to query listener port for WFP bypass", "error", err)
  30. return
  31. }
  32. s, err := wfp.PermitUDPPort(addr.Port())
  33. if err != nil {
  34. b.l.Warn("Failed to install WFP bypass filters for listener", "error", err)
  35. return
  36. }
  37. b.l.Info("Installed WFP filters bypassing Windows Defender Firewall on UDP listener port",
  38. "port", addr.Port())
  39. b.session = s
  40. })
  41. b.Conn.ReloadConfig(c)
  42. }
  43. func (b *bypassConn) Close() error {
  44. if b.session != nil {
  45. b.session.Close()
  46. b.session = nil
  47. }
  48. return b.Conn.Close()
  49. }