import os import json import re def load_sites(): if not os.path.isfile('sites.json'): with open('sites.json', 'w') as file: file.write('[]') with open('sites.json', 'r') as file: sites = json.loads(file.read()) return sites def get_info(): sites = load_sites() if not sites: return { 'total_sites': 0, 'active_sites': 0 } total_sites = len(sites) active_sites = 0 for site in sites: if site['active']: active_sites += 1 return { 'total_sites': total_sites, 'active_sites': active_sites } def get_site(name): sites = load_sites() for site in sites: if site['name'] == name: return site return False def add_site(name, domain): sites = load_sites() domain = domain.lower().strip() # Check domain if re.search(r'[^a-zA-Z0-9.-]', domain): return False # Make sure certs directory exists if not os.path.isdir('certs'): os.mkdir('certs') if is_icann(domain): tlsa = "Not needed" else: # Generate TLSA record tlsa = os.popen(f'./tlsa.sh {domain}').read().strip() print(tlsa) if not tlsa: return False id = len(sites) for site in sites: if site['id'] >= id: id = site['id'] + 1 sites.append({ 'name': name, 'domain': domain, 'active': False, 'tlsa': tlsa, 'id': id }) with open('sites.json', 'w') as file: file.write(json.dumps(sites)) return True def add_alt_domain(name, domain): sites = load_sites() for site in sites: if site['name'] == name: if 'alt_domains' not in site: site['alt_domains'] = [] site['alt_domains'].append(domain) if is_icann(domain): tlsa = "Not needed" else: # Generate TLSA record tlsa = os.popen(f'./tlsa.sh {domain}').read().strip() print(tlsa) if not tlsa: return False if 'alt_tlsa' not in site: site['alt_tlsa'] = {} site['alt_tlsa'][domain] = tlsa with open('sites.json', 'w') as file: file.write(json.dumps(sites)) return True return False def enable(name, enable): sites = load_sites() if enable == 'on': enable = True # Create site file write_nginx_conf(name) else: enable = False # Delete site file os.remove(f'/etc/nginx/sites-enabled/{name}') for site in sites: if site['name'] == name: site['active'] = enable with open('sites.json', 'w') as file: file.write(json.dumps(sites)) return True return False def get_content(site): site = get_site(site) id = site['id'] path = f'/var/www/{id}' if not os.path.isdir(path): return [] files = os.listdir(path) return files def get_dns_info(site): # Get public ip of server public_ip = os.popen('curl ipinfo.io/ip').read().strip() # Get domains domains = get_site(site) if not domains: return False main = domains['domain'] tlsa = domains['tlsa'] alt = [] if 'alt_domains' in domains: alt = domains['alt_domains'] info = [{ 'domain': main, 'ip': public_ip, 'tlsa': tlsa }] for alt_domain in alt: alt_tlsa = domains['alt_tlsa'][alt_domain] info.append({ 'domain': alt_domain, 'ip': public_ip, 'tlsa': alt_tlsa }) return info def write_nginx_conf(site): site = get_site(site) domain = site['domain'] id = site['id'] location = f'/var/www/{id}' ssl = "" if not is_icann(domain): ssl = f''' listen 443 ssl; ssl_certificate /root/site-manager/certs/{domain}/cert.crt; ssl_certificate_key /root/site-manager/certs/{domain}/cert.key; ''' conf = f''' server {{ listen 80; listen [::]:80; root '{location}'; index index.html; server_name {domain} *.{domain}; location / {{ try_files $uri $uri/ @htmlext; }} location ~ \.html$ {{ try_files $uri =404; }} location @htmlext {{ rewrite ^(.*)$ $1.html last; }} error_page 404 /404.html; location = /404.html {{ internal; }} location = /.well-known/wallets/HNS {{ add_header Cache-Control 'must-revalidate'; add_header Content-Type text/plain; }} {ssl} }} ''' # Add alt domains if 'alt_domains' in site: for alt in site['alt_domains']: if not is_icann(alt): ssl = f''' listen 443 ssl; ssl_certificate /root/site-manager/certs/{alt}/cert.crt; ssl_certificate_key /root/site-manager/certs/{alt}/cert.key; ''' else: ssl = "" conf += f''' server {{ listen 80; listen [::]:80; root '{location}'; index index.html; server_name {alt} *.{alt}; location / {{ try_files $uri $uri/ @htmlext; }} location ~ \.html$ {{ try_files $uri =404; }} location @htmlext {{ rewrite ^(.*)$ $1.html last; }} error_page 404 /404.html; location = /404.html {{ internal; }} location = /.well-known/wallets/HNS {{ add_header Cache-Control 'must-revalidate'; add_header Content-Type text/plain; }} {ssl} }} ''' with open(f'/etc/nginx/sites-enabled/{id}.conf', 'w') as file: file.write(conf) # Restart nginx os.system('systemctl restart nginx') # Create certs for ICANN domains icann_domains = [] if is_icann(domain): icann_domains.append(domain) if 'alt_domains' in site: for alt in site['alt_domains']: if is_icann(alt): icann_domains.append(alt) if len(icann_domains) > 0: email = f'admin@{icann_domains[0]}' icann_domains = " -d ".join(icann_domains) icann_domains = f'-d {icann_domains}' os.system(f'certbot --nginx {icann_domains} --non-interactive --agree-tos --email {email} --redirect') return True def is_icann(domain): # Check if domain list is downloaded yet if not os.path.isfile('icann.txt'): os.system('wget https://data.iana.org/TLD/tlds-alpha-by-domain.txt -O icann.txt') tlds = open('icann.txt', 'r').read().split('\n') # Remove any comments tlds = [tld for tld in tlds if not tld.startswith('#')] if domain.split('.')[-1].upper() in tlds: return True return False def clone_git(name, url): site = get_site(name) id = site['id'] path = f'/var/www/{id}' if not os.path.isdir(path): os.mkdir(path) os.system(f'git clone {url} {path}') with open('sites.json', 'r') as file: sites = json.loads(file.read()) for site in sites: if site['name'] == name: site['git'] = url with open('sites.json', 'w') as file: file.write(json.dumps(sites)) return True return True def pull_git(name): site = get_site(name) id = site['id'] path = f'/var/www/{id}' if not os.path.isdir(path): return False # Check if it's a git repo if not os.path.isdir(f'{path}/.git'): # Remove git from sites.json with open('sites.json', 'r') as file: sites = json.loads(file.read()) for site in sites: if site['name'] == name: del site['git'] with open('sites.json', 'w') as file: file.write(json.dumps(sites)) return False os.system(f'cd {path} && git pull') return True