📜 ⬆️ ⬇️

A practical episode of the fight against DDoS

One young man loved to swear on a thematic resource. And for this he was regularly banned. And once they took, and not unban.

Offended the young man, and decided to take revenge. I saved up money, took it and ordered a DDoS resource. Fortunately, this is not a criminal offense in the Russian Federation, unfortunately, a punishable act.

The DDoS, for which the young man managed to accumulate, was to send the same HTTP requests to the army of bots.
')
As usual, for picky administrators there were no satisfactory looking solutions that simply read the HTTP log and give out the addresses that should be banned.
Therefore, I had to build my own amusement park, with this and these same ones. A comrade metakey managed to write the logic of assigning an ip to a ban, and your humble servant - set up the rest of the harness.

Those who (prefers) read Hemingway in the original can immediately go here . There and the code can also be found.



For all others and just lazy - I will continue here. Sorry, that without pictures. But everything in the case ...

log2ban



How log2ban works


To detect bots, each request to the server is marked with an identifier from the properties of the request (for example, from an IP address and URL: "1.2.3.4/login.php"). When the number of calls with a specific ID reaches the set limit, within the time window of the discovery, the client IP is passed as an argument for an external command (BAN_IP_COMMAND) or collected for a batch block (see “List Blocking”).

Log2ban is working on server logs in real time, and is not intended for use as a log archive analyzer. You should use the firewall tools to block the system itself (settings and scripts for ipset are attached in the example).

The script reads the log in real time, using, for example, "tail -f" or a similar command, as specified in the configuration. If the command sends EOF, log2ban will exit. If the command stops writing journal entries to standard output, the log2ban process will hang forever.

Customization


The default Apache / Nginx log template is supported. Changes made to the format should be reflected in the variable ACCESS_LOG_RECORD_FORMAT.

You can also configure discovery rules. The most important parameter is TOLERANCE_MARGIN (the number of hits in the window). The second most important are WINDOW_SIZE (window size in slots) and SLOT_INTERVAL. (slot size in seconds) A shorter interval and an increased size means better detection (and worse performance).

To change the rules for calculating IDs, change the "create_server_hit_id" function.

To change the rules for skipping lines in the logs, change the function "skip". By default, requests for static file types are skipped.

Blocking lists


To use blocking by lists, turn on the database, process the logs for a while, and then execute

python log2ban.py print (banned | allbanned)

print the collected IP addresses to stdout. “Banned” will print only new IP addresses (since the last print banned), while “allbanned” will print each prohibited IP, regardless of whether it was previously printed or not.

After several days, the IP addresses will be unbanned to get their list:

python log2ban.py print (unbanned)

This command will print every IP that was banned during the current_time period - DAYS_UNBAN, and will delete the entries from the database.

Performance


log2ban is fast enough by itself, but for very fast-growing logs, processing requests can be a problem. Consider disabling the registration of requests for static resources, such as images, scripts and style sheets. Further optimization may include a simpler log format (CSV), instead of using the default format, which is processed by the apachelog module through regular expressions.

Firewall installation and integration



The process is described for Debian Squeeze 6.0, for other distributions it may differ.

Install ipset:

sudo apt-get install module-assistant xtables-addons-source
sudo module-assistant prepare
sudo module-assistant auto-install xtables-addons-source
depmod -a


Check that it works.
ipset -L


If you get a non-empty response, such as the error 'Module ip_set not found', then ipset is not installed correctly. Googling this problem for your specific installation. The general idea is that the ip_set kernel module should be locally compiled and loaded into the kernel.

Install MongoDB, Python, and PIP:


sudo apt-get install mongodb python-pip


Install modules for python:

sudo pip install apachelog pexpect pymongo


Clone the log2ban repository:

git clone git://github.com/unicodefreak/log2ban.git


In the log2ban.py file, configure the following command, if necessary.

ECHO_LOG_COMMAND = "tail -f /var/log/nginx/access.log"


Add the following text to /etc/logrotate.d/nginx:

/var/log/nginx/*log {
daily
rotate 10
missingok
notifempty
compress
sharedscripts
postrotate
[ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
/etc/init.d/log2ban stop
/etc/init.d/log2ban start
endscript
}


Install scripts

sudo mkdir /opt/log2ban
sudo cp log2ban/log2ban.py /opt/log2ban/
sudo cp log2ban/ipset-control.sh /opt/log2ban/
sudo cp log2ban/init-scripts/log2ban-debian.sh /etc/init.d/log2ban
sudo chmod +x /etc/init.d/log2ban
sudo chmod +x /opt/log2ban/ipset-control.sh


Run MongoDB
sudo /etc/init.d/mongodb start


Run log2ban

sudo /etc/init.d/log2ban start


Add the following command to the root cron script, for example, to update addresses every 5 minutes
*/5 * * * * /opt/log2ban/ipset_control.sh update


Let him work for a while. Check if any IPs are blocked:
sudo ipset -L


If the list is similar to the truth, then the last step is to connect iptables.

Add a line:

-A INPUT -m set --match-set autoban src -j DROP

in the /etc/firewall.conf file and execute

sudo /etc/init.d/networking restart


Everything, you can open the champagne ... and other drinks to taste.

Source: https://habr.com/ru/post/134331/


All Articles