26 March 2017

Why Whitelisting Your Server After Cloudflare Setup is Very Important

TLDR; Your server has a public IP Address that is globally accessible. To prevent attacks, deny all access to your global IP address and allow only Cloudflare's IP addresses -- don't skip whitelisting because your server is being scanned constantly by its public address and still accessible for attacks through its public IP address if you skipped whitelisting.

The Cloudflare company made headlines in the news recently and much was discussed about whether or not they are a good choice for your hosting.  I am not interested in that debate, and if you continue reading, I assume you aren't either.  I assume you are using Cloudflare and are happy with it.

I have watched an read many videos and articles about setting yourself up with Cloudflare and many of them tell you to turn on all the advanced settings after setup such as HSTS and other perks offered by the product.  Those options are great and you should turn on those as well, but I have found countless guides never mention how important it is to whitelist.  The Cloudflare company offers a video that speaks of it, but recommends you ask for help from someone technical.  Your choice to use your host's firewall, your ISPs, or your webserver's tools to deny/allow the Cloudflare IP ranges as the right solution varies based on your needs and the tools you use.  I can show you what happens if you don't.

So, after you setup Cloudflare, the GUI will show you a list of to dos which mention whitelisting Cloudflare's IPs.  Go to that page.  A sample of what it looks like is below.

Cloudflare provides a list of IPv4 and IPv6 Addresses to whitelist
Cloudflare's IP Whitelisting

The image above shows all the IP address blocks that Cloudflare will use to connect to your web server.  After setting up Cloudflare, deny access to your web server ports 80 (http) and 443 (http secure) to everyone except Cloudflare IP blocks above and your own access points.  Don't know your access point IPs?  That is one of the many reasons why this is hard for Cloudflare or anyone else to tell people how to perform the whitelisting setting.

I can, provide an example of what happens if you don't whitelist.  I built two servers, which will not be around for many of you to see since I have no need to pay for hosting these.  But, you will be able to see this on on your own server.  If you already performed the whitelisting, you can read something else, but if you are interested then read on.

The following server whitelists only Cloudflare servers in the list above.  The first log entry begins on 08 Mar 2017 as seen below.  The last entry ends today.

root@crumpton:/var/log # head httpd-access.log ::1 - - [08/Mar/2017:01:17:32 +0000] "GET / HTTP/1.0" 200 18427

Servers on the Internet are scanned constantly with many looking for vulnerabilities.  There are numerous scans but we'll focus on PHP attacks.  The scan below is looking for PHP administrative scripts and/or vulnerabilities.  Whitelisting was enabled on this server after the following scan edited for brevity below was complete.  Notice, the command prompt finishes and as I mentioned above, there are no more scans at all on this server since whitelisting was completed.

root@crumpton:/var/log # grep php httpd-access.log 
1XX.9X.8X.XX0 - - [08/Mar/2017:20:09:42 +0000] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 226
 - - [08/Mar/2017:20:09:42 +0000] "GET /phpmyadmin/scripts/setup.php HTTP/1.1" 404 226
 - - [08/Mar/2017:20:09:42 +0000] "GET /pma/scripts/setup.php HTTP/1.1" 404 219
1X1.X6.XXX.97 - - [08/Mar/2017:23:30:46 +0000] "GET /phpmyadmin/scripts/setup.php HTTP/1.0" 404 226

So now, lets look at a Cloudflare server without whitelisting.  This server has been whitelisted for seven days now.  But, I am only going to show you the log for yesterday.  First, a count of just the phpMyAdmin based attacks reveals 72 attempts to access phpMyAdmin, which isn't installed. There are so many scans in the file that posting it would make this blog too long to read through.  This server isn't advertised and almost all of the requests are from scanning tools.  The remainder are me playing with it.

azcrumpty@LAMP:/var/log/nginx$ grep -i phpmy access.log.1 | wc -l72
Here is a sample of what they look like:

XX.8X.XX.X1 - - [26/Mar/2017:03:53:03 +0000] "GET /phpMyAdmin-2.9.0/scripts/setup.php HTTP/1.1" 404 152 "-" "ZmEu"XX.8X.XX.X1 - - [26/Mar/2017:03:53:04 +0000] "GET /phpMyAdmin-2.9.2/scripts/setup.php HTTP/1.1" 404 152 "-" "ZmEu"XX.8X.XX.X1 - - [26/Mar/2017:03:53:04 +0000] "GET /phpMyAdmin- HTTP/1.1" 404 152 "-" "ZmEu"XX.8X.XX.X1 - - [26/Mar/2017:03:53:04 +0000] "GET /phpMyAdmin- HTTP/1.1" 404 152 "-" "ZmEu"XX.8X.XX.X1 - - [26/Mar/2017:03:53:04 +0000] "GET /phpMyAdmin- HTTP/1.1" 404 152 "-" "ZmEu" 

The server is being aggressively scanned compared to the whitelisted one before it where no more scans have shown up since whitelisting was enabled.

Whitelisting also saves bandwidth since only Cloudflare requests come in instead of the server being forced to respond to hacking attempts.  Again, the whitelisted server above has no noise, just requests coming in from Cloudflare from people using the site.

So what can you do?  Do perform the whitelisting and check your web server for scans.  I can't list all of the scans you could see as I am not familiar with every product available for web servers.  Check your web server logs for similar scans and make sure you did the whitelisting correctly.  You know your server's IP Address, so test it at coffee shops, work, free Wi-Fi's to see if you still see your site by entering its IP address directly into the browser yourself.  If you see content, you are still vulnerable to scans.

How do attacks work?  Web servers are assigned numbers and the scanning tools go through each IP address looking for trouble.  Cloudflare doesn't protect you from this type of scan unless you whitelist.  Sure, they hide your IP, if you did that correctly, but IP scanners crawl through every IPv4 number they can and if they retrieve the starting page (index.html), you can identify the site because the welcome page usually indicates the brand. If you didn't hide your IP correctly, you get the following warning from the customer panel in Cloudflare that tells you about your IP leak.

Cloudflare will inform you if you are leaking your servers IP Address
DNS IP Leak Warning

If you search Youtube for how to bypass Cloudflare sites, you will see the favored method is to use the non whitelisted public IP address. DNS leaks, should you have any, are a favorite way to find your server's IP address and launch attacks.  Such attacks will be extremely difficult if not impossible to do if you whitelist properly as shown in the first example.  Such attacks will continue or possibly succeed if you didn't whitelist as shown in the second example.  In summary, the Linux server above is scanned, and the DNS does leak the IP since the same server hosts mail (MX record gives it away). But, the whitelisted FreeBSD server and non-whitelisted Linux server are for demo purposes only and will not exist in April.  Cloudflare can not stop attacks directly to your server's public address. Whitelisting does that.  Cloudflare does support SSL Mutual Authentication called Authenticated Origin Pulls on their site which is another way ensure only their servers can talk to your web server. But that is for your SSL port (443) and doesn't help your unsecured port if it is open, too.  Cloudflare gives your host a Cloudflare  IP address and your server can still be attacked through it, but the attacker has to face all of Cloudflare's security wisdom and might.

The FreeBSD server is whitelisted and hasn't seen scans for several weeks. The pf rules are sloppy and were done quickly for example purposes only.  Don't use sloppy firewall rules on your host should you whitelist via this method -- use a firewall building tool.  I abbreviated the pf.conf rules to the main points.

# cat /etc/pf.confext_if="hn0"
home = "{  }"
cloudflare = "{ , , , , , , , , , , , , , , }"
azure = ""

block all
pass in quick on $ext_if inet from $home to any
pass in quick on $ext_if inet from $azure to any 
pass in quick on $ext_if proto tcp from  $cloudflare to port { http, https }
I list all of the Cloudflare IP networks and allow them to pass along with my home block and local Azure systems. Avoid host based rules since you can easily lock yourself out of your server.  I should have added the Cloudflare IP whitelist to the security group in the cPanel below but I found rapidly entering them in the HTTP interface slow and clunky.  In the real world, your provider's GUI will probably be the best choice.

An example of the GUI without the rules above is below.  You see I also whitelist admin ports.

Firewall rules for inbound connections show administrative ports SSH and WEBMIN are whitelisted
Firewall Rules in cPanel