site-manager/sites.py

329 lines
7.8 KiB
Python
Raw Normal View History

2024-02-23 13:55:05 +11:00
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')
2024-02-23 15:30:57 +11:00
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
2024-02-23 13:55:05 +11:00
2024-02-23 15:15:34 +11:00
id = len(sites)
for site in sites:
if site['id'] >= id:
id = site['id'] + 1
2024-02-23 13:55:05 +11:00
sites.append({
'name': name,
'domain': domain,
'active': False,
'tlsa': tlsa,
2024-02-23 15:15:34 +11:00
'id': id
2024-02-23 13:55:05 +11:00
})
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)
2024-02-23 15:30:57 +11:00
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
2024-02-23 13:55:05 +11:00
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):
2024-02-23 14:59:35 +11:00
site = get_site(site)
id = site['id']
path = f'/var/www/{id}'
2024-02-23 13:55:05 +11:00
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']
2024-02-23 14:58:21 +11:00
location = f'/var/www/{id}'
2024-02-23 13:55:05 +11:00
2024-02-23 15:30:57 +11:00
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;
'''
2024-02-23 13:55:05 +11:00
conf = f'''
server {{
listen 80;
listen [::]:80;
2024-02-23 14:42:15 +11:00
root '{location}';
2024-02-23 13:55:05 +11:00
index index.html;
server_name {domain} *.{domain};
location / {{
2024-02-23 15:51:56 +11:00
try_files $uri $uri/ @htmlext;
2024-02-23 13:55:05 +11:00
}}
location ~ \.html$ {{
2024-02-23 15:51:56 +11:00
try_files $uri =404;
2024-02-23 13:55:05 +11:00
}}
location @htmlext {{
2024-02-23 15:51:56 +11:00
rewrite ^(.*)$ $1.html last;
2024-02-23 13:55:05 +11:00
}}
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;
}}
2024-02-23 15:30:57 +11:00
{ssl}
2024-02-23 13:55:05 +11:00
}}
'''
# Add alt domains
if 'alt_domains' in site:
for alt in site['alt_domains']:
2024-02-23 15:30:57 +11:00
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 = ""
2024-02-23 13:55:05 +11:00
conf += f'''
server {{
listen 80;
listen [::]:80;
2024-02-23 14:42:15 +11:00
root '{location}';
2024-02-23 13:55:05 +11:00
index index.html;
server_name {alt} *.{alt};
location / {{
2024-02-23 15:51:56 +11:00
try_files $uri $uri/ @htmlext;
2024-02-23 13:55:05 +11:00
}}
location ~ \.html$ {{
2024-02-23 15:51:56 +11:00
try_files $uri =404;
2024-02-23 13:55:05 +11:00
}}
location @htmlext {{
2024-02-23 15:51:56 +11:00
rewrite ^(.*)$ $1.html last;
2024-02-23 13:55:05 +11:00
}}
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;
}}
2024-02-23 15:59:01 +11:00
{ssl}
2024-02-23 13:55:05 +11:00
}}
'''
2024-02-23 14:42:15 +11:00
with open(f'/etc/nginx/sites-enabled/{id}.conf', 'w') as file:
2024-02-23 13:55:05 +11:00
file.write(conf)
# Restart nginx
os.system('systemctl restart nginx')
2024-02-23 15:30:57 +11:00
# 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)
2024-02-23 16:00:40 +11:00
email = f'admin@{icann_domains[0]}'
2024-02-23 15:30:57 +11:00
icann_domains = " -d ".join(icann_domains)
icann_domains = f'-d {icann_domains}'
2024-02-23 16:00:40 +11:00
os.system(f'certbot --nginx {icann_domains} --non-interactive --agree-tos --email {email} --redirect')
2024-02-23 15:30:57 +11:00
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:
2024-02-23 15:59:01 +11:00
return True
2024-02-23 17:07:34 +11:00
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