如何利用Python获取Cloudflare白名单的IP地址列表

770 阅读2分钟

在今天的文章中,我们要做的是一个真实的Python脚本,用于Devops。

当今世界上的许多网站都受到Cloudflare的保护,免受DDoS攻击。
Cloudflare通过充当来自网络的所有流量的中介来提供这种保护。因此,网站访问者不是直接连接到托管网站的服务器,而是连接到Cloudflare的一个服务器。通过这种方式,Cloudflare可以过滤所有看起来可疑的请求。

但是,这只有在攻击者不绕过Cloudflare的服务器时才有效

如果攻击者发现了托管网站的服务器的IP地址,那么它就可以直接攻击网站!这就是为什么我们需要防止攻击。

为此,我们需要通过将Cloudflare的所有IP地址列入白名单来防止这种情况,这样,即使攻击者知道我们网站的真实IP地址,他们也无法轻易攻击网站,因为他们的IP地址不会被列入白名单的IP地址。

Cloudflare提供了一个网址www.cloudflare.com/ips-v4www.cloudflare.com/ips-v6,以下载Cloudflare服务器使用的IP地址范围(CIDR)。

我们将使用Python来读取这些URL的内容,并返回一个包含IPV4和IPV6的所有CIDR的字符串列表。

我们还将创建一个单元测试列表,以确保我们的代码总是返回一个有效的CIDR IP地址的非空列表。

def getIPAddresses(url):
      headers = {
        'User-Agent': 'My User Agent 1.0',
        'From': '[email protected]'  # This is another valid field
      }
      result = []
      try:
        req = urllib.request.Request(url, headers=headers)
        with urllib.request.urlopen(req) as f:
            ips = f.read().decode('utf-8').split("n")
            result = ips
      except urllib.error.URLError as e:
        print(e.reason)

      return result      
import urllib
import urllib.request

def whitelistCloudflareIps():
    ips_v4 = getIPAddresses("https://www.cloudflare.com/ips-v4")
    ips_v6 = getIPAddresses("https://www.cloudflare.com/ips-v6")
    return ips_v4 + ips_v6
whitelistCloudflareIps()
['173.245.48.0/20',
 '103.21.244.0/22',
 '103.22.200.0/22',
 '103.31.4.0/22',
 '141.101.64.0/18',
 '108.162.192.0/18',
 '190.93.240.0/20',
 '188.114.96.0/20',
 '197.234.240.0/22',
 '198.41.128.0/17',
 '162.158.0.0/15',
 '104.16.0.0/13',
 '104.24.0.0/14',
 '172.64.0.0/13',
 '131.0.72.0/22',
 '2400:cb00::/32',
 '2606:4700::/32',
 '2803:f800::/32',
 '2405:b500::/32',
 '2405:8100::/32',
 '2a06:98c0::/29',
 '2c0f:f248::/32']
import unittest
import re

class TestGetIpAddressesFromCloudflare(unittest.TestCase):

  def test_whitelistCloudflareIpsForIpv4(self):
    ips = getIPAddresses("https://www.cloudflare.com/ips-v4")
    self.assertTrue(len(ips)> 0)

  def test_whitelistCloudflareIpsForIpv6(self):
    ips = getIPAddresses("https://www.cloudflare.com/ips-v6")
    self.assertTrue(len(ips)> 0)

  def test_whitelistCloudflareIpsForIpv4ShouldReturnValidIpRanges(self):
    ips = getIPAddresses("https://www.cloudflare.com/ips-v4")
    self.assertTrue(len(ips)> 0)
    for ip in ips:
      pattern_ipv4_cidr = "d+.d+.d+.d+/d+"
      result = re.fullmatch(pattern_ipv4_cidr, ip)
      self.assertNotEqual(result, None)

  def test_whitelistCloudflareIpsForIpv6ShouldReturnValidIpRanges(self):
    ips = getIPAddresses("https://www.cloudflare.com/ips-v6")
    self.assertTrue(len(ips)> 0)
    for ip in ips:
      pattern_ipv6_cidr = "(d|[a-f])+:(d|[a-f])+::/d+"
      result = re.fullmatch(pattern_ipv6_cidr, ip)
      self.assertNotEqual(result, None)
if __name__ == '__main__':
   unittest.main(argv=['first-arg-is-ignored'], exit=False)
....
----------------------------------------------------------------------
Ran 4 tests in 0.161s

OK