update ovpn downloader to handle missing files.

This commit is contained in:
2024-09-07 17:34:15 -05:00
parent 6dd4e6f755
commit 99b39a53f8
2 changed files with 68 additions and 31 deletions

View File

@@ -6,7 +6,7 @@ import datetime
import re
import sys
from psql_utils import connect_to_database, update_or_insert_ip
from ovpn_downloader import download_and_extract_ovpn_configs
from ovpn_downloader import download_and_extract_ovpn_configs, download_ovpn_if_needed
from openvpn_manager import establish_vpn_connection, is_vpn_active, disconnect_vpn, get_external_ip
# Variables
@@ -67,7 +67,7 @@ ovpn_files_to_check = download_and_extract_ovpn_configs(cursor, conn)
total_files = len(ovpn_files_to_check)
debug_print(f"{datetime.datetime.now()} [Main Script]: Found {total_files} OVPN files to check.")
debug_print(ovpn_files_to_check) # Print the list of OVPN files
#debug_print(ovpn_files_to_check) # Print the list of OVPN files
# Process each OVPN file
FILE_NUM = 1
@@ -76,55 +76,63 @@ for OVPN_FILE in ovpn_files_to_check:
debug_print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Processing OVPN file...")
# Check if the OVPN file exists, download if needed
file_exists = download_ovpn_if_needed(OVPN_FILENAME, cursor, conn)
if not file_exists:
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Skipping, file not found and removed from database.")
FILE_NUM += 1
continue
# Read credentials
with open(CREDENTIAL_FILE, 'r') as f:
username = f.readline().strip()
password = f.readline().strip()
# Establish VPN connection (capture stdout and stderr)
max_retries = 3 # Maximum number of retries
max_retries = 3
retry_count = 0
while retry_count < max_retries:
openvpn_command = ["openvpn", "--config", f"{OVPN_DIR}/{OVPN_FILE}",
"--auth-user-pass", CREDENTIAL_FILE, "--daemon",
openvpn_command = ["openvpn", "--config", f"{OVPN_DIR}/{OVPN_FILE}",
"--auth-user-pass", CREDENTIAL_FILE, "--daemon",
"--log-append", LOG_FILE, "--verb", "3"]
debug_print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Executing OpenVPN command: {' '.join(openvpn_command)}")
process = subprocess.Popen(openvpn_command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
process = subprocess.Popen(openvpn_command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = process.communicate(input=password.encode())
# Check for errors and print output
if process.returncode != 0 or "AUTH_FAILED" in stderr.decode():
if process.returncode != 0 or "Error opening configuration file" in stderr.decode() or "AUTH_FAILED" in stderr.decode():
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Error starting OpenVPN connection or authentication failed:")
print(stderr.decode())
print(stderr.decode())
# Explicitly disconnect VPN if there was an error or auth failure
disconnect_vpn()
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: VPN disconnected (due to error or auth failure).")
if retry_count < max_retries - 1: # Retry if not the last attempt
if retry_count < max_retries - 1 and "Error opening configuration file" not in stderr.decode():
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Retrying connection in 10 seconds...")
time.sleep(10)
retry_count += 1
else:
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Max retries reached. Skipping this OVPN file.")
break # Exit the retry loop if max retries reached
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Max retries reached or config file error. Skipping this OVPN file.")
break
else:
break # Exit the retry loop if connection is successful
break
# Wait for connection to establish (with backoff for auth failure)
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Waiting for VPN connection to establish...")
max_attempts = 10
attempt = 0
backoff_time = 0
with open(LOG_FILE, 'r') as f:
with open(LOG_FILE, 'r') as f:
while attempt < max_attempts:
line = f.readline()
if not line:
time.sleep(1)
time.sleep(1)
attempt += 1
continue
@@ -135,29 +143,26 @@ for OVPN_FILE in ovpn_files_to_check:
backoff_time += 1
if backoff_time >= 30:
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Authentication failed. Skipping this OVPN file.")
break
break
if attempt == max_attempts or backoff_time >= 30:
if attempt == max_attempts or backoff_time >= 30:
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: VPN connection failed to establish (timeout or auth failure).")
# Disconnect VPN
# Disconnect VPN
disconnect_vpn()
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: VPN disconnected.")
if not DEBUG_MODE:
log_file.flush()
# Wait for a random time between 1 and 4 seconds
sleep_time = random.randint(1, 4)
sleep_time = random.randint(1, 4)
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Waiting for {sleep_time} seconds before the next connection...")
time.sleep(sleep_time)
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: Resuming...")
if not DEBUG_MODE:
log_file.flush()
continue # Skip to the next OVPN file
# Check if the VPN connection is active (using the function from openvpn_manager.py)
# Check if the VPN connection is active (using the function from openvpn_manager.py)
try:
subprocess.run(["pgrep", "-f", OVPN_FILENAME], check=True, capture_output=True)
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: VPN connection established.")
# Check external IP (with validation and retries)
external_ip = get_external_ip()
@@ -174,7 +179,7 @@ for OVPN_FILE in ovpn_files_to_check:
except subprocess.CalledProcessError:
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: VPN connection failed to establish.")
# Disconnect VPN
# Disconnect VPN
disconnect_vpn()
print(f"{datetime.datetime.now()} [{FILE_NUM}/{total_files}] [{OVPN_FILENAME}]: VPN disconnected.")
if not DEBUG_MODE:

View File

@@ -2,13 +2,15 @@ import os
import subprocess
import random
import datetime
import requests
OVPN_DIR = "/root/nordvpn/ovpn_configs/ovpn_tcp"
OVPN_DIR = "ovpn_configs"
OVPN_ZIP_URL = "https://downloads.nordcdn.com/configs/archives/servers/ovpn.zip"
OVPN_LEGACY_URL = "https://downloads.nordcdn.com/configs/files/ovpn_legacy/servers/"
def download_and_extract_ovpn_configs(cursor, conn):
"""
Downloads the OVPN ZIP archive, extracts its contents,
Downloads the OVPN ZIP archive, extracts its contents,
adds new entries to the database, and cleans up.
Returns a list of OVPN filenames that need to be checked.
"""
@@ -38,4 +40,34 @@ def download_and_extract_ovpn_configs(cursor, conn):
cursor.execute("SELECT file_name FROM ovpn_files WHERE last_exit_ip_check < %s OR last_exit_ip_check IS NULL", (three_days_ago,))
ovpn_files_to_check = [row[0] for row in cursor.fetchall()]
return ovpn_files_to_check
return ovpn_files_to_check
def download_ovpn_if_needed(filename, cursor, conn):
"""
Downloads the specified OVPN file from the legacy URL if it doesn't exist in the OVPN_DIR.
Removes the entry from the database if the file returns a 404 error.
Returns True if the file was downloaded or already exists, False if it was not found and removed from the database
"""
filepath = os.path.join(OVPN_DIR+"/ovpn_tcp/", filename)
if os.path.exists(filepath):
print(f"{filename} already exists. Skipping download.")
return True
url = OVPN_LEGACY_URL + filename
print(f"Attempting to download {filename} from legacy URL...")
response = requests.get(url)
if response.status_code == 200:
with open(filepath, 'wb') as f:
f.write(response.content)
print(f"Downloaded {filename} from legacy URL.")
return True
elif response.status_code == 404:
print(f"{filename} not found on legacy URL: {filepath}. Removing from database.") # this is the updated line
cursor.execute("DELETE FROM ovpn_files WHERE file_name = %s", (filename,))
conn.commit()
return False
else:
print(f"Error downloading {filename}: {response.status_code}")
return False