Advertisement
drpanwe

Untitled

Jan 22nd, 2025 (edited)
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.79 KB | Source Code | 0 0
  1. package main
  2.  
  3. import (
  4.     "log"
  5.     "net"
  6.     "time"
  7.  
  8.     "github.com/cilium/ebpf"
  9.     "github.com/cilium/ebpf/link"
  10.     "github.com/cilium/ebpf/rlimit"
  11. )
  12.  
  13. // Adjust these constants for your setup
  14. const (
  15.     bpfObjectFile          = "udp_flood_blocker.bpf.o"
  16.     interfaceName          = "eth0" // e.g. "eth0", "ens5", etc. on Ubuntu
  17.     packetsPerSecThreshold = 10000  // example threshold
  18. )
  19.  
  20. func main() {
  21.     // 1) Remove the memlock limit so eBPF maps can be created
  22.     if err := rlimit.RemoveMemlock(); err != nil {
  23.         log.Fatalf("failed to remove memlock limit: %v", err)
  24.     }
  25.  
  26.     // 2) Load the compiled eBPF object from file
  27.     spec, err := ebpf.LoadCollectionSpec(bpfObjectFile)
  28.     if err != nil {
  29.         log.Fatalf("failed to load eBPF collection spec from %s: %v", bpfObjectFile, err)
  30.     }
  31.  
  32.     // 3) Create a Collection from the spec (program + maps)
  33.     coll, err := ebpf.NewCollection(spec)
  34.     if err != nil {
  35.         log.Fatalf("failed to create eBPF collection: %v", err)
  36.     }
  37.     defer coll.Close()
  38.  
  39.     // 4) Get the XDP program from the collection
  40.     prog, ok := coll.Programs["detect_and_block_udp"]
  41.     if !ok {
  42.         log.Fatalf("program 'detect_and_block_udp' not found in %s", bpfObjectFile)
  43.     }
  44.  
  45.     // 5) Attach the XDP program to the given network interface
  46.     ifIndex := resolveInterfaceIndex(interfaceName)
  47.     linkXDP, err := link.AttachXDP(link.XDPOptions{
  48.         Program:   prog,
  49.         Interface: ifIndex,
  50.         Flags:     link.XDPGenericMode, // or link.XDPDriverMode if supported
  51.     })
  52.     if err != nil {
  53.         log.Fatalf("failed to attach XDP to interface %s: %v", interfaceName, err)
  54.     }
  55.     defer linkXDP.Close()
  56.  
  57.     log.Printf("XDP program attached to interface %s (ifIndex=%d)", interfaceName, ifIndex)
  58.  
  59.     // 6) Retrieve eBPF maps from the collection
  60.     udpCountMap, ok := coll.Maps["udp_count"]
  61.     if !ok {
  62.         log.Fatalf("map 'udp_count' not found in the collection")
  63.     }
  64.     blockStateMap, ok := coll.Maps["block_state"]
  65.     if !ok {
  66.         log.Fatalf("map 'block_state' not found in the collection")
  67.     }
  68.  
  69.     // Initialize block_state to 0 (allow)
  70.     zeroKey := uint32(0)
  71.     zeroVal := uint32(0)
  72.     if err := blockStateMap.Update(&zeroKey, &zeroVal, ebpf.UpdateAny); err != nil {
  73.         log.Fatalf("failed to initialize block_state: %v", err)
  74.     }
  75.  
  76.     // We'll track how many UDP packets we see each second
  77.     var oldCount, newCount uint64
  78.     ticker := time.NewTicker(1 * time.Second)
  79.     defer ticker.Stop()
  80.  
  81.     for range ticker.C {
  82.         // Read the current count from the eBPF map
  83.         if err := udpCountMap.Lookup(&zeroKey, &newCount); err != nil {
  84.             log.Printf("lookup failed: %v", err)
  85.             continue
  86.         }
  87.  
  88.         diff := newCount - oldCount
  89.         oldCount = newCount
  90.  
  91.         if diff > packetsPerSecThreshold {
  92.             // Exceeded threshold => block further UDP
  93.             log.Printf("[ALERT] High UDP rate: %d pkts/sec => blocking...", diff)
  94.             blockVal := uint32(1)
  95.             if err := blockStateMap.Update(&zeroKey, &blockVal, ebpf.UpdateAny); err != nil {
  96.                 log.Printf("failed to set block_state: %v", err)
  97.             }
  98.         } else {
  99.             // If you want automatic unblocking, uncomment:
  100.             /*
  101.             blockVal := uint32(0)
  102.             blockStateMap.Update(&zeroKey, &blockVal, ebpf.UpdateAny)
  103.             */
  104.             log.Printf("UDP packets last second: %d", diff)
  105.         }
  106.     }
  107. }
  108.  
  109. // resolveInterfaceIndex fetches the index of an interface by name
  110. func resolveInterfaceIndex(ifaceName string) int {
  111.     iface, err := net.InterfaceByName(ifaceName)
  112.     if err != nil {
  113.         log.Fatalf("cannot find interface %q: %v", ifaceName, err)
  114.     }
  115.     return iface.Index
  116. }
  117.  
Tags: eBPF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement