drpanwe icon

Untitled

drpanwe | PRO | 01/22/25 11:07:39 AM UTC (Edited) | 0 ⭐ | 15882 👁️ | Never ⏰ | [eBPF]
Go |

3.79 KB

|

Source Code

|

0 👍

/

0 👎

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
}
 

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