Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "log"
- "net"
- "time"
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/link"
- "github.com/cilium/ebpf/rlimit"
- )
- // Adjust these constants for your setup
- const (
- bpfObjectFile = "udp_flood_blocker.bpf.o"
- interfaceName = "eth0" // e.g. "eth0", "ens5", etc. on Ubuntu
- packetsPerSecThreshold = 10000 // example threshold
- )
- func main() {
- // 1) Remove the memlock limit so eBPF maps can be created
- if err := rlimit.RemoveMemlock(); err != nil {
- log.Fatalf("failed to remove memlock limit: %v", err)
- }
- // 2) Load the compiled eBPF object from file
- spec, err := ebpf.LoadCollectionSpec(bpfObjectFile)
- if err != nil {
- log.Fatalf("failed to load eBPF collection spec from %s: %v", bpfObjectFile, err)
- }
- // 3) Create a Collection from the spec (program + maps)
- coll, err := ebpf.NewCollection(spec)
- if err != nil {
- log.Fatalf("failed to create eBPF collection: %v", err)
- }
- defer coll.Close()
- // 4) Get the XDP program from the collection
- prog, ok := coll.Programs["detect_and_block_udp"]
- if !ok {
- log.Fatalf("program 'detect_and_block_udp' not found in %s", bpfObjectFile)
- }
- // 5) Attach the XDP program to the given network interface
- ifIndex := resolveInterfaceIndex(interfaceName)
- linkXDP, err := link.AttachXDP(link.XDPOptions{
- Program: prog,
- Interface: ifIndex,
- Flags: link.XDPGenericMode, // or link.XDPDriverMode if supported
- })
- if err != nil {
- log.Fatalf("failed to attach XDP to interface %s: %v", interfaceName, err)
- }
- defer linkXDP.Close()
- log.Printf("XDP program attached to interface %s (ifIndex=%d)", interfaceName, ifIndex)
- // 6) Retrieve eBPF maps from the collection
- udpCountMap, ok := coll.Maps["udp_count"]
- if !ok {
- log.Fatalf("map 'udp_count' not found in the collection")
- }
- blockStateMap, ok := coll.Maps["block_state"]
- if !ok {
- log.Fatalf("map 'block_state' not found in the collection")
- }
- // Initialize block_state to 0 (allow)
- zeroKey := uint32(0)
- zeroVal := uint32(0)
- if err := blockStateMap.Update(&zeroKey, &zeroVal, ebpf.UpdateAny); err != nil {
- log.Fatalf("failed to initialize block_state: %v", err)
- }
- // We'll track how many UDP packets we see each second
- var oldCount, newCount uint64
- ticker := time.NewTicker(1 * time.Second)
- defer ticker.Stop()
- for range ticker.C {
- // Read the current count from the eBPF map
- if err := udpCountMap.Lookup(&zeroKey, &newCount); err != nil {
- log.Printf("lookup failed: %v", err)
- continue
- }
- diff := newCount - oldCount
- oldCount = newCount
- if diff > packetsPerSecThreshold {
- // Exceeded threshold => block further UDP
- log.Printf("[ALERT] High UDP rate: %d pkts/sec => blocking...", diff)
- blockVal := uint32(1)
- if err := blockStateMap.Update(&zeroKey, &blockVal, ebpf.UpdateAny); err != nil {
- log.Printf("failed to set block_state: %v", err)
- }
- } else {
- // If you want automatic unblocking, uncomment:
- /*
- blockVal := uint32(0)
- blockStateMap.Update(&zeroKey, &blockVal, ebpf.UpdateAny)
- */
- log.Printf("UDP packets last second: %d", diff)
- }
- }
- }
- // resolveInterfaceIndex fetches the index of an interface by name
- func resolveInterfaceIndex(ifaceName string) int {
- iface, err := net.InterfaceByName(ifaceName)
- if err != nil {
- log.Fatalf("cannot find interface %q: %v", ifaceName, err)
- }
- return iface.Index
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement