Experiencing DDoS attacks may seem like inevitable collateral damage when publishing services on the internet, and the more prominent a site or service is, the more likely it is to become the target of an attack at some point. This problem affects millions of services worldwide each year, and the number of attacks is increasing exponentially. For this reason, at Clouding we offer flexible Anti-DDoS protection by default and configurable Strict Anti-DDoS Filtering.
Currently, a denial-of-service attack is quite easy to carry out and does not require much knowledge; every day there are more tools that make it easy. However, it is also possible to reduce the chances of a DDoS attack affecting a website or service through proper configuration and added protection. In particular, a web server will need dedicated DDoS mitigation through a proxy, especially because traffic is usually encrypted (HTTPS).
We recommend using Cloudflare for a website; they offer unlimited DDoS attack mitigation to maintain performance and availability. Additionally, we will explain how to configure blocking to allow access to the web server exclusively through Cloudflare. First, you will need to configure all the server's domains in Cloudflare and in Proxy mode (except for the records needed for email to work).
How to Configure the Web Server for Cloudflare
When a website's traffic is routed through Cloudflare's network, it acts as a reverse proxy. As a result, when responding to requests and logging them, the origin server returns a Cloudflare IP address. Therefore, the web server will need to be configured to obtain the visitor's real IP using the CF-Connecting-IP header.
We recommend using systemd to automate the addition of Cloudflare IP addresses, so that if they add another address, the service will update the configuration for NGINX. To do this, you will need to create a service and a timer to automatically restore visitors' real IP addresses for NGINX.
First, you will need to create a service file for systemd. You can do this with a text editor such as nano or vim. For example, you can run the following to create and edit it with nano:
# nano /etc/systemd/system/cloudflare-ip-reset.service
The content should be as follows:
[Unit]
Description=Cloudflare IP reset service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cloudflare-ip-reset
[Install]
WantedBy=multi-user.target
In this file, we specify that the service is named "Cloudflare IP reset service" and that it will run once with the command /usr/local/bin/cloudflare-ip-reset. We also specify that the service should be available when the "multi-user.target" target is reached.
Next, make sure that the NGINX configuration includes the conf.d directory:
# grep -Ri include /etc/nginx/nginx.conf
If it does, create a file to specify the header and store Cloudflare's IP addresses:
# touch /etc/nginx/conf.d/cloudflare.conf
Once you have created this file, you will need to create a script that will run when the service starts:
# nano /usr/local/bin/cloudflare-ip-reset
This script must perform the task of restoring Cloudflare visitors' real IP addresses for NGINX. You can do this with a programming language such as Python or Bash. For example, here is a possible Bash script that could do this:
#!/bin/bash
# Path to the configuration file for Cloudflare
CLOUDFLARE_RUTA=/etc/nginx/conf.d/cloudflare.conf
# Clear the file and add a comment
echo "# Configuración para Cloudflare" > $CLOUDFLARE_RUTA;
# Add Cloudflare IPv4 addresses
echo "" >> $CLOUDFLARE_RUTA;
echo "# - IPv4" >> $CLOUDFLARE_RUTA;
for i in `curl -s -L https://www.cloudflare.com/ips-v4`; do
echo "set_real_ip_from $i;" >> $CLOUDFLARE_RUTA;
done
# Add Cloudflare IPv6 addresses
echo "" >> $CLOUDFLARE_RUTA;
echo "# - IPv6" >> $CLOUDFLARE_RUTA;
for i in `curl -s -L https://www.cloudflare.com/ips-v6`; do
echo "set_real_ip_from $i;" >> $CLOUDFLARE_RUTA;
done
# Configure the Cloudflare header
echo "" >> $CLOUDFLARE_RUTA;
echo "real_ip_header CF-Connecting-IP;" >> $CLOUDFLARE_RUTA;
# Reload NGINX configuration
nginx -s reload
In this script, Cloudflare visitors' real IP addresses for NGINX are first obtained from the NGINX configuration file. Then, the new real IP addresses of Cloudflare visitors are obtained from Cloudflare's website. If the real IP address has changed, the NGINX configuration file is updated and the NGINX service is reloaded.
Once you have created the script, you must make sure it has execute permissions:
# chmod 700 /usr/local/bin/cloudflare-ip-reset
You can then test it manually by running the command:
# systemctl start cloudflare-ip-reset && journalctl --unit=cloudflare-ip-reset --no-pager
To configure a timer so that the service runs periodically, you will need to create a timer file for systemd. You can do this with a text editor such as nano or vim. For example, you can create a file named "cloudflare-ip-reset.timer" in /etc/systemd/system:
# nano /etc/systemd/system/cloudflare-ip-reset.timer
With the following content:
[Unit]
Description=Cloudflare IP reset timer
[Timer]
OnBootSec=10min
OnUnitActiveSec=24h
[Install]
WantedBy=multi-user.target
In this file, we specify that the timer is named "Cloudflare IP reset timer" and that it will start 10 minutes after the system starts. We also specify that the timer will activate every twenty-four hours after it starts. We also specify that the timer should be available when the "multi-user.target" target is reached.
Once you have created this file, you must link it to the service you just created. You can do this by running the command:
# systemctl enable --now cloudflare-ip-reset.timer
This command will enable the timer and also start it immediately.
From that point on, the service will run automatically every 24 hours and restore Cloudflare visitors' real IP addresses for NGINX if they have changed. You can check the status of the timer and service by running the command:
# systemctl status cloudflare-ip-reset.timer
Cloudflare no longer updates or supports mod_cloudflare. However, if you use an Apache web server, you can use Apache's official mod_remoteip module to log your visitor's original IP address.
To enable the mod_remoteip module on your Apache web server, run the following:
# a2enmod remoteip
Next, you will need to update the server configuration for the combined LogFormat entry in apache.conf or the sites, replacing %h with %a so that the real address appears in the logs:
# nano /etc/apache2/apache2.conf
For example, if your current LogFormat entry looks like this:
LogFormat "%h %l %u %t "%r" %>s %O "%{Referer}i" "%{User-Agent}i"" combined
You must update LogFormat as shown below:
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
We recommend using systemd to automate the addition of Cloudflare IP addresses, so that if they add another address, the service will update the configuration for Apache. To do this, you will need a service and a timer to automatically restore visitors' real IP addresses for Apache.
First, you will need to create a service file for systemd. You can do this with a text editor such as nano or vim. For example, you can run the following to create and edit it with nano:
# nano /etc/systemd/system/cloudflare-ip-reset.service
The content should be as follows:
[Unit]
Description=Cloudflare IP reset service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cloudflare-ip-reset
[Install]
WantedBy=multi-user.target
In this file, we specify that the service is named "Cloudflare IP reset service" and that it will run once with the command /usr/local/bin/cloudflare-ip-reset. We also specify that the service should be available when the "multi-user.target" target is reached.
Create a configuration file to specify the header and store Cloudflare's IP addresses:
# touch /etc/apache2/conf-available/remoteipcloudflare.conf
Once you have created this file, you will need to create a script that will run when the service starts:
# nano /usr/local/bin/cloudflare-ip-reset
This script must perform the task of restoring Cloudflare visitors' real IP addresses for Apache. You can do this with a programming language such as Python or Bash. For example, here is a possible Bash script that could do this:
#!/bin/bash
# Path to the configuration file for Cloudflare
CLOUDFLARE_RUTA=/etc/apache2/conf-available/remoteipcloudflare.conf
# Clear the file and add a comment
echo "# Configuración para Cloudflare" > $CLOUDFLARE_RUTA;
# Configure the Cloudflare header
echo "RemoteIPHeader CF-Connecting-IP" >> $CLOUDFLARE_RUTA;
# Add Cloudflare IPv4 addresses
echo "" >> $CLOUDFLARE_RUTA;
echo "# - IPv4" >> $CLOUDFLARE_RUTA;
for i in `curl -s -L https://www.cloudflare.com/ips-v4`; do
echo "RemoteIPTrustedProxy $i" >> $CLOUDFLARE_RUTA;
done
# Add Cloudflare IPv6 addresses
echo "" >> $CLOUDFLARE_RUTA;
echo "# - IPv6" >> $CLOUDFLARE_RUTA;
for i in `curl -s -L https://www.cloudflare.com/ips-v6`; do
echo "RemoteIPTrustedProxy $i" >> $CLOUDFLARE_RUTA;
done
# Reload Apache configuration
systemctl restart apache2
In this script, Cloudflare visitors' real IP addresses for NGINX are first obtained from the Apache configuration file. Then, the new real IP addresses of Cloudflare visitors are obtained from Cloudflare's website. If the real IP address has changed, the Apache configuration file is updated and the service is reloaded.
Once you have created the script, you must make sure it has execute permissions, and then you can test it manually by running the command:
# chmod 700 /usr/local/bin/cloudflare-ip-reset && systemctl start cloudflare-ip-reset && journalctl --unit=cloudflare-ip-reset --no-pager
To configure a timer so that the service runs periodically, you will need to create a timer file for systemd. You can do this with a text editor such as nano or vim. For example, you can create a file named "cloudflare-ip-reset.timer" in /etc/systemd/system with the following content:
[Unit]
Description=Cloudflare IP reset timer
[Timer]
OnBootSec=10min
OnUnitActiveSec=24h
[Install]
WantedBy=multi-user.target
In this file, we specify that the timer is named "Cloudflare IP reset timer" and that it will start 10 minutes after the system starts. We also specify that the timer will activate every twenty-four hours after it starts. We also specify that the timer should be available when the "multi-user.target" target is reached.
Once you have created this file, you must link it to the service you just created. You can do this by running the command:
# systemctl enable --now cloudflare-ip-reset.timer
This command will enable the timer and also start it immediately.
From that point on, the service will run automatically every 24 hours and restore Cloudflare visitors' real IP addresses for Apache if they have changed. You can check the status of the timer and service by running the command:
# systemctl status cloudflare-ip-reset.timer
Next, enable the Apache configuration:
# a2enconf remoteipcloudflare
Finally, test the Apache configuration:
# apache2ctl configtest
If you get "Syntax OK", restart Apache
# systemctl restart apache2
For more information about mod_remoteip, see the Apache module documentation.
On Plesk with NGINX, you can use the script they provide on their support page:
# curl -L -so /root/cf.sh https://plesk.zendesk.com/hc/article_attachments/4406613093138/cf.sh && chmod 700 /root/cf.sh && sh /root/cf.sh
However, remember to add a scheduled task or create a service to run periodically to update Cloudflare's IP addresses.
If you use only Apache in Plesk or are looking for a configuration for just one domain, the following official Plesk support article has more information: Incorrect IP addresses are logged by Plesk behind a Cloudflare or Google Cloud Load Balancing
The cPanel configuration when using Apache/httpd is quite similar to an Apache configuration on a Linux distribution. The following official cPanel support article has more information: Restoring visitors IP with mod_remoteip
However, remember to update Cloudflare's IP addresses in the configuration. You can check the Apache configuration tab for an example using systemd.
To configure LiteSpeed to restore visitors' real IPs, you can use the OpenLiteSpeed Console or LiteSpeed WebAdmin under Configuración del servidor and Configuración general. You must set "Usar IP del cliente" in the header to "Sólo IP de confianza" and add CloudFlare's IPs/Subnets to the trusted list. The following official OpenLiteSpeed article has more information: Show Real Visitor IP Instead of CloudFlare IPs.
However, remember to update Cloudflare's addresses periodically. You can use a scheduled task or a systemd service as in the configuration on the Apache tab.
From IIS 8.5 onward, custom logging is a built-in option. See IIS Enhanced Logging.
- In IIS Manager, double-click Registro in the Acciones menu for the site you are working on.
- Once this opens, select W3C as the format and then click Seleccionar Campos next to the format drop-down menu in the Archivo de registro subsection.
- Click Agregar Campo and add the CF-Connecting-IP header.
- Click Aceptar. You should see your new entry under Campos Personalizados. Click Aplicar when you are back in the Registro window.
- If this is successful, the log file should now have an underscore: You should also see the change in the fields:
- Restart the site, then W3SVC, and then the entire instance if the change does not appear immediately. When enhanced logging is used in IIS 8.5+, it does not restore the visitor's original IP at the application level.
If your web server does not appear in this article, you can consult the configuration directly on Cloudflare's official website under How to Restore Original Visitor IPs.
How to Allow Only Cloudflare (Linux)
To allow web access only through Cloudflare and block potential direct DDoS attacks, you can use a systemd service and timer. This will automatically update the iptables rules to allow current and future Cloudflare IP addresses and block all other web traffic.
Recommendation
We recommend filtering Cloudflare's IP addresses directly using the server's Firewall from Clouding profile, instead of using iptables rules as explained below. This way, the server will not have to process the packets, and its response time will not be affected.
First, create a service file with an editor. For example, with the nano editor:
# nano /etc/systemd/system/cloudflare-iptables.serviceAdd the following content to it:
[Unit]
Description=Cloudflare IPTables Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cloudflare-iptables
[Install]
WantedBy=multi-user.target
Next, save the changes and create another file for the service script:
# nano /usr/local/bin/cloudflare-iptablesWith the following content:
#!/bin/bash
# https://www.cloudflare.com/ips
# https://developers.cloudflare.com/fundamentals/get-started/setup/allow-cloudflare-ip-addresses/
CF4=$(curl -s https://www.cloudflare.com/ips-v4)
CF6=$(curl -s https://www.cloudflare.com/ips-v6)
# Clear previous rules (IPv4)
for i in $CF4; do
iptables -D INPUT -p tcp -m multiport --dports http,https -s "$i" -j ACCEPT 2>/dev/null
done
# Clear previous rules (IPv6)
for i in $CF6; do
ip6tables -D INPUT -p tcp -m multiport --dports http,https -s "$i" -j ACCEPT 2>/dev/null
done
# Get the list of Cloudflare IP addresses and allow only Cloudflare IP addresses in the iptables inbound filtering rule
for i in $CF4; do
iptables -A INPUT -p tcp -m multiport --dports http,https -s "$i" -j ACCEPT
done
for i in $(curl -s https://www.cloudflare.com/ips-v6); do ip6tables -I INPUT -p tcp -m multiport --dports http,https -s $i -j ACCEPT; done
for i in $CF6; do
ip6tables -A INPUT -p tcp -m multiport --dports http,https -s "$i" -j ACCEPT
done
# Block all unauthorized web traffic
# WARNING: If you experience an attack and CloudFlare discontinues your service, your site(s) will become inaccessible.
iptables -A INPUT -p tcp -m multiport --dports http,https -j DROP
ip6tables -A INPUT -p tcp -m multiport --dports http,https -j DROP
Make sure the script file has execute permissions by using the command:
# chmod +x /usr/local/bin/cloudflare-iptablesThen start and enable the service using the command:
# systemctl start cloudflare-iptables.service && systemctl enable cloudflare-iptables.serviceFinally, create a file for the timer:
# nano /etc/systemd/system/cloudflare-iptables.timerWith the following content:
[Unit]
Description=Cloudflare IPTables Timer
[Timer]
OnCalendar=daily
[Install]
WantedBy=timers.target
Finally, start and enable the timer using the command:
# systemctl start cloudflare-iptables.timer && systemctl enable cloudflare-iptables.timer
You can list the timers to see the next run:
# systemctl list-timers --allTo verify that the services work, you can run the following command:
# service cloudflare-iptables start && journalctl --unit=cloudflare-iptables --no-pagerWith this configuration, the service will run daily to update the iptables inbound filtering rule and allow only Cloudflare IP addresses, blocking all other unauthorized web traffic. Keep in mind that this is only an example and may require modifications depending on the server's specific configuration and security needs.
It is important to be careful when configuring iptables, as an incorrect configuration can negatively affect the performance and availability of the website or web service. Additionally, it is important to remember that this configuration only protects against DDoS attacks using Cloudflare filtering, so it is important to implement additional security measures to protect against other types of cyberattacks.
How to List the Addresses with the Most Accesses:
Additionally, the following command may interest you or be useful:
# cat /var/www/vhosts/*/logs/access_ssl_log | awk '{print $1}' | sort | uniq -c | sort -rn | headYou can use it to check whether any client has multiple access attempts. Typically, DDoS attacks use the same address for several connections, and you can use it to block those addresses. You can also adapt it as an example for any other web server.
Remember, if you have questions about this or any other issue related to your servers at Clouding, feel free to write to soporte@clouding.io We're here for whatever you need. Get in touch!