Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
en:dpi:qoe:use_cases:dpi_bestpractice_ddos_find_activity [2023/08/28 14:58] – elena.krasnobryzh | en:dpi:qoe:use_cases:dpi_bestpractice_ddos_find_activity [2024/04/25 08:39] (current) – removed elena.krasnobryzh | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Simple DDoS analysis ====== | ||
- | {{indexmenu_n> | ||
- | ===== Challenge ===== | ||
- | Initial conditions: 10Gbit channel, periodic powerful DDoS attack to one of the network ip-address takes place which leads to service degradation. | ||
- | The DDoS attack diagram is shown below, it shows that the DDoS attack power with the current traffic power in total exceeds the channel capacity. | ||
- | {{ : | ||
- | ===== Solution ===== | ||
- | Since it's impossible to quickly expand the channel capacity and increase the DPI power, pursue the following sequence of actions: | ||
- | 1. get the list of IP addresses subjected to DDoS | ||
- | 2. place the IP in the null route ( to a blackhole ) | ||
- | ==== Configuration ==== | ||
- | - create / | ||
- | - install the [[en: | ||
- | # | ||
- | protocol=udp | ||
- | host=0.0.0.0 | ||
- | port=1599 | ||
- | |||
- | [dump] | ||
- | rotate_minutes=1 | ||
- | processcmd=/ | ||
- | dumpfiledir=/ | ||
- | |||
- | [InfoModel] | ||
- | XMLElements = / | ||
- | |||
- | [Template] | ||
- | Elements = octetDeltaCount, | ||
- | |||
- | [ExportModel] | ||
- | Elements = session_id, octetDeltaCount, | ||
- | |||
- | |||
- | [logging] | ||
- | loggers.root.level = information | ||
- | loggers.root.channel = fileChannel | ||
- | channels.fileChannel.class = FileChannel | ||
- | channels.fileChannel.path = / | ||
- | channels.fileChannel.rotation = 1 M | ||
- | channels.fileChannel.archive = timestamp | ||
- | channels.fileChannel.purgeCount = 5 | ||
- | channels.fileChannel.formatter.class = PatternFormatter | ||
- | channels.fileChannel.formatter.pattern = %Y-%m-%d %H:%M:%S.%i [%P] %p %s - %t | ||
- | channels.fileChannel.formatter.times = local | ||
- | |||
- | </ | ||
- | - set permission for the 1599 UDP port in iptables, launch the ipfixreceiver.< | ||
- | # check out that the process is listening | ||
- | netstat -anpl | grep 1599 | ||
- | udp | ||
- | </ | ||
- | - create flow processing file: / | ||
- | |||
- | export PATH=/ | ||
- | export LD_LIBRARY_PATH=/ | ||
- | |||
- | gzip $1 | ||
- | echo "DDoS statistics" | ||
- | date >> / | ||
- | |||
- | echo -e " | ||
- | / | ||
- | |||
- | echo -e " | ||
- | / | ||
- | |||
- | echo -e " | ||
- | / | ||
- | |||
- | echo -e " | ||
- | / | ||
- | |||
- | |||
- | mv -f / | ||
- | chown apache / | ||
- | chmod a+w / | ||
- | chcon -v --type=httpd_sys_content_t / | ||
- | - create the script to calculate the number of sessions top-20 / | ||
- | s=`echo " | ||
- | ip=`printf ' | ||
- | echo -n $ip | ||
- | } | ||
- | |||
- | zcat $1 | awk -F ' | ||
- | |||
- | head -20 tmp$$$ > tmp2$$$ | ||
- | |||
- | echo -e " | ||
- | while read p; do | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | done < tmp2$$$ | ||
- | |||
- | |||
- | rm -f tmp$$$ tmp2$$$ | ||
- | |||
- | </ | ||
- | - install bc< | ||
- | - create the script / | ||
- | - create the script top-20 / | ||
- | # usage: | ||
- | # by source ip | ||
- | #./topsize arch/ | ||
- | # by destination ip | ||
- | #./topsize arch/ | ||
- | # | ||
- | |||
- | import sys, os, logging, ConfigParser, | ||
- | |||
- | def main(): | ||
- | delim=' | ||
- | accumulater={} | ||
- | for line in openinfile(sys.argv[1]): | ||
- | acc=long(0) | ||
- | fields = line.rstrip(' | ||
- | if(sys.argv[2]==" | ||
- | # by src | ||
- | | ||
- | acc=accumulater[fields[5]] | ||
- | accumulater[fields[5]]=acc+long(fields[1]) | ||
- | | ||
- | accumulater[fields[5]]=long(fields[1]) | ||
- | if(sys.argv[2]==" | ||
- | #by dsc | ||
- | try: | ||
- | acc=accumulater[fields[7]] | ||
- | accumulater[fields[7]]=acc+long(fields[1]) | ||
- | | ||
- | accumulater[fields[7]]=long(fields[1]) | ||
- | |||
- | for key, value in accumulater.iteritems(): | ||
- | print str(value)+' | ||
- | |||
- | |||
- | # open input file | ||
- | def openinfile(filename): | ||
- | if filename is None: | ||
- | inf = sys.stdin | ||
- | logging.debug(" | ||
- | else: | ||
- | if " | ||
- | inf = gzip.open(filename, | ||
- | else: | ||
- | inf = open(filename, | ||
- | logging.debug(" | ||
- | return inf | ||
- | |||
- | def ipv4str(ipv4): | ||
- | return str((ipv4 >> 24) & 0xFF) + ' | ||
- | |||
- | if __name__ == " | ||
- | main() | ||
- | |||
- | </ | ||
- | - add the line to the / | ||
- | - configure DPI settings< | ||
- | netflow_full_collector_type=1 | ||
- | netflow_dev=eth2 | ||
- | netflow_timeout=10 | ||
- | #!!!here the source ip should be specified | ||
- | netflow_full_collector=127.0.0.1: | ||
- | netflow_passive_timeout=20 | ||
- | netflow_active_timeout=60 | ||
- | </ | ||
- | ==== Working with scripts ==== | ||
- | If you've configured fasdpi properly the ipfixreceiver will start to receive data in the / | ||
- | cd / | ||
- | ./topcnt flow/ | ||
- | ip hits | ||
- | 77.XXX.XX.64 | ||
- | 77.88.8.8 | ||
- | 128.128.128.8 | ||
- | 77.88.8.1 | ||
- | ... | ||
- | 77.XXX.XX.208 | ||
- | </ | ||
- | observe that one ip info from the top is quite different, it means the address is to be subjected the DDoS attack and is overflowed from the outside. | ||
- | Check the top by size all over the src and dst IP: | ||
- | ./topsize arch/ | ||
- | 5380.01 77.XXX.XX.64 | ||
- | 165.881 81.XXX.XXX.79 | ||
- | ... | ||
- | 27.2184 74.XXX.XXX.27 | ||
- | observe that at the moment this IP received and send 5.4 GB of traffic, the next only 226 MB. Thus, the assumption about DDoS attack on IP = 77.XXX.XX.64 is confirmed. We move this address to the blackhole, the channel capacity is not enough, so it can be blocked only by the superior provider using the null route. | ||
- | |||
- | ==== httpd configuration ==== | ||
- | If you have http on your server where the IPFIX is reveived then it can be specified in the / | ||
- | < | ||
- | < | ||
- | Options Indexes FollowSymLinks | ||
- | AllowOverride None | ||
- | Order allow,deny | ||
- | Allow from all | ||
- | </ | ||
- | |||
- | Alias / | ||
- | </ | ||
- | It is desirable to add an access restriction, | ||
- | Accordingly, | ||
- | < | ||
- | http://< | ||
- | </ | ||
- | {{ : | ||
- | ==== So what does that leave us? ==== | ||
- | It is interesting to understand if there is a possibility simply to block an ip from the outside? Or there present a couple of dozen? \\ | ||
- | Create a script for calculating the attack power / | ||
- | < | ||
- | #!/bin/bash | ||
- | |||
- | function getipv4() { | ||
- | s=`echo " | ||
- | ip=`printf ' | ||
- | echo -n $ip | ||
- | } | ||
- | |||
- | zcat $1 | grep $2 | awk -F ' | ||
- | |||
- | echo -e " | ||
- | echo -n " | ||
- | head -20 tmp$$$ > top20$$$ | ||
- | while read p; do | ||
- | | ||
- | | ||
- | | ||
- | done < | ||
- | |||
- | rm -f tmp$$$ top20$$$ | ||
- | </ | ||
- | launch it, put the decimal IP representation from () within the TOP-20 sessions as the second option: | ||
- | < | ||
- | ./topip ' | ||
- | ip hits | ||
- | unique ip=58261 | ||
- | 202.92.200.6 | ||
- | 110.76.131.6 | ||
- | 119.235.28.59 | ||
- | 38.70.202.194 | ||
- | 177.38.144.14 | ||
- | 138.204.18.18 | ||
- | 212.119.180.222 | ||
- | 88.220.134.2 | ||
- | 200.186.13.86 | ||
- | ... | ||
- | </ | ||
- | As shown in the table above DDoS attack involves 58 thousands of addresses. | ||
- | ===== Related links ===== | ||
- | * [[https:// | ||
- | |||
- | |||