[Update]: Thanks to digitaltoast for informing me about the missing real_ip_header CF-Connecting-IP; from the script and providing a patch for it.
OK, I suppose you know what CloudFlare is, and are familiar with Nginx configuration process, before we proceed any further. Just in case you don’t know, CloudFlare offers free and commercial, cloud-based services to help secure and accelerate websites. The thing is, I’m really satisfied with the services they offer except a repellent issue about logging the real IP address of your website’s visitors. Since CloudFlare acts as a reverse proxy, all connections come from CloudFlare’s IP addresses, not the real visitors anymore. Anyway, using Nginx there’s a simple workaround for this issue, which I’ll describe in the rest of this post.
Table of Contents
HttpRealipModule
Well, to achieve over goal we have to first build Nginx with HttpRealipModule support. I’ll describe three methods to build Nginx with RealIP module support on FreeBSD, Funtoo or Gentoo GNU/Linux variants and any other distros.
Building from Ports on FreeBSD
In fact, building and installing Nginx from Ports is very easy and straightforward. Just issue the following commands:
$ cd /usr/ports/www/nginx
$ make config
You have to find and choose HTTP_REALIP by hitting Spacebar on your keyboard in the opening configuration window:
[*] HTTP_REALIP Enable http_realip module
By issuing the following command Nginx will be built and installed by Ports.
$ make install clean
Building from Portage on Funtoo / Gentoo
To build and install Nginx with RealIP support from Portage on Gentoo or Funtoo we have to first touch the make.conf file with the following content. Just add the realip keyword to NGINX_MODULES_HTTP:
|
|
Start the building and installation process by using the emerge command:
$ emerge -avt www-servers/nginx
You should see the realip keyword without “-” sign in the NGINX_MODULES_HTTP on the emerge command output:
Calculating dependencies... done!
[ebuild R ] www-servers/nginx-1.x.x USE="some use flags -some -disbaled -use -flags" NGIN
X_MODULES_HTTP="some other modules ... realip ... -some -disbaled -modules" NGINX_MODULES_MAIL=
"some modules -some -disbaled -modules"
Building from Source
By following the instructions given below, it is easy to build Nginx from source with RealIP module support on any other distro. Because the RealIP module won’t build by default, you need to enable it with the configuration option with-http_realip_module.
$ wget http://nginx.org/download/nginx-1.x.x.tar.gz
$ tar xvzf nginx-1.x.x.tar.gz
$ cd nginx-1.x.x
$ ./configure --with-http_realip_module
$ make
$ make install
Nginx Configuration
After building Nginx with RealIP support enabled, now it’s time to configure our vhosts in order to enable real visitors IP logging. I assume you’ve configured your vhosts and Nginx installation already.
You need to first fetch CloudFlare’s IPv4 and IPv6 IP Ranges. You should consider, this list changes from time to time. So, it’s vital to fetch and synchronize them with your own list on regular basis. However, it’s possible to write an automated update script to accomplish this task. Therefore, I’ll provide one at the end of the article.
Let’s say we’ve chosen /usr/local/www/nginx as Ngix default host root. So, we put each vhost in its own directory at /usr/local/www. And, also put the vhost configurations inside the /usr/local/www/_vhosts directory. In addition to that, we create an _include directory at /usr/local/www for sharing CloudFlare settings among our vhosts.
$ mkdir -p /usr/local/www/_include/
Anyway, our CloudFlare configuration file at /usr/local/www/_include/cloudflare looks like this:
|
|
Finally, you can enable RealIP for each vhost by including the /usr/local/www/_include/cloudflare file:
|
|
Automated CloudFlare IP Ranges Update
You have to first create the /usr/local/www/_cron directory:
$ mkdir -p /usr/local/www/_cron
Then, put the cloudflare-ip-ranges-updater.sh file with the provided contents inside the /usr/local/www/_cron directory. The major prerequisites for this script to run correctly are AWK and FreeBSD fetch or GNU Wget. Also, you may need to change the shebang line or script variables such as CLOUDFLARE_IP_RANGES_FILE_PATH, WWW_GROUP and WWW_USER according to your OS requirements.
|
|
After that, set the script file’s permissions to executable by all users:
$ chmod a+x /usr/local/www/_cron/cloudflare-ip-ranges-updater.sh
Now, you may want to test the script by issuing the following set of commands:
$ /usr/local/www/_cron/cloudflare-ip-ranges-updater.sh
$ cat /usr/local/www/_include/cloudflare
The output must be something like this:
|
|
If you want to update the CloudFlare IP Ranges every 24:00 hours as root user you should add the following at the end of your system’s crontab file:
$ sudo crontab -e -u root
|
|
It’s also possible to set time intervals weekly or several times a month, a day or even hours:
|
|
In order to verify your crontab entry:
$ sudo crontab -l -u root
Finally, if necessary restart the cron service:
$ service cron restart
Source Code
Check out the source code on GitLab
Check out the source code on GitHub
See also
- How to disable HP Proliant ML350p Gen8 P420i RAID controller, enable HBA mode (a.k.a. pass-through), and perform a FreeBSD root on ZFS installation
- A quick workaround for Unreal Engine Modeling Tools Editor Mode plugin not showing up on Linux and macOS
- Host Unreal Engine 4 projects on Microsoft Azure DevOPS with unlimited cost-free Git LFS quota
- Gregorian / Jalali (a.k.a. Persian Calendar) Date Conversion in C++ using boost::locale