#!/bin/bash set -euo pipefail if [ "$(id -u)" -ne 0 ]; then echo "Run as root" exit 1 fi apt update apt upgrade -y apt install -y nginx tor python3 python3-venv python3-pip qrencode sqlite3 git curl socat # create site user useradd -m -s /bin/bash horus || true mkdir -p /home/horus/www chown -R horus:horus /home/horus # nginx config (listen on localhost only) cat > /etc/nginx/sites-available/horus <<'NGINX' server { listen 127.0.0.1:8080; server_name localhost; root /home/horus/www; index index.html; access_log off; error_log /dev/null; } NGINX ln -sf /etc/nginx/sites-available/horus /etc/nginx/sites-enabled/horus nginx -t systemctl restart nginx # tor hidden service for site if ! grep -q "HiddenServiceDir /var/lib/tor/horus_hidden/" /etc/tor/torrc 2>/dev/null; then cat >> /etc/tor/torrc <<'TOR' HiddenServiceDir /var/lib/tor/horus_hidden/ HiddenServiceVersion 3 HiddenServicePort 80 127.0.0.1:8080 TOR fi systemctl restart tor || true # prepare python env and flask app as horus user sudo -u horus bash -lc "python3 -m venv /home/horus/venv && /home/horus/venv/bin/pip install --upgrade pip flask requests" # create minimal flask app cat > /home/horus/www/app.py <<'PY' from flask import Flask, render_template_string, send_from_directory import sqlite3, os, subprocess, requests app = Flask(__name__) DB='/home/horus/site.db' SITE_ROOT='/home/horus/www' RPC_URL='http://127.0.0.1:18082/json_rpc' # monero-wallet-rpc INDEX_HTML='''
Price: {{price}} XMR
Address: {{addr}}

Status: {{status}}
''' def init_db(): if not os.path.exists(DB): conn=sqlite3.connect(DB); c=conn.cursor() c.execute('CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price REAL)') c.execute('CREATE TABLE orders (id INTEGER PRIMARY KEY, product_id INTEGER, subaddress TEXT, amount REAL, status TEXT)') conn.commit(); conn.close() def rpc(method, params=None): payload={'jsonrpc':'2.0','id':'0','method':method} if params: payload['params']=params r=requests.post(RPC_URL, json=payload, timeout=10) return r.json() @app.route('/') def index(): conn=sqlite3.connect(DB); c=conn.cursor() c.execute('SELECT id,name,price FROM products'); products=c.fetchall(); conn.close() return render_template_string(INDEX_HTML, products=products) @app.route('/buy/