7 Commits

Author SHA1 Message Date
908a4e0422 bot: Check for install every 5 seconds
All checks were successful
Build Docker / Build Master (push) Successful in 22s
Build Docker / Build Bot (push) Successful in 26s
2023-08-25 12:54:31 +10:00
d217309e74 bot: Fixed check if site ready function args
All checks were successful
Build Docker / Build Master (push) Successful in 21s
Build Docker / Build Bot (push) Successful in 24s
2023-08-25 12:51:58 +10:00
ce8827ed97 worker: Install missing update repo
All checks were successful
Build Docker / Build Bot (push) Successful in 24s
Build Docker / Build Master (push) Successful in 25s
2023-08-25 12:49:29 +10:00
3b914abf7a bot: Send a dm with the site info when the site is ready
All checks were successful
Build Docker / Build Master (push) Successful in 23s
Build Docker / Build Bot (push) Successful in 26s
2023-08-25 12:46:08 +10:00
d7c6e1cf70 docs: Cleared up some info
All checks were successful
Build Docker / Build Master (push) Successful in 24s
Build Docker / Build Bot (push) Successful in 22s
2023-08-25 12:36:23 +10:00
dbbb60cab8 bot: Add private ip to new worker command
All checks were successful
Build Docker / Build Bot (push) Successful in 27s
Build Docker / Build Master (push) Successful in 27s
2023-08-25 12:26:26 +10:00
f54d805371 main: Initial private ip for api 2023-08-25 12:25:23 +10:00
4 changed files with 68 additions and 16 deletions

View File

