Skip to content
This repository has been archived by the owner on Nov 11, 2022. It is now read-only.

Export Cloudflare and Fastly IPs as facter facts

License

Notifications You must be signed in to change notification settings

byronwolfman/real_ip_facter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Consume Cloudflare and Fastly IP Addresses through Facter

What is this?

I'm prepping a new webhost to be served behind Cloudflare. Cloudflare advices that you will need to implement the real_ip module if you use nginx and want to know where your traffic is really coming from. The method to do so is described here:

https://support.cloudflare.com/hc/en-us/articles/200170706-How-do-I-restore-original-visitor-IP-with-Nginx-

Below the list of Cloudflare IP addresses is the following caveat:

NB: That list of prefixes needs to be updated regularly

It's unclear what the frequency of "regularly" is, but it sure would be nice to not have to worry about it. I originally solved this problem with a big pile of bash -- you can see what that looked like over here (but TL;DR: it grabs and parses Cloudflare's published list of IPv4 and IPv6 addresses and shoves them into an nginx config). This was all well and good but I worried that the script and puppet might clobber each other, and anyway, it doesn't seem fantastic to have two different things managing nginx's configuration.

Now, if puppet could consume that information as a fact, we'd be cooking.

(Note that only Cloudflare instructions and examples are provided for brevity. The Fastly facts work exactly the same; just substitute cloudflare_ipv4s for fastly_ipv4s and cloudflare_ipv6s with fastly_ipv6s and you're done. Note that at the time of writing, Fastly does not publish any IPv6 addresses, so the latter array will be empty. This is normal.)

How it works

Hopefully the script is easy to parse, but just in case it isn't, here's what it does:

  1. Downloads a list of return-delimited IPv4 and IPv6 addresses from Cloudflare
  2. Validates the list through a couple of very ugly (but accurate) regexes
  3. Returns the arrays cloudflare_ipv4s and cloudflare_ipv6s to facter to be used as you see fit.

How to use it with facter

If you're not using puppet and just want to use facter, you can consume it like so:

facter --custom-dir /path/to/cloudflare_ips.rb

How to use it with puppet

It probably makes sense to associate the fact with the module that will consume it. In my case this is the nginx module, so the script itself is located in

modules/nginx/lib/facter/cloudflare_ips.rb

Next consume the fact in nginx's params.pp manifest:

$cloudflare_ipv4s = $facts['cloudflare_ipv4s']
$cloudflare_ipv6s = $facts['cloudflare_ipv6s']

Finally, render the arrays into a template:

<% scope['nginx::params::cloudflare_ipv4s'].each do |ip| -%>
set_real_ip_from <%= ip %>;
<% end -%>

<% scope['nginx::params::cloudflare_ipv6s'].each do |ip| -%>
set_real_ip_from <%= ip %>;
<% end -%>

real_ip_header X-Forwarded-For;

Alternatively you can access the facts in the template directly as a top-level variable, i.e. scope['::cloudflare_ipv4s'] and skip on adding it to the params.pp manifest. This is fine and it works, but you lose out on the means to perform validation within the manifests (you could do validation in the templates themselves but this is ugly).

Danger

This script makes certain assumptions which may cause you grief:

  • The script assumes return-delimited lists for Cloudflare and a JSON blob for Fastly.
  • The script returns an empty array to facter if it can't download the lists.
  • The net/http and openssl module are imported for both facts; the json module is additionally imported for Fastly facts.

Use/modify/deploy at your own risk.

Contributing

Feel free to fork and make pull requests.

About

Export Cloudflare and Fastly IPs as facter facts

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages