The DDoS attack on net 44 continues. I'm filtering out a goodly amount of it at amprgw, but the people whose subnets are directly connected (BGP announced) are getting hit too, and there's nothing I can do to filter it out here. Basically, if you're directly connected (ie, not on a tunnel), you have to add a list of bad guys to your own firewall blocking.
Here is a little script that will create a list of candidate addresses for blocking. You'll need the 'badguys' program, which I'll post below. What this does is give you a list of addrsses that sent you more than 1000 packets in the sample period.
If you're connected via tunnel, you probably don't need this.
I run this several times a day to accumulate a list of bad guys. I sample 100 million packets at a time; smaller subnets will probably want to use a smaller sample size.
This was developed on FreeBSD but I'm told it works fine on Linux
Hope this helps. - Brian
----------------------------------------------------------- block.sh: #!/bin/sh # # generate a list of possible bad guys #
# sample incoming traffic, 100,000,000 incoming packets # during DDoS storm on a /8, this takes about 3 minutes
time tcpdump -w /tmp/t.pcap -s 40 -c 100000000
# turn into a list of source IP addresses with counts, # sorted by decreasing count # throw away all those counted less than 1000, # delete the count from the line # elide our own addresses (put your own in the egrep) # store in a file
./badguys /tmp/t.pcap \ | sort \ | uniq -c \ | sort -rn \ | sed -e '/^ /d' \ | sed -e 's/.* //' \ | egrep -v '^44.|^169.228.' \ > /tmp/badguys
# all done with this file rm -f /tmp/t.pcap
exit 0 ----------------------------------------------------------- badguys.c: /* * reads pcap capture file (use tcpdump -w to create) named * * spins through it, listing the IP source address on stdout * prints summary statistics on stderr * * the documentation on the pcap library leaves a lot to be * desired, use the source. a lot of what you need is in tcpdump.c * * compile me with * cc -g -Wall badguys.c -lpcap -o badguys * * (You'll need to have libpcap installed) * * Brian Kantor, UCSD, 2017 */
/* probably most of these includes are superfluous */ #include <sys/errno.h> #include <sys/types.h>
#include <ctype.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
#include <net/ethernet.h>
#include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h>
#include <arpa/inet.h>
#include <pcap/pcap.h> #include <pcap/bpf.h>
void getpkt(u_char *, const struct pcap_pkthdr *, const u_char *);
char * iptoa(u_long);
int capcount = 0; int skipcount = 0;
int main(int argc, char**argv) { char inpcapname[FILENAME_MAX+1]; char errbuf[BUFSIZ]; pcap_t *pcap; int rslt;
if (argc != 2) { fprintf(stderr, "Usage: %s pcapfilename\n", argv[0]); exit(1); }
strncpy(inpcapname, argv[1], FILENAME_MAX); fprintf(stderr, "opening PCAP file %s\n", inpcapname);
pcap = pcap_open_offline(inpcapname, errbuf); if (!pcap) { fprintf(stderr, "Error: %s\n", errbuf); exit(1); } /* * read through the capture savefile */ rslt = pcap_loop(pcap, 0, getpkt, 0); if (rslt) { fprintf(stderr, "pcap_loop returned %d\n", rslt); pcap_perror(pcap, "pcap_loop returned"); exit(1); } pcap_close(pcap);
fprintf(stderr, "%d packets read from savefile\n", capcount); fprintf(stderr, "%d non-IP packets discarded\n", skipcount);
exit(0); }
/* * called by pcap_loop once per packet read from savefile */ void getpkt(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { struct ip * ip; u_short * ethertype;
capcount++;
/* get the Ethernet packet type */ ethertype = (u_short *)&p[(2*ETHER_ADDR_LEN)];
/* we only want IP packets */ if (ntohs(*ethertype) != ETHERTYPE_IP) { skipcount++; return; }
/* IP packet starts after Ethernet header */ ip = (struct ip *)&p[ETHER_HDR_LEN];
puts(iptoa(ntohl(ip->ip_src.s_addr)));
return; }
/* * nicely format host-byte-order u_int into dotted quad * returns pointer to a small static buffer; you can't * call this more than once in a single syslog or printf statement */ char * iptoa(u_long ipaddr) { static char buf[32];
snprintf(buf, sizeof buf, "%lu.%lu.%lu.%lu", (ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff, (ipaddr >> 8) & 0xff, (ipaddr) & 0xff);
return buf; }