Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ build/
*.so
# Logs
*.log
# Reports
reports/
35 changes: 20 additions & 15 deletions 01_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ AP_IFACE="wlan0" # WiFi interface used as AP (internal hotspot)
WAN_IFACE="eth0" # LAN port = uplink from ISP router/switch

AP_SSID="PiGateway"
AP_PASS="SuperSecret99" # ← Change this!
AP_PASS="SuperSecret99" # ← CHANGE THIS before production deployment!
AP_CHANNEL=6
AP_IP="192.168.50.1"
AP_SUBNET="192.168.50.0/24"
Expand All @@ -30,12 +30,12 @@ AP_COUNTRY="US" # ← Set your 2-letter country code (regulatory domai

WARP_MTU=1280
DASHBOARD_PORT=5000
BOT_TOKEN="" # Set after install or in /etc/EdgeGateway/config.env
BOT_TOKEN="" # Set after install or in /etc/WarpGate/config.env
ADMIN_CHAT_ID="" # Your Telegram chat ID

# ── Persist config ────────────────────────────────────────
mkdir -p /etc/EdgeGateway
cat > /etc/EdgeGateway/config.env <<EOF
mkdir -p /etc/WarpGate
cat > /etc/WarpGate/config.env <<EOF
AP_IFACE=$AP_IFACE
WAN_IFACE=$WAN_IFACE
AP_SSID=$AP_SSID
Expand All @@ -51,7 +51,7 @@ DASHBOARD_PORT=$DASHBOARD_PORT
BOT_TOKEN=$BOT_TOKEN
ADMIN_CHAT_ID=$ADMIN_CHAT_ID
EOF
ok "Config written to /etc/EdgeGateway/config.env"
ok "Config written to /etc/WarpGate/config.env"

# ── System update ─────────────────────────────────────────
info "Updating system..."
Expand Down Expand Up @@ -83,18 +83,15 @@ ok "Cloudflare WARP installed"

# ── Python venv for dashboard + bot ──────────────────────
info "Setting up Python environment..."
python3 -m venv /opt/EdgeGateway/venv
/opt/EdgeGateway/venv/bin/pip install -q --upgrade pip
/opt/EdgeGateway/venv/bin/pip install -q \
flask flask-socketio \
python-telegram-bot==20.8 \
psutil requests \
gunicorn eventlet
python3 -m venv /opt/WarpGate/venv
/opt/WarpGate/venv/bin/pip install -q --upgrade pip
/opt/WarpGate/venv/bin/pip install -q -r /opt/WarpGate/requirements.txt
ok "Python environment ready"

# ── Copy app files ────────────────────────────────────────
info "Installing gateway app files..."
mkdir -p /opt/EdgeGateway/{templates,static}
mkdir -p /opt/WarpGate/{templates,static}
cp requirements.txt /opt/WarpGate/requirements.txt
# (Files will be copied by 02_configure.sh)

# ── Enable IP forwarding ──────────────────────────────────
Expand Down Expand Up @@ -166,6 +163,11 @@ iptables -F
iptables -t nat -F
iptables -X

# Default deny
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
Expand Down Expand Up @@ -203,19 +205,22 @@ systemctl unmask hostapd
systemctl enable hostapd dnsmasq warp-svc
ok "Services enabled"

# ── Install systemd units (created by next script) ───────
# ── Done ───────────────────────────────────────────────────
info "Done! Run 02_configure.sh to deploy dashboard & bot."
echo ""
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN} Pi Gateway base install complete! ${NC}"
echo -e "${GREEN}======================================${NC}"
echo ""
echo -e "${YELLOW}⚠ WARNING: Default AP password is set!${NC}"
echo -e "${YELLOW} Edit AP_PASS in 01_install.sh before production use.${NC}"
echo ""
echo " AP SSID : $AP_SSID"
echo " AP Pass : $AP_PASS"
echo " AP IP : $AP_IP"
echo ""
echo " Next steps:"
echo " 1. Edit /etc/EdgeGateway/config.env → add BOT_TOKEN + ADMIN_CHAT_ID"
echo " 1. Edit /etc/WarpGate/config.env → add BOT_TOKEN + ADMIN_CHAT_ID"
echo " 2. Run: sudo bash 02_configure.sh"
echo " 3. Reboot: sudo reboot"
echo ""
25 changes: 12 additions & 13 deletions 02_configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ ok() { echo -e "${GREEN}[OK]${NC} $1"; }
die() { echo -e "${RED}[ERR]${NC} $1"; exit 1; }

[[ $EUID -ne 0 ]] && die "Run as root: sudo bash 02_configure.sh"
source /etc/EdgeGateway/config.env
source /etc/WarpGate/config.env

APP_DIR=/opt/EdgeGateway
APP_DIR=/opt/WarpGate
VENV=$APP_DIR/venv

# ── Validate required config ───────────────────────────────
if [[ -z "$BOT_TOKEN" ]]; then
die "BOT_TOKEN is empty. Edit /etc/EdgeGateway/config.env first."
die "BOT_TOKEN is empty. Edit /etc/WarpGate/config.env first."
fi
if [[ -z "$ADMIN_CHAT_ID" ]]; then
die "ADMIN_CHAT_ID is empty. Edit /etc/EdgeGateway/config.env first."
die "ADMIN_CHAT_ID is empty. Edit /etc/WarpGate/config.env first."
fi

# ── WARP watchdog script ──────────────────────────────────
Expand Down Expand Up @@ -52,7 +52,7 @@ cat > /usr/local/bin/gw-stats.sh <<'STATS'
set -o pipefail

# Source config for interface names
source /etc/EdgeGateway/config.env 2>/dev/null
source /etc/WarpGate/config.env 2>/dev/null

# Fallback defaults if config didn't load
: "${WAN_IFACE:=eth0}"
Expand Down Expand Up @@ -140,7 +140,7 @@ ok "Stats helper ready"
# ── Flask Dashboard ───────────────────────────────────────
info "Deploying dashboard..."
cat > $APP_DIR/dashboard.py <<'DASHBOARD'
import os, json, subprocess, time
import os, json, subprocess, time, ipaddress
from flask import Flask, render_template, jsonify, request
from flask_socketio import SocketIO
import threading
Expand All @@ -151,7 +151,7 @@ socketio = SocketIO(app, cors_allowed_origins=[], async_mode="eventlet")
PORT = int(os.environ.get("DASHBOARD_PORT", 5000))

# Restrict API endpoints to AP subnet by default
AP_SUBNET = os.environ.get("AP_SUBNET", "192.168.50.0/24")
AP_SUBNET = ipaddress.ip_network(os.environ.get("AP_SUBNET", "192.168.50.0/24"), strict=False)

def get_stats():
try:
Expand All @@ -177,9 +177,8 @@ def restrict_subnet():
"""Optional: restrict write operations to AP subnet."""
# Allow all GET requests; restrict POST to AP subnet only
if request.method == "POST":
client_ip = request.remote_addr
# Check if client is in AP subnet (simple prefix check for /24)
if not client_ip.startswith(AP_SUBNET.rsplit(".", 1)[0] + "."):
client_ip = ipaddress.ip_address(request.remote_addr)
if client_ip not in AP_SUBNET:
return jsonify({"error": "Forbidden: not on AP subnet"}), 403

@app.route("/")
Expand Down Expand Up @@ -254,7 +253,7 @@ BOT_TOKEN = os.environ.get("BOT_TOKEN", "")
ADMIN_IDS = [int(x) for x in os.environ.get("ADMIN_CHAT_ID", "").split(",") if x.strip()]

if not BOT_TOKEN:
raise SystemExit("BOT_TOKEN not set! Edit /etc/EdgeGateway/config.env")
raise SystemExit("BOT_TOKEN not set! Edit /etc/WarpGate/config.env")

if not ADMIN_IDS:
logger.warning("ADMIN_CHAT_ID is empty — no users will have admin access!")
Expand Down Expand Up @@ -392,7 +391,7 @@ After=network.target warp-svc.service
[Service]
User=root
WorkingDirectory=$APP_DIR
EnvironmentFile=/etc/EdgeGateway/config.env
EnvironmentFile=/etc/WarpGate/config.env
ExecStart=$VENV/bin/python $APP_DIR/dashboard.py
Restart=always
RestartSec=5
Expand All @@ -410,7 +409,7 @@ After=network.target
[Service]
User=root
WorkingDirectory=$APP_DIR
EnvironmentFile=/etc/EdgeGateway/config.env
EnvironmentFile=/etc/WarpGate/config.env
ExecStart=$VENV/bin/python $APP_DIR/bot.py
Restart=always
RestartSec=10
Expand Down
Loading