-
Notifications
You must be signed in to change notification settings - Fork 30
/
cloudflare.py
51 lines (42 loc) · 1.31 KB
/
cloudflare.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import ipaddress
import asyncio
import logging
import tornado.web
from tornado.httpclient import AsyncHTTPClient
from tornado.platform.asyncio import to_asyncio_future
CLOUDFLARE_IPS = []
logger = logging.getLogger(__name__)
async def update_cloudflare_ips():
global CLOUDFLARE_IPS
urls = ['https://www.cloudflare.com/ips-v4',
'https://www.cloudflare.com/ips-v6']
client = AsyncHTTPClient()
coros = [to_asyncio_future(client.fetch(url)) for url in urls]
rs, _ = await asyncio.wait(coros)
new = []
for r in rs:
r = r.result()
new.extend(ipaddress.ip_network(line)
for line in r.body.decode('utf-8').splitlines())
CLOUDFLARE_IPS = new
async def updater():
while True:
try:
await update_cloudflare_ips()
logger.info('cloudflare ips updated.')
except Exception:
logger.exception('error when update cloudflare ips')
await asyncio.sleep(24 * 3600)
def install():
RH = tornado.web.RequestHandler
RH.prepare = _my_prepare
def _my_prepare(self):
request = self.request
cfip = request.headers.get('Cf-Connecting-IP')
if cfip:
ip = ipaddress.ip_address(request.remote_ip)
for net in CLOUDFLARE_IPS:
if ip in net:
request.remote_ip = cfip
request.protocol = request.headers.get('X-Forwarded-Proto', 'http')
break