Last active
August 7, 2022 14:00
-
-
Save Tugzrida/5910e1b1a9d096e297e793890b7c5236 to your computer and use it in GitHub Desktop.
nginx realip updater for Cloudflare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# v0.5 Created by Tugzrida(https://gist.github.com/Tugzrida/5910e1b1a9d096e297e793890b7c5236) | |
# This script should be added to the root crontab (or whichever user controls nginx) | |
# to run perhaps once or twice a day. It will create and keep up to date | |
# the file /etc/nginx/conf.d/cloudflare_realip.conf which will make all of nginx | |
# trust and use Cloudflare's provided client IP's. | |
# | |
# After updating the file, it runs nginx -t to check the config for errors, and if | |
# any are found, nginx will not be restarted to avoid taking things down. You may wish | |
# to add your own error reporting to the handle_error function below. | |
from urllib.request import urlopen | |
from urllib.error import URLError | |
from json import load | |
from os import system | |
def handle_error(e): | |
# Add your error reporting here | |
raise SystemExit(e) | |
try: | |
res = load(urlopen("https://api.cloudflare.com/client/v4/ips")) | |
if not res.get("success"): | |
raise URLError("Request not successful") | |
res = res["result"] | |
if not (res.get("etag") and res.get("ipv4_cidrs") and res.get("ipv6_cidrs")): | |
raise KeyError | |
except (URLError, ValueError, KeyError): | |
handle_error("Error loading Cloudflare IPs") | |
try: | |
with open("/etc/nginx/conf.d/cloudflare_realip.conf", "r") as f: | |
if f.readline().strip() == "#{}".format(res["etag"]): | |
print("No change. Exiting...") | |
raise SystemExit | |
except OSError: | |
# File doesn't exist yet | |
pass | |
print("IPs changed. Updating...") | |
newfile = '''#{} | |
############## THIS FILE IS AUTOMATICALLY GENERATED ############## | |
# This is a list of Cloudflare's IP addresses, which will supply a 'CF-Connecting-IP' header | |
# containing the proxied client's IP. These options tell nginx about this header and to trust it only | |
# from Cloudflare's IP's, thereby correcting all further references(logs, PHP, access control, etc.) | |
# to client IP to be the actual client's IP and not the proxy's IP. | |
real_ip_header CF-Connecting-IP; | |
'''.format(res["etag"]) | |
for ip in res["ipv4_cidrs"] + res["ipv6_cidrs"]: | |
newfile += "set_real_ip_from {};\n".format(ip) | |
try: | |
with open("/etc/nginx/conf.d/cloudflare_realip.conf", "w") as f: | |
f.write(newfile) | |
except OSError: | |
handle_error("Cannot write to /etc/nginx/conf.d/cloudflare_realip.conf. Aborting") | |
if system("nginx -t") == 0: | |
system("service nginx reload") | |
else: | |
handle_error("Nginx config error! Not restarting") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment