Last active
May 6, 2020 08:27
-
-
Save lexffe/71b47e0c6351d9045db66db592da2ae8 to your computer and use it in GitHub Desktop.
Create DigitalOcean cloud firewall with Cloudflare IP populated.
This file contains 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/env python3 | |
''' | |
This script | |
1. creates a DigitalOcean cloud firewall with incoming connection from Cloudflare allowed. (80/tcp, 443/tcp, 3012/tcp) | |
2. requires urllib3. | |
3. is non-interactive. You must edit this file for the variables. | |
4. is not production ready. (I honestly don't know.) | |
License: MIT | |
''' | |
from typing import List | |
import urllib3 | |
import json | |
# const, env var | |
CF_DOMAIN = "www.cloudflare.com" | |
DO_ENDPOINT = "api.digitalocean.com" | |
FIREWALL_NAME = "CF-re" | |
DO_TOKEN = "aabbccddeeff" | |
# memory | |
cidr: List[str] = [] | |
# fetch cf ips | |
cf_https = urllib3.HTTPSConnectionPool(CF_DOMAIN) | |
res = cf_https.request('GET', '/ips-v4') | |
if res.status != 200: | |
raise ConnectionError("failed to get from CF") | |
raw_ips: bytes = res.data | |
cidr.extend(list(map(lambda x: x.decode('ascii'), raw_ips.split()))) | |
res = cf_https.request('GET', '/ips-v6') | |
if res.status != 200: | |
raise ConnectionError("failed to get from CF") | |
raw_ips: bytes = res.data | |
cidr.extend(list(map(lambda x: x.decode('ascii'), raw_ips.split()))) | |
cf_https.close() | |
# post to DO | |
do_https = urllib3.HTTPSConnectionPool(DO_ENDPOINT) | |
req_body = json.dumps({ | |
'name': FIREWALL_NAME, | |
'inbound_rules': [ | |
{ | |
'protocol': 'tcp', | |
'ports': '80', | |
'sources': { | |
'addresses': cidr | |
} | |
}, | |
{ | |
'protocol': 'tcp', | |
'ports': '443', | |
'sources': { | |
'addresses': cidr | |
} | |
}, | |
{ | |
'protocol': 'tcp', | |
'ports': '3012', | |
'sources': { | |
'addresses': cidr | |
} | |
} | |
] | |
}).encode('utf-8') | |
res: urllib3.HTTPResponse = do_https.request('POST', '/v2/firewalls', body=req_body, headers={"Content-Type": "application/json", "Authorization": "Bearer " + DO_TOKEN}) | |
if res.status == 409: # None Conflict | |
print('Firewall with the name', FIREWALL_NAME, 'already exists.') | |
if res.status > 299 or res.status < 200: | |
raise ConnectionError("failed to post to DO", res.status, res.msg, res.reason) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment