|
from flask import Flask, request, jsonify |
|
from flask_cors import CORS |
|
import os |
|
import requests |
|
import ipaddress |
|
import hashlib |
|
import urllib.request |
|
|
|
app = Flask(__name__) |
|
CORS(app) |
|
|
|
|
|
VPN_LIST_URL = "https://raw.githubusercontent.com/Dan-Duran/vpn-checker/main/known-vpn/vpn-list.txt" |
|
VPN_LIST_PATH = "known-vpn/vpn-list.txt" |
|
MANUAL_LIST_PATH = "known-vpn/vpn-manual.txt" |
|
|
|
|
|
os.makedirs("known-vpn", exist_ok=True) |
|
|
|
|
|
@app.route('/') |
|
|
|
def home(): |
|
|
|
return "" |
|
|
|
|
|
def download_file(url, local_path): |
|
"""Download the VPN IP list if updated.""" |
|
try: |
|
response = urllib.request.urlopen(url) |
|
new_content = response.read() |
|
|
|
if os.path.exists(local_path): |
|
with open(local_path, "rb") as local_file: |
|
existing_content = local_file.read() |
|
if hashlib.md5(existing_content).hexdigest() == hashlib.md5(new_content).hexdigest(): |
|
print(f"No changes in {local_path}. Using the existing file.") |
|
return |
|
|
|
with open(local_path, "wb") as local_file: |
|
local_file.write(new_content) |
|
print(f"Updated {local_path} with the latest version.") |
|
except urllib.error.URLError as e: |
|
print(f"Failed to download {url}: {e}") |
|
|
|
|
|
def load_ip_list(file_path): |
|
"""Load IP lists from a given file path.""" |
|
if os.path.exists(file_path): |
|
with open(file_path, "r") as file: |
|
return [line.strip() for line in file if line.strip()] |
|
return [] |
|
|
|
|
|
def is_ip_in_list(ip, ip_list): |
|
"""Check if an IP is in a VPN CIDR block.""" |
|
try: |
|
ip_obj = ipaddress.IPv4Address(ip) |
|
for cidr in ip_list: |
|
if ip_obj in ipaddress.IPv4Network(cidr, strict=False): |
|
return True |
|
except ipaddress.AddressValueError: |
|
return False |
|
return False |
|
|
|
|
|
def get_public_ip(): |
|
"""Fetch the user's public IP from api64.ipify.org""" |
|
try: |
|
response = requests.get("https://api64.ipify.org?format=json") |
|
return response.json().get("ip") |
|
except requests.RequestException: |
|
return None |
|
|
|
|
|
@app.route("/check-vpn", methods=["GET"]) |
|
def check_vpn(): |
|
"""Check if an IP is in the VPN list.""" |
|
try: |
|
user_ip = request.args.get("ip") |
|
|
|
|
|
if not user_ip: |
|
user_ip = get_public_ip() |
|
if not user_ip: |
|
return jsonify({"error": "Could not fetch public IP"}), 500 |
|
|
|
|
|
download_file(VPN_LIST_URL, VPN_LIST_PATH) |
|
|
|
vpn_list = load_ip_list(VPN_LIST_PATH) |
|
manual_list = load_ip_list(MANUAL_LIST_PATH) |
|
|
|
is_vpn = is_ip_in_list(user_ip, vpn_list) or is_ip_in_list(user_ip, manual_list) |
|
|
|
return jsonify({"ip": user_ip, "vpn_detected": is_vpn}) |
|
|
|
except Exception as e: |
|
import traceback |
|
print("❌ Error:", traceback.format_exc()) |
|
return jsonify({"error": "Internal Server Error", "details": str(e)}), 500 |
|
|
|
|
|
if __name__ == "__main__": |
|
app.run(host='0.0.0.0', port=7860) |