Here’s an old (over a year) post that’s been sitting in my queue for a while. Some things may be out of date.
Many web administrators use Cloudflare to mask their server’s IP address to protect against DDoS attacks. Cloudflare works by sitting between clients and the server. With Cloudflare running as a middleman, a server’s IP never needs to be revealed to the public, since public clients connect through Cloudflare. Any attacks are routed first to Cloudflare, who can provide defenses and protect the origin server. Unfortunately, there are many other ways that an attacker can still resolve the original server’s IP address, bypassing Cloudflare’s protection and attack the origin directly.
In this post, I’ll highlight some methods, provide a short background on how/why they work, and give steps on fixing them.
The most basic technique, used by almost all “Cloudflare IP Resolvers”, is brute-forcing DNS records. But first, let’s go over some background information on how this works. Suppose you are the web administrator in charge of example.com, with the IP address 18.104.22.168.
The classic diagram of Cloudflare is this:
In short, you handover your DNS management to Cloudflare. Your domain’s A record (depicted as “Your naked website” in the diagram) is now switched to Cloudflare IP address (“Cloudflare’s globally distributed network”. Now, all connections to example.com get send to Cloudflare’s IP addresses (eg, 222.222.xxx.xxx), instead of your original server’s (eg, 22.214.171.124), and Cloudflare reverse proxies requests between visitors and your origin server.
The issue is that Cloudflare only proxies HTTP/HTTPS connections (ports 80/443) from the open internet to your server’s IP address. So you won’t be able to access other services running on the origin server through example.com; Cloudflare servers do not respond to FTP (port 21), SSH (port 22), cPanel (port 2082), etc… So how does an administrator access these services? Here’s what Cloudflare recommends:
The solution is simply to create a new DNS record, such as direct.example.com that points to your original IP address. When you need to connect to the origin IP, you simply use direct.example.com instead of example.com.
Now, suppose you are an attacker. By pinging example.com and www.example.com, you realize that the website has Cloudflare enabled, which means example.com and www.example.com both have an IP address that belongs to Cloudflare.
Using the information in the “background” section above, you know the site administrator probably has other subdomains whose records point directly to the origin IP and are not protected by Cloudflare. Now, you can simply guess what they are and try pinging them. Some popular ones are “mail.example.com”, “ssh.example.com”, “ftp.example.com”, and “direct.example.com”. You can also run “host -a example.com” to list advertised DNS records.
This method is what all “Cloudflare IP resolvers/scripts” use. Here’s an example.
DNS resolution of Cloudflare websites has been a common attack vector so many careful web admins have already made sure that they don’t have any dangling subdomains. If you want to access the original server without any subdomains, you can create a completely separate domain (eg, connect.otherdomain.com) or just connect directly using your server’s IP address.
If you’re a site administrator setting up Cloudflare for your domain (example.com), it’s very likely that your website is already live and hosted on a public IP address (eg, 126.96.36.199).
If a website has been hosted on the same IP for awhile (~1 month), it’s likely that a public web crawler has accessed it. Many of these crawlers save this information, which can later be accessed.
An attacker can simply look up a website in hosting history databases and find out what the original IP address was before Cloudflare was set up.
Luckily, fixes are quite simple. If you’re launching a new website and want to hide your origin server’s IP, make sure you set up Cloudflare before you link your domain to your host.
If your original server’s IP is in a historical database, your best bet is to switch IP addresses. It shouldn’t be too hard buy/rent a new IP from your host. Make sure the old IP no longer points to the same server.
Outbound IP Leakage
Most people who want to protect themselves from DDoS attacks are sufficiently secure up to this point. Outbound IP leakage refers to your server sending clients its IP address, something that’s harder to keep track of.
The most common case of IP leakage I’ve seen is through outbound emails. Let’s say you run a popular forum, coolcats.com. You’ve taken precautions and don’t have any direct references to your origin server IP from DNS and run on Cloudflare. When users sign up for your forum, they receive a confirmation email. Unless you’ve manually configured an outbound email server, the default confirmation of most web server software is to use the local mail server. That means any email sent by the forum software has headers that contain the true origin server IP.
An attacker can look for a service running on the server that makes outbound connections. While email is the most common, anything that allows the user to direct the server to make an outbound connection is vulnerable. The attacker can trigger that outbound connection (eg, signing up for a forum that sends a confirmation email) and grab the origin server’s IP address from any metadata (eg, email headers) .
Make sure not to allow the local server to make outbound connections. For example, use another server or service (ie, Mailgun, external smtp server) to send email on behalf of your server.
The default configuration for web servers is to respond to all IPs that send a request, unless explicit whitelisting/blacklisting is enabled. This is how public facing websites should be set up — you want anyone in the world to be able to view your public content. When Cloudflare is enabled, however, all requests to the origin server are made from Cloudflare servers. For example, the domain example.com has an origin server with IP 188.8.131.52 and is serving a webpage with the content “Hello, World!”. If the site is behind Cloudflare, when a visitor requests example.com, the origin server sees a request from Cloudflare, which is acting as a reverse proxy, and sends “Hello, World!” to Cloudflare, which in turn sends it to the visitor. But if a visitor sends an HTTP request for example.com directly to the 184.108.40.206 IP address, the origin server will also respond with “Hello, World!”.
Knowing that a webserver is configured to respond to all IP addresses the same way, an attacker can verify a website’s origin server IP. If an attacker knows the general IP block where the origin server is located, they can scan for hosts that are up, and then send HTTP requests to the IPs directly. The code below shows a request to an IP asking for the content of example.com.
$ nc 220.127.116.11 80
GET / HTTP/1.1
If the data returned by this request is the same request as one to example.com (below), then it is highly likely that the IP address is the origin server for example.com
$ nc example.com 80
GET / HTTP/1.1
Using a tool like Zmap will allow an attacker to scan a massive IP block quickly and with few resources.
The easiest way to prevent this attack is to disallow non-Cloudflare IPs from connecting to your webserver. Cloudflare publishes their IP ranges (found here), so you can set up a whitelist consisting of only Cloudflare and administrator IPs.
Hopefully this post raised your awareness on possible attack vectors for Cloudflare hosted sites as well as any other IP masking service, such as Tor. If you know of any other methods of unmasking an origin server, please feel free to share in the comments and I’ll make sure to add them to this list!