@@ -24,7 +24,7 @@ The bot will be used to provide an easier way to manage the master server.
After installing the master and discord bot you can use the following commands (as bot owner).
```
/addworker <ip> <name> | add a worker to the master server pool (Make sure the master can access port 5000 on the worker, and don't allow anyone else to access it)
/addworker <ip> <private ip> <name> | add a worker to the master server pool
/listworkers | list all workers
/licence | Creates a licence key (valid for 1 wp site)
```
@@ -90,9 +90,14 @@ screen -dmS hnshosting-worker python3 main.py
```
Add worker to master server pool:
The master server will need to be able to access port 5000 on the worker server over the PRIVATE ip. This is not secured by the api key so make sure you don't allow anyone else to access it.
```sh
curl -X POST http://master-server-ip:5000/add-worker?worker=worker-name&ip=worker-server-ip -H "key: api-key"
curl -X POST http://master-server-ip:5000/add-worker?worker=worker-name&ip=worker-server-ip&priv=worker-server-private-ip -H "key: api-key"
```
Alternatively you can use the discord bot to add the worker to the master server pool.
```
/addworker <ip> <private ip> <name>
```
## Discord bot install

View File

@@ -3,6 +3,7 @@ from dotenv import load_dotenv
import discord
from discord import app_commands
import requests
import asyncio
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
@@ -21,9 +22,9 @@ client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)
@tree.command(name="addworker", description="Adds a worker to the master server")
async def addworker(ctx, ip: str, name: str):
async def addworker(ctx, ip: str,privateip: str, name: str):
if ctx.user.id == ADMINID:
r = requests.post(f"http://{Master_IP}:{Master_Port}/add-worker?worker={name}&ip={ip}",headers={"key":os.getenv('WORKER_KEY')})
r = requests.post(f"http://{Master_IP}:{Master_Port}/add-worker?worker={name}&ip={ip}&priv={privateip}",headers={"key":os.getenv('WORKER_KEY')})
if r.status_code == 200:
await ctx.response.send_message(f"Worker {name} added to the master server",ephemeral=True)
else:
@@ -69,7 +70,22 @@ async def createsite(ctx, domain: str, licence: str):
if r.status_code == 200:
json = r.json()
if json['success'] == "true":
await ctx.response.send_message(f"Site {domain} creating...\nPlease wait a few minutes and then send /siteinfo domain:{domain}")
await ctx.response.send_message(f"Site {domain} creating...\nI'll send you a message when it's ready")
ready = False
while ready == False:
ready = await check_site_ready(domain)
if ready == False:
await asyncio.sleep(5)
r = requests.get(f"http://{Master_IP}:{Master_Port}/site-info?domain={domain}")
json = r.json()
if json['success'] == "true":
await ctx.user.send(f"Site {domain} is ready!\nHere is the site info for {json['domain']}\nA: `{json['ip']}`\nTLSA: `{json['tlsa']}`\nMake sure you put the TLSA in either `_443._tcp.{domain}` or `*.{domain}`")
else:
await ctx.user.send(f"Error getting site info\n" + json['error'])
else:
await ctx.response.send_message(f"Error creating site\n" + json['error'])
else:
@@ -88,6 +104,17 @@ async def siteinfo(ctx, domain: str):
else:
await ctx.response.send_message(f"Error getting site info\n" + r.text)
async def check_site_ready(domain):
r = requests.get(f"http://{Master_IP}:{Master_Port}/site-info?domain={domain}")
if r.status_code == 200:
json = r.json()
if json['success'] == "true":
return True
else:
return False
else:
return False
# When the bot is ready
@client.event
async def on_ready():

View File

@@ -107,9 +107,10 @@ def new_site():
def add_worker():
worker=request.args.get('worker')
worker_IP=request.args.get('ip')
worker_PRIV=request.args.get('priv')
# Get API header
api_key = request.headers.get('key')
if api_key == None or worker == None or worker_IP == None:
if api_key == None or worker == None or worker_IP == None or worker_PRIV == None:
return jsonify({'error': 'Invalid API key or worker info', 'success': 'false'})
if api_key != os.getenv('WORKER_KEY'):
return jsonify({'error': 'Invalid API key', 'success': 'false'})
@@ -130,11 +131,11 @@ def add_worker():
# Add worker to file
workers_file = open('/data/workers.txt', 'a')
workers_file.write(worker + ":" + worker_IP + '\n')
workers_file.write(worker + ":" + worker_PRIV + ":"+ worker_IP + '\n')
workers_file.close()
online=True
resp=requests.get("http://"+worker_IP + ":5000/ping",timeout=2)
resp=requests.get("http://"+worker_PRIV + ":5000/ping",timeout=2)
if (resp.status_code != 200):
online=False
@@ -174,14 +175,14 @@ def list_workers():
resp=requests.get("http://"+worker.split(':')[1].strip('\n') + ":5000/status",timeout=2)
if (resp.status_code != 200):
online=False
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[1].strip('\n'), 'online': online, 'sites': 0, 'status': 'offline'})
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[2].strip('\n'), 'online': online, 'sites': 0, 'status': 'offline'})
continue
sites = resp.json()['num_sites']
availability = resp.json()['availability']
if availability == True:
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[1].strip('\n'), 'online': online, 'sites': sites, 'status': 'ready'})
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[2].strip('\n'), 'online': online, 'sites': sites, 'status': 'ready'})
else:
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[1].strip('\n'), 'online': online, 'sites': sites, 'status': 'full'})
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[2].strip('\n'), 'online': online, 'sites': sites, 'status': 'full'})
if len(worker_list) == 0:
return jsonify({'error': 'No workers available', 'success': 'false'})
@@ -203,17 +204,18 @@ def site_status():
return jsonify({'error': 'Domain does not exist', 'success': 'false'})
# Get worker ip
ip = workerIP(worker)
ip = workerIP_PRIV(worker)
# Get TLSA record
resp=requests.get("http://"+ip + ":5000/tlsa?domain=" + domain,timeout=2)
json = resp.json()
publicIP = workerIP(worker)
if "tlsa" in json:
tlsa = json['tlsa']
return jsonify({'success': 'true', 'domain': domain, 'ip': ip, 'tlsa': tlsa})
return jsonify({'success': 'true', 'domain': domain, 'ip': publicIP, 'tlsa': tlsa})
else:
return jsonify({'success': 'false', 'domain': domain, 'ip': ip, 'tlsa': 'none','error': 'No TLSA record found'})
return jsonify({'success': 'false', 'domain': domain, 'ip': publicIP, 'tlsa': 'none','error': 'No TLSA record found'})
@app.route('/tlsa', methods=['GET'])
@@ -232,7 +234,7 @@ def tlsa():
return jsonify({'error': 'Domain does not exist', 'success': 'false'})
# Get worker ip
ip = workerIP(worker)
ip = workerIP_PRIV(worker)
# Get TLSA record
resp=requests.get("http://"+ip + ":5000/tlsa?domain=" + domain,timeout=2)
@@ -343,6 +345,24 @@ def site_worker(domain):
sites_file.close()
return worker
def workerIP_PRIV(worker):
# If file doesn't exist, create it
try:
workers_file = open('/data/workers.txt', 'r')
except FileNotFoundError:
workers_file = open('/data/workers.txt', 'w')
workers_file.close()
workers_file = open('/data/workers.txt', 'r')
ip = None
for line in workers_file.readlines():
if worker == line.split(':')[0]:
ip = line.split(':')[2].strip('\n')
break
workers_file.close()
return ip
def workerIP(worker):
# If file doesn't exist, create it
try:
@@ -360,7 +380,6 @@ def workerIP(worker):
workers_file.close()
return ip
# Start the server

View File

@@ -11,6 +11,7 @@ KERNEL_VERSION=$(uname -r)
sudo apt-mark hold linux-image-generic linux-headers-generic linux-generic linux-image-$KERNEL_VERSION linux-headers-$KERNEL_VERSION
# Install Docker
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common python3-pip nginx -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null