Script to enable/disable CloudFlare DDoS protection automatically

Some of you may regularely see application layer 7 attacks on your sites that are behind CloudFlare, apparently L7 attacks are usually the only attacks that can shutdown a site covered by CloudFlare (if you don’t leak your origin IP).

The normal solution for these attacks is to go to the CloudFlare control panel and enable “I’m under attack” mode, but what if you’re not online to do this or if you don’t instantly notice an attack is coming in?
It gets even worse: If the attack runs for a long time without you taking any action, CloudFlare will temporarily route all traffic directly to the origin IP (exposing it to the attacker). You’d have to watch your sites for attacks constantly to not risk getting temporarily routed directly to your origin IP.

That’s why I created a simple script to automatically turn CloudFlare’s DDoS protection page on/off in case of an attack.

The script watches the server load and if it’s over a certain threshold, acts accordingly.

For this script you need to have curl installed:

apt-get install curl

First let’s create a directory to work in:

mkdir /etc/ddos

Here’s the script that enables the DDoS protection page:

nano /etc/ddos/ddos.sh

Content of the file:

cat /proc/loadavg | colrm 6 > ddos.ini
FILE=ddos.ini
grep -w "[0.00-6.00]" $FILE >/dev/null 

if [ $? -eq 0 ]
then
 exit
else
 sh /etc/ddos/attack.sh
fi

Let me explain everything that the script does:

– cat /proc/loadavg | colrm 6 > ddos.ini #grabs the server load and saves it into a file called ddos.ini

– grep -w “[0.00-6.00]” $FILE >/dev/null #checks if the server load is between 0 and 6 (you can change that to different values)

– if [ $? -eq 0 ] #If the server load is between 0 and 6, the script will do nothing

– else #If it is not between 0 and 6, we will run /etc/ddos/attack.sh, the file which enables the DDoS protection page

We also need to create the script, that will enable the DDoS protection page:

nano /etc/ddos/attack.sh

Content of the script:

curl https://www.cloudflare.com/api_json.html \
 -d 'a=sec_lvl' \
 -d 'tkn=tkn' \
 -d 'email=mail@domain.com' \
 -d 'z=domain.com' \
 -d 'v=help'

Let me explain this script aswell:

– curl https://www.cloudflare.com/api_json.html \ #requests access to the CloudFlare API

-d ‘a=sec_lvl’ \ #chooses “security level” as the option to change

-d ‘tkn=token’ \ #Your CF token, you can find it here (API key)

-d ’email=mail@domain.com’ \ #Your CloudFlare E-Mail-Address

-d ‘z=domain.com’ \ #Your domain that you want to protect

-d ‘v=help’ #Changes the security level to “I’m under attack” (enables the DDoS protection page)

 

After saving both scripts, make them executable:

chmod u+x /etc/ddos/ddos.sh
chmod u+x /etc/ddos/attack.sh

Now you can run ddos.sh as a cronjob every 15 seconds to constantly check for a high server load and enable the CloudFlare DDoS protection page accordingly:

crontab -e

At the end of the file add this:

* * * * * sh /etc/ddos/ddos.sh
* * * * * ( sleep 15 ; sh /etc/ddos/ddos.sh )
* * * * * ( sleep 30 ; sh /etc/ddos/ddos.sh )
* * * * * ( sleep 45 ; sh /etc/ddos/ddos.sh )

An example of how the file could look like:

# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
* * * * * sh /etc/ddos/ddos.sh
* * * * * ( sleep 15 ; sh /etc/ddos/ddos.sh )
* * * * * ( sleep 30 ; sh /etc/ddos/ddos.sh )
* * * * * ( sleep 45 ; sh /etc/ddos/ddos.sh )

Great, you now have a script that checks for high server load every 15 seconds and enables the CloudFlare DDoS protection page, if it finds a high server load (in this case >6), but how do you automatically remove the protection page if the attack ceases?

Let’s create another script to turn off the protection page:

nano /etc/ddos/unblock.sh

Content of the file:

cat /proc/loadavg | colrm 6 > ddos.ini
FILE=ddos.ini

grep -w "[0.00-5.00]" $FILE >/dev/null

if [ $? -eq 0 ]
then
 sh /etc/ddos/noattack.sh
else
 exit
fi

The file does the same stuff as the ddos.sh file, but in this case runs the script, that disables the DDoS protection page if the server load is in between 0 and 5.

Let’s also create the script that disables the DDoS protection page:

nano /etc/ddos/noattack.sh

Content of the file:

curl https://www.cloudflare.com/api_json.html \
 -d 'a=sec_lvl' \
 -d 'tkn=tkn' \
 -d 'email=mail@domain.com' \
 -d 'z=domain.com' \
 -d 'v=high'

You’ll see that the script does the same thing as the other script, but it will change the security level to “high” (disables the protection page), you could also choose “med”, “low” or “eoff” (essetially off) as the default level here.

Grant execution rights to both of the files:

chmod u+x /etc/ddos/unblock.sh
chmod u+x /etc/ddos/noattack.sh

Add the unblock.sh file to your cronjob file, in this case the file will only run every 30 minutes, that’s because once the CloudFlare DDoS protection page is enabled, your load will decrease as the attacks won’t reach your server anymore. If you would run the script that causes the protection page to be disabled again every minute, it would disable the page all the time and enable it again then, causing downtime. By running this script every 30 minutes, you have a fair buffer between attacks and the possible downtime is essentially 15 seconds at max.

crontab -e

Add:

10,40 * * * * sh /etc/ddos/unblock.sh

Your crontab file should now look similar to this:

# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
* * * * * sh /etc/ddos/ddos.sh
* * * * * ( sleep 15 ; sh /etc/ddos/ddos.sh )
* * * * * ( sleep 30 ; sh /etc/ddos/ddos.sh )
* * * * * ( sleep 45 ; sh /etc/ddos/ddos.sh )
10,40 * * * * sh /etc/ddos/unblock.sh

There you go, now once you receive an attack that affects server load (that’s usually 100% of the attacks, if you’re behind CloudFlare and the attacker doesn’t know the origin IP of your server), within 15 seconds the DDoS protection page will be automatically enabled and after some time the DDoS protection page will disable itself again.

One thought on “Script to enable/disable CloudFlare DDoS protection automatically

  1. Would you consider making a script to do the same thing as this but running it on a separate host?
    Example: Server -> Webhost. The server would check if the webhost load is high. Rather than the server detecting the local load. I am very interested in this.

Leave a Reply

Your email address will not be published. Required fields are marked *