Files
wevads-platform/scripts/freedns-api.py
2026-02-26 04:53:11 +01:00

396 lines
12 KiB
Python
Executable File

#!/usr/bin/env python3
"""
FREEDNS API MANAGER
Gère les domaines FreeDNS:
- Récupère liste des domaines disponibles
- Ajoute des sous-domaines
- Configure DNS (A, MX, TXT/SPF)
- Valide et teste
FreeDNS: https://freedns.afraid.org
"""
import psycopg2
import requests
import re
import hashlib
from bs4 import BeautifulSoup
from datetime import datetime
import time
DB_CONFIG = {
'host': 'localhost',
'database': 'adx_system',
'user': 'admin',
'password': 'admin123'
}
# FreeDNS Configuration
FREEDNS_CONFIG = {
'base_url': 'https://freedns.afraid.org',
'login_url': 'https://freedns.afraid.org/zc.php?from=L2R5bmFtaWMv',
'subdomain_url': 'https://freedns.afraid.org/subdomain/',
'registry_url': 'https://freedns.afraid.org/domain/registry/',
# Credentials - à configurer
'username': '',
'password': '',
'cookie': '', # Session cookie if logged in
}
def get_db():
return psycopg2.connect(**DB_CONFIG)
class FreeDNSClient:
def __init__(self, username=None, password=None, cookie=None):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})
self.logged_in = False
if cookie:
self.session.cookies.set('dns_cookie', cookie)
self.logged_in = True
elif username and password:
self.login(username, password)
def login(self, username, password):
"""Login to FreeDNS"""
try:
# Get login page for any tokens
self.session.get(FREEDNS_CONFIG['base_url'])
# Login
data = {
'username': username,
'password': password,
'submit': 'Login',
'action': 'auth'
}
response = self.session.post(FREEDNS_CONFIG['login_url'], data=data)
if 'logout' in response.text.lower() or 'my account' in response.text.lower():
self.logged_in = True
print("✅ FreeDNS login successful")
return True
else:
print("❌ FreeDNS login failed")
return False
except Exception as e:
print(f"Login error: {e}")
return False
def get_available_domains(self, limit=50):
"""Get list of available public domains"""
try:
response = self.session.get(FREEDNS_CONFIG['registry_url'])
soup = BeautifulSoup(response.text, 'html.parser')
domains = []
# Parse domain list
for row in soup.find_all('tr'):
cells = row.find_all('td')
if len(cells) >= 3:
domain_link = cells[0].find('a')
if domain_link:
domain = domain_link.text.strip()
if '.' in domain and not domain.startswith('.'):
# Get domain info
hosts = cells[1].text.strip() if len(cells) > 1 else '0'
status = cells[2].text.strip() if len(cells) > 2 else 'unknown'
domains.append({
'domain': domain,
'hosts': hosts,
'status': status
})
if len(domains) >= limit:
break
return domains
except Exception as e:
print(f"Error fetching domains: {e}")
return []
def get_my_subdomains(self):
"""Get list of my subdomains"""
if not self.logged_in:
print("Not logged in")
return []
try:
response = self.session.get(FREEDNS_CONFIG['subdomain_url'])
soup = BeautifulSoup(response.text, 'html.parser')
subdomains = []
# Parse subdomain table
for row in soup.find_all('tr'):
cells = row.find_all('td')
if len(cells) >= 4:
subdomain = cells[0].text.strip()
record_type = cells[1].text.strip()
destination = cells[2].text.strip()
if subdomain and '.' in subdomain:
subdomains.append({
'subdomain': subdomain,
'type': record_type,
'destination': destination
})
return subdomains
except Exception as e:
print(f"Error fetching subdomains: {e}")
return []
def add_subdomain(self, subdomain, domain, record_type='A', destination=''):
"""Add a new subdomain"""
if not self.logged_in:
print("Not logged in")
return False
try:
# Get domain ID from registry
response = self.session.get(f"{FREEDNS_CONFIG['registry_url']}?q={domain}")
# Find domain ID in response
match = re.search(rf'domain_id=(\d+).*?{re.escape(domain)}', response.text)
if not match:
print(f"Domain {domain} not found in registry")
return False
domain_id = match.group(1)
# Add subdomain
data = {
'type': record_type,
'subdomain': subdomain,
'domain_id': domain_id,
'address': destination,
'submit': 'Save!'
}
response = self.session.post(
f"{FREEDNS_CONFIG['subdomain_url']}save.php",
data=data
)
if 'successfully' in response.text.lower() or subdomain in response.text:
print(f"✅ Added {subdomain}.{domain}")
return True
else:
print(f"❌ Failed to add subdomain")
return False
except Exception as e:
print(f"Error adding subdomain: {e}")
return False
def add_txt_record(self, subdomain, domain, txt_value):
"""Add TXT record (for SPF)"""
return self.add_subdomain(subdomain, domain, 'TXT', txt_value)
def save_domain_to_pool(domain, source='freedns'):
"""Save domain to database pool"""
conn = get_db()
cur = conn.cursor()
try:
cur.execute("""
INSERT INTO admin.domain_pool (domain, source, dns_provider, status)
VALUES (%s, %s, 'freedns', 'pending')
ON CONFLICT (domain) DO UPDATE SET
last_check = NOW()
RETURNING id
""", (domain, source))
conn.commit()
return cur.fetchone()[0]
except Exception as e:
print(f"Error saving domain: {e}")
return None
finally:
conn.close()
def fetch_and_save_domains(limit=100):
"""Fetch domains from FreeDNS and save to database"""
client = FreeDNSClient()
print("=" * 60)
print("📥 FETCHING FREEDNS DOMAINS")
print("=" * 60)
domains = client.get_available_domains(limit)
print(f"\nFound {len(domains)} domains")
saved = 0
for d in domains:
domain = d['domain']
if save_domain_to_pool(domain, 'freedns_registry'):
saved += 1
print(f"{domain}")
print(f"\n✅ Saved {saved} domains to pool")
return saved
def configure_freedns_credentials():
"""Interactive configuration of FreeDNS credentials"""
print("=" * 60)
print("🔧 FREEDNS CONFIGURATION")
print("=" * 60)
print("\nFreeDNS requires an account at https://freedns.afraid.org")
print("Create a free account and enter your credentials below.\n")
conn = get_db()
cur = conn.cursor()
# Check if already configured
cur.execute("""
SELECT config_value FROM admin.system_config
WHERE config_key = 'freedns_username'
""")
existing = cur.fetchone()
if existing:
print(f"Current username: {existing[0]}")
change = input("Change credentials? (y/n): ")
if change.lower() != 'y':
conn.close()
return
username = input("FreeDNS Username: ")
password = input("FreeDNS Password: ")
# Test login
client = FreeDNSClient(username=username, password=password)
if client.logged_in:
# Save to database
cur.execute("""
INSERT INTO admin.system_config (config_key, config_value)
VALUES ('freedns_username', %s)
ON CONFLICT (config_key) DO UPDATE SET config_value = EXCLUDED.config_value
""", (username,))
cur.execute("""
INSERT INTO admin.system_config (config_key, config_value)
VALUES ('freedns_password', %s)
ON CONFLICT (config_key) DO UPDATE SET config_value = EXCLUDED.config_value
""", (password,))
conn.commit()
print("\n✅ Credentials saved!")
else:
print("\n❌ Login failed, credentials not saved")
conn.close()
def get_stored_credentials():
"""Get stored FreeDNS credentials"""
conn = get_db()
cur = conn.cursor()
cur.execute("""
SELECT config_key, config_value FROM admin.system_config
WHERE config_key IN ('freedns_username', 'freedns_password')
""")
creds = dict(cur.fetchall())
conn.close()
return creds.get('freedns_username'), creds.get('freedns_password')
def show_status():
"""Show FreeDNS status"""
conn = get_db()
cur = conn.cursor()
print("=" * 60)
print("📊 FREEDNS STATUS")
print("=" * 60)
# Check credentials
username, password = get_stored_credentials()
print(f"\nCredentials: {'✅ Configured' if username else '❌ Not configured'}")
# Domain pool stats
cur.execute("""
SELECT source, status, COUNT(*)
FROM admin.domain_pool
WHERE source LIKE 'freedns%'
GROUP BY source, status
""")
print("\nDomain Pool:")
for source, status, count in cur.fetchall():
print(f" {source} / {status}: {count}")
conn.close()
def main():
import sys
# Ensure system_config table exists
conn = get_db()
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS admin.system_config (
config_key VARCHAR(100) PRIMARY KEY,
config_value TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
)
""")
conn.commit()
conn.close()
if len(sys.argv) < 2:
show_status()
print("\nUsage:")
print(" freedns-api.py status - Show status")
print(" freedns-api.py configure - Configure credentials")
print(" freedns-api.py fetch - Fetch available domains")
print(" freedns-api.py list - List my subdomains")
print(" freedns-api.py add <sub> <domain> <ip> - Add subdomain")
return
cmd = sys.argv[1]
if cmd == 'status':
show_status()
elif cmd == 'configure':
configure_freedns_credentials()
elif cmd == 'fetch':
fetch_and_save_domains()
elif cmd == 'list':
username, password = get_stored_credentials()
if username:
client = FreeDNSClient(username=username, password=password)
subdomains = client.get_my_subdomains()
print(f"\nMy Subdomains ({len(subdomains)}):")
for s in subdomains:
print(f" {s['subdomain']} ({s['type']}) → {s['destination']}")
else:
print("❌ Credentials not configured. Run: freedns-api.py configure")
elif cmd == 'add':
if len(sys.argv) < 5:
print("Usage: freedns-api.py add <subdomain> <domain> <ip>")
return
subdomain, domain, ip = sys.argv[2], sys.argv[3], sys.argv[4]
username, password = get_stored_credentials()
if username:
client = FreeDNSClient(username=username, password=password)
client.add_subdomain(subdomain, domain, 'A', ip)
else:
print("❌ Credentials not configured")
else:
print(f"Unknown command: {cmd}")
if __name__ == '__main__':
main()