Created
January 13, 2026 09:20
-
-
Save cnicodeme/2c4b59f646835e84edda0849a1cab351 to your computer and use it in GitHub Desktop.
BetterUptime automatic update of IPs for iptable
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
| import requests, hashlib, os, ipaddress, subprocess | |
| from typing import List | |
| BETTERUPTIME_URL = 'https://uptime.betterstack.com/ips.txt' | |
| def run(cmd: List[str], check: bool = True, capture: bool = False) -> subprocess.CompletedProcess: | |
| return subprocess.run( | |
| cmd, | |
| check=check, | |
| text=True, | |
| stdout=subprocess.PIPE if capture else None, | |
| stderr=subprocess.PIPE if capture else None, | |
| ) | |
| def process(content): | |
| ips_v4 = [] | |
| ips_v6 = [] | |
| for line in content.splitlines(): | |
| line = line.strip() | |
| if not line or line.startswith('#'): | |
| continue | |
| if line.find(':') > -1: | |
| ips_v6.append(line) | |
| else: | |
| ips_v4.append(line) | |
| # Create temporary ipsets | |
| run(['ipset', 'create', 'better_uptime_v4_tmp', 'hash:net', 'family', 'inet', '-exist'], check=True) | |
| run(['ipset', 'create', 'better_uptime_v6_tmp', 'hash:net', 'family', 'inet6', '-exist'], check=True) | |
| for ip in ips_v4: | |
| run(['ipset', 'add', 'better_uptime_v4_tmp', ip, '-exist'], check=True) | |
| for ip in ips_v6: | |
| run(['ipset', 'add', 'better_uptime_v6_tmp', ip, '-exist'], check=True) | |
| run(['ipset', 'swap', 'better_uptime_v4', 'better_uptime_v4_tmp'], check=True) | |
| run(['ipset', 'swap', 'better_uptime_v6', 'better_uptime_v6_tmp'], check=True) | |
| run(['ipset', 'destroy', 'better_uptime_v4_tmp'], check=True) | |
| run(['ipset', 'destroy', 'better_uptime_v6_tmp'], check=True) | |
| def main(): | |
| # First, we load the Better Uptime IP list | |
| response = requests.get(BETTERUPTIME_URL) | |
| try: | |
| response.raise_for_status() | |
| except requests.HTTPError as e: | |
| print(f"Failed to fetch Better Uptime IP list: {e}") | |
| exit(1) | |
| # Now, we hash the file contents | |
| content = response.text | |
| sha256_hash = hashlib.sha256(content.encode('utf-8')).hexdigest() | |
| # And we compare to local BetterUptime file hash located at /tmp/betteruptime-ips.txt.sha256 | |
| try: | |
| with open('/tmp/betteruptime-ips.txt.sha256', 'r') as f: | |
| local_hash = f.read().strip() | |
| except FileNotFoundError: | |
| local_hash = '' | |
| if sha256_hash == local_hash: | |
| print("Better Uptime IP list is up to date.") | |
| return | |
| # If we reach here, the file has changed | |
| with open('/tmp/betteruptime-ips.txt.sha256', 'w') as f: | |
| f.write(sha256_hash) | |
| process(content) | |
| print("Better Uptime IP list successfully updated.") | |
| if __name__ == '__main__': | |
| if os.geteuid() != 0: | |
| raise SystemExit("This script must be run as root (ipset requires privileges).") | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment