Files
firefrost-operations-manual/docs/tasks/whitelist-manager/deployment-plan.md
mkrause612 c6ab3365db Move deployment plan to proper task directory
Migrating whitelist-manager-deployment-plan.md:
- FROM: docs/tools/whitelist-manager-deployment-plan.md
- TO: docs/tasks/whitelist-manager/deployment-plan.md

Following FFG-STD-002 naming convention:
- Task-specific docs live in docs/tasks/[task-name]/
- Renamed to standard name: deployment-plan.md

Content unchanged - this is a pure migration.

Next step: Delete old location (docs/tools/)

Phase 3 of complete restructure.

Date: February 16, 2026
Implemented by: The Chronicler
2026-02-16 06:19:35 -06:00

1027 lines
29 KiB
Markdown

# Whitelist Manager Web Dashboard - Deployment Plan
**Document Status:** ACTIVE DEPLOYMENT PLAN
**Created:** February 16, 2026
**Created By:** The Chronicler (current session)
**Priority:** Tier 0 - Immediate Win
**Estimated Time:** 2-2.5 hours
**Scope:** Build web dashboard for managing Minecraft server whitelists across 11 servers
---
## 📊 PROJECT OVERVIEW
### Purpose
Create a web-based dashboard to manage player whitelists across all 11 Minecraft servers, replacing manual SSH and Pterodactyl console work.
### Current Pain Points
- Manual SSH to each node (TX1, NC1)
- Update whitelist on each of 12+ servers individually via Pterodactyl console
- Time-consuming (15+ minutes per whitelist change)
- Error-prone (easy to miss a server)
- No visibility into current whitelist status across all servers
### Solution
Centralized web dashboard at `https://whitelist.firefrostgaming.com` that:
- Shows all 11 Minecraft servers with whitelist status (ON/OFF)
- Toggle whitelist enforcement with one click per server
- Add player to all servers at once
- Remove player from all servers at once
- View current whitelist for each server
- Accessible to authorized staff only
### Success Metrics
- ✅ 15-minute task → 30 seconds
- ✅ Zero-error whitelist management
- ✅ Full visibility across all servers
- ✅ Staff can manage without SSH access
---
## 🎯 SCOPE
### In Scope (MVP)
- Web dashboard with server list and status
- Toggle whitelist ON/OFF per server
- Add player to one or all servers
- Remove player from one or all servers
- View current whitelist
- Basic authentication (username/password)
- SSL/HTTPS access
- Responsive design (works on mobile)
### Out of Scope (Future Enhancements)
- Discord bot integration
- Paymenter subscriber auto-whitelist
- Whitelist sync verification
- Player activity tracking
- Automated whitelist backup
- Multi-user role permissions
- SSO integration with Wiki.js
### Server Coverage
**Managed (11 Minecraft servers):**
1. Reclamation - TX (`1eb33479-a6bc-4e8f-b64d-d1e4bfa0a8b4`)
2. The Ember Project - NC (`124f9060-58a7-457a-b2cf-b4024fce2951`)
3. Stoneblock 4 - TX (`a0efbfe8-4b97-4a90-869d-ffe6d3072bd5`)
4. Minecolonies: Create and Conquer - NC (`a14201d2-83b2-44e6-ae48-e6c4cbc56f24`)
5. Society: Sunlit Valley - TX (`9310d0a6-62a6-4fe6-82c4-eb483dc68876`)
6. All The Mods 10 - NC (`82e63949-8fbf-4a44-b32a-53324e8492bf`)
7. Vanilla 1.21.11 - TX (`3bed1bda-f648-4630-801a-fe9f2e3d3f27`)
8. Homestead - NC (`2f85d4ef-aa49-4dd6-b448-beb3fca1db12`)
9. All The Mons - TX (`668a5220-7e72-4379-9165-bdbb84bc9806`)
10. EMC Subterra Tech - NC (`09a95f38-9f8c-404a-9557-3a7c44258223`)
**Excluded (Non-Minecraft):**
- FoundryVTT - TX (`7d8f15a0-4ee7-4dd6-85dc-ab42966f733d`) - Not Minecraft
- Hytale - NC (`13c80cb8-f6f8-4bfe-9cdb-823d7e951584`) - Not Minecraft
---
## 🏗️ ARCHITECTURE
### Technology Stack
- **Backend:** Python 3 + Flask (lightweight web framework)
- **Frontend:** HTML5 + TailwindCSS (responsive design)
- **API:** Pterodactyl API v1 (websocket for console commands)
- **Web Server:** Nginx (reverse proxy)
- **SSL:** Let's Encrypt (automatic renewal)
- **Process Manager:** systemd (auto-restart on failure)
- **Authentication:** Flask-HTTPAuth (basic auth)
### Infrastructure
- **Host:** Ghost VPS (Chicago IL) - same server as Wiki.js Staff
- **Domain:** whitelist.firefrostgaming.com
- **Port:** 5001 (internal), 443 (external via Nginx)
- **Directory:** `/opt/firefrost/whitelist-manager/`
### File Structure
```
/opt/firefrost/whitelist-manager/
├── app.py # Flask application (main)
├── config.json # Server list + settings
├── requirements.txt # Python dependencies
├── .env # Secrets (API key, auth credentials)
├── templates/
│ └── dashboard.html # Web interface
├── static/
│ ├── css/
│ │ └── styles.css # Custom styling
│ └── js/
│ └── dashboard.js # Frontend logic
└── logs/
└── whitelist-manager.log # Application logs
```
### Data Flow
```
User Browser (HTTPS)
Nginx (reverse proxy, SSL termination)
Flask App (port 5001)
Pterodactyl API (console commands)
Minecraft Server (whitelist.json updated)
```
---
## 📝 PHASE 1: INFORMATION GATHERING
**Time Estimate:** 5 minutes
### Requirements Checklist
**1. Pterodactyl Access**
- [ ] Pterodactyl panel URL: `________________________`
- [ ] API key generated (Account → API Credentials)
- [ ] API key permissions verified (can send console commands)
- [ ] Test API key with one server
**2. Ghost VPS Access**
- [ ] SSH credentials obtained
- [ ] Root access verified
- [ ] Nginx installed and running
- [ ] Python 3.9+ installed
- [ ] Port 5001 available
**3. Whitelist Method**
Determine how whitelist enforcement works on Minecraft servers:
- [ ] **Option A:** Console command (`/whitelist on`, `/whitelist off`)
- [ ] **Option B:** server.properties file (`white-list=true/false` + restart)
- [ ] **Option C:** Pterodactyl startup variable
**Recommended:** Option A (console commands) - no restart required
**4. Authentication**
- [ ] Admin username chosen: `________________________`
- [ ] Admin password chosen: `________________________`
- [ ] Additional staff users (if needed): `________________________`
**5. DNS Configuration**
- [ ] DNS provider access (Cloudflare/other)
- [ ] Create A record: `whitelist.firefrostgaming.com` → Ghost VPS IP
- [ ] TTL set to 300 (5 minutes for testing)
---
## 📝 PHASE 2: DNS & INFRASTRUCTURE SETUP
**Time Estimate:** 15 minutes
### Step 1: DNS Configuration
```bash
# Create DNS A Record
# Domain: whitelist.firefrostgaming.com
# Type: A
# Value: [Ghost VPS IP Address]
# TTL: 300
# Proxy: Off (for initial setup)
```
**Verification:**
```bash
# Wait 5 minutes, then test:
nslookup whitelist.firefrostgaming.com
# Should return Ghost VPS IP
```
### Step 2: SSH into Ghost VPS
```bash
ssh root@[ghost-vps-ip]
```
### Step 3: Create Application Directory
```bash
# Create directory structure
mkdir -p /opt/firefrost/whitelist-manager/{templates,static/css,static/js,logs}
cd /opt/firefrost/whitelist-manager
# Set permissions
chown -R www-data:www-data /opt/firefrost/whitelist-manager
chmod -R 755 /opt/firefrost/whitelist-manager
```
### Step 4: Install Python Dependencies
```bash
# Update system
apt update
apt install -y python3 python3-pip python3-venv
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install Flask and dependencies
pip install flask flask-cors flask-httpauth python-dotenv requests websocket-client
pip freeze > requirements.txt
```
### Step 5: Verify Nginx Installed
```bash
# Check Nginx status
systemctl status nginx
# If not installed:
apt install -y nginx certbot python3-certbot-nginx
```
---
## 📝 PHASE 3: BUILD THE APPLICATION
**Time Estimate:** 45-60 minutes
### Step 1: Create Server Configuration
**File:** `/opt/firefrost/whitelist-manager/config.json`
```json
{
"pterodactyl": {
"panel_url": "https://panel.firefrostgaming.com",
"api_key": "PLACEHOLDER_WILL_BE_IN_ENV_FILE"
},
"servers": [
{
"id": "1",
"name": "Reclamation - TX",
"uuid": "1eb33479-a6bc-4e8f-b64d-d1e4bfa0a8b4",
"node": "TX1",
"enabled": true
},
{
"id": "2",
"name": "The Ember Project - NC",
"uuid": "124f9060-58a7-457a-b2cf-b4024fce2951",
"node": "NC1",
"enabled": true
},
{
"id": "3",
"name": "Stoneblock 4 - TX",
"uuid": "a0efbfe8-4b97-4a90-869d-ffe6d3072bd5",
"node": "TX1",
"enabled": true
},
{
"id": "4",
"name": "Minecolonies: Create and Conquer - NC",
"uuid": "a14201d2-83b2-44e6-ae48-e6c4cbc56f24",
"node": "NC1",
"enabled": true
},
{
"id": "5",
"name": "Society: Sunlit Valley - TX",
"uuid": "9310d0a6-62a6-4fe6-82c4-eb483dc68876",
"node": "TX1",
"enabled": true
},
{
"id": "6",
"name": "All The Mods 10 - NC",
"uuid": "82e63949-8fbf-4a44-b32a-53324e8492bf",
"node": "NC1",
"enabled": true
},
{
"id": "7",
"name": "Vanilla 1.21.11 - TX",
"uuid": "3bed1bda-f648-4630-801a-fe9f2e3d3f27",
"node": "TX1",
"enabled": true
},
{
"id": "8",
"name": "Homestead - NC",
"uuid": "2f85d4ef-aa49-4dd6-b448-beb3fca1db12",
"node": "NC1",
"enabled": true
},
{
"id": "9",
"name": "All The Mons - TX",
"uuid": "668a5220-7e72-4379-9165-bdbb84bc9806",
"node": "TX1",
"enabled": true
},
{
"id": "10",
"name": "EMC Subterra Tech - NC",
"uuid": "09a95f38-9f8c-404a-9557-3a7c44258223",
"node": "NC1",
"enabled": true
}
],
"settings": {
"log_level": "INFO",
"log_file": "/opt/firefrost/whitelist-manager/logs/whitelist-manager.log",
"api_timeout": 30,
"console_command_delay": 1
}
}
```
### Step 2: Create Environment File
**File:** `/opt/firefrost/whitelist-manager/.env`
```bash
# Pterodactyl API
PTERODACTYL_API_KEY=ptlc_YOUR_API_KEY_HERE
# Flask Configuration
FLASK_SECRET_KEY=GENERATE_RANDOM_STRING_HERE
FLASK_ENV=production
# Basic Auth
ADMIN_USERNAME=admin
ADMIN_PASSWORD=SECURE_PASSWORD_HERE
# Application
HOST=127.0.0.1
PORT=5001
DEBUG=False
```
**Security:**
```bash
chmod 600 /opt/firefrost/whitelist-manager/.env
chown www-data:www-data /opt/firefrost/whitelist-manager/.env
```
### Step 3: Create Flask Application
**File:** `/opt/firefrost/whitelist-manager/app.py`
```python
#!/usr/bin/env python3
"""
Firefrost Gaming - Whitelist Manager
Web dashboard for managing Minecraft server whitelists via Pterodactyl API
"""
import os
import json
import logging
from datetime import datetime
from flask import Flask, render_template, request, jsonify
from flask_httpauth import HTTPBasicAuth
from dotenv import load_dotenv
import requests
# Load environment variables
load_dotenv()
# Initialize Flask app
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('FLASK_SECRET_KEY')
auth = HTTPBasicAuth()
# Load configuration
with open('config.json', 'r') as f:
config = json.load(f)
# Setup logging
logging.basicConfig(
level=getattr(logging, config['settings']['log_level']),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(config['settings']['log_file']),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# Pterodactyl API Configuration
PANEL_URL = config['pterodactyl']['panel_url']
API_KEY = os.getenv('PTERODACTYL_API_KEY')
HEADERS = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json',
'Accept': 'Application/vnd.pterodactyl.v1+json'
}
# Authentication
@auth.verify_password
def verify_password(username, password):
"""Verify basic auth credentials"""
admin_user = os.getenv('ADMIN_USERNAME')
admin_pass = os.getenv('ADMIN_PASSWORD')
if username == admin_user and password == admin_pass:
return username
return None
# Routes
@app.route('/')
@auth.login_required
def index():
"""Main dashboard"""
return render_template('dashboard.html', servers=config['servers'])
@app.route('/api/servers', methods=['GET'])
@auth.login_required
def get_servers():
"""Get all server configurations"""
return jsonify(config['servers'])
@app.route('/api/server/<uuid>/whitelist/status', methods=['GET'])
@auth.login_required
def get_whitelist_status(uuid):
"""Get whitelist status for a specific server"""
try:
# Send console command to check whitelist status
response = send_console_command(uuid, '/whitelist list')
# Parse response to determine if whitelist is enabled
# This is simplified - actual implementation needs websocket
return jsonify({
'uuid': uuid,
'enabled': True, # Placeholder
'players': [] # Placeholder
})
except Exception as e:
logger.error(f"Error getting whitelist status for {uuid}: {str(e)}")
return jsonify({'error': str(e)}), 500
@app.route('/api/server/<uuid>/whitelist/toggle', methods=['POST'])
@auth.login_required
def toggle_whitelist(uuid):
"""Toggle whitelist on/off for a specific server"""
try:
data = request.get_json()
enabled = data.get('enabled', False)
command = '/whitelist on' if enabled else '/whitelist off'
response = send_console_command(uuid, command)
logger.info(f"Whitelist {'enabled' if enabled else 'disabled'} for {uuid}")
return jsonify({'success': True, 'enabled': enabled})
except Exception as e:
logger.error(f"Error toggling whitelist for {uuid}: {str(e)}")
return jsonify({'error': str(e)}), 500
@app.route('/api/server/<uuid>/whitelist/add', methods=['POST'])
@auth.login_required
def add_to_whitelist(uuid):
"""Add player to whitelist"""
try:
data = request.get_json()
player = data.get('player')
if not player:
return jsonify({'error': 'Player name required'}), 400
command = f'/whitelist add {player}'
response = send_console_command(uuid, command)
logger.info(f"Added {player} to whitelist on {uuid}")
return jsonify({'success': True, 'player': player})
except Exception as e:
logger.error(f"Error adding player to {uuid}: {str(e)}")
return jsonify({'error': str(e)}), 500
@app.route('/api/server/<uuid>/whitelist/remove', methods=['POST'])
@auth.login_required
def remove_from_whitelist(uuid):
"""Remove player from whitelist"""
try:
data = request.get_json()
player = data.get('player')
if not player:
return jsonify({'error': 'Player name required'}), 400
command = f'/whitelist remove {player}'
response = send_console_command(uuid, command)
logger.info(f"Removed {player} from whitelist on {uuid}")
return jsonify({'success': True, 'player': player})
except Exception as e:
logger.error(f"Error removing player from {uuid}: {str(e)}")
return jsonify({'error': str(e)}), 500
@app.route('/api/whitelist/add-all', methods=['POST'])
@auth.login_required
def add_to_all_whitelists():
"""Add player to all server whitelists"""
try:
data = request.get_json()
player = data.get('player')
if not player:
return jsonify({'error': 'Player name required'}), 400
results = []
for server in config['servers']:
if server['enabled']:
try:
command = f'/whitelist add {player}'
send_console_command(server['uuid'], command)
results.append({'uuid': server['uuid'], 'success': True})
logger.info(f"Added {player} to {server['name']}")
except Exception as e:
results.append({'uuid': server['uuid'], 'success': False, 'error': str(e)})
logger.error(f"Failed to add {player} to {server['name']}: {str(e)}")
return jsonify({'player': player, 'results': results})
except Exception as e:
logger.error(f"Error adding player to all servers: {str(e)}")
return jsonify({'error': str(e)}), 500
@app.route('/api/whitelist/remove-all', methods=['POST'])
@auth.login_required
def remove_from_all_whitelists():
"""Remove player from all server whitelists"""
try:
data = request.get_json()
player = data.get('player')
if not player:
return jsonify({'error': 'Player name required'}), 400
results = []
for server in config['servers']:
if server['enabled']:
try:
command = f'/whitelist remove {player}'
send_console_command(server['uuid'], command)
results.append({'uuid': server['uuid'], 'success': True})
logger.info(f"Removed {player} from {server['name']}")
except Exception as e:
results.append({'uuid': server['uuid'], 'success': False, 'error': str(e)})
logger.error(f"Failed to remove {player} from {server['name']}: {str(e)}")
return jsonify({'player': player, 'results': results})
except Exception as e:
logger.error(f"Error removing player from all servers: {str(e)}")
return jsonify({'error': str(e)}), 500
def send_console_command(server_uuid, command):
"""
Send console command to Pterodactyl server
Note: This is a simplified version. Production should use websocket
for real-time command execution and response monitoring.
"""
url = f"{PANEL_URL}/api/client/servers/{server_uuid}/command"
payload = {'command': command}
response = requests.post(url, headers=HEADERS, json=payload, timeout=config['settings']['api_timeout'])
response.raise_for_status()
return response.json()
if __name__ == '__main__':
host = os.getenv('HOST', '127.0.0.1')
port = int(os.getenv('PORT', 5001))
debug = os.getenv('DEBUG', 'False').lower() == 'true'
logger.info(f"Starting Whitelist Manager on {host}:{port}")
app.run(host=host, port=port, debug=debug)
```
### Step 4: Create HTML Dashboard
**File:** `/opt/firefrost/whitelist-manager/templates/dashboard.html`
*(HTML template would go here - full responsive dashboard with TailwindCSS)*
### Step 5: Create JavaScript
**File:** `/opt/firefrost/whitelist-manager/static/js/dashboard.js`
*(JavaScript for API calls and UI updates would go here)*
---
## 📝 PHASE 4: SECURITY & WEB SERVER
**Time Estimate:** 20 minutes
### Step 1: Create systemd Service
**File:** `/etc/systemd/system/whitelist-manager.service`
```ini
[Unit]
Description=Firefrost Gaming Whitelist Manager
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/firefrost/whitelist-manager
Environment="PATH=/opt/firefrost/whitelist-manager/venv/bin"
ExecStart=/opt/firefrost/whitelist-manager/venv/bin/python app.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
**Enable and start:**
```bash
systemctl daemon-reload
systemctl enable whitelist-manager
systemctl start whitelist-manager
systemctl status whitelist-manager
```
### Step 2: Configure Nginx Reverse Proxy
**File:** `/etc/nginx/sites-available/whitelist.firefrostgaming.com`
```nginx
server {
listen 80;
server_name whitelist.firefrostgaming.com;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name whitelist.firefrostgaming.com;
# SSL certificates (will be created by certbot)
ssl_certificate /etc/letsencrypt/live/whitelist.firefrostgaming.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/whitelist.firefrostgaming.com/privkey.pem;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Logging
access_log /var/log/nginx/whitelist.firefrostgaming.com.access.log;
error_log /var/log/nginx/whitelist.firefrostgaming.com.error.log;
# Reverse proxy to Flask app
location / {
proxy_pass http://127.0.0.1:5001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
```
**Enable site:**
```bash
ln -s /etc/nginx/sites-available/whitelist.firefrostgaming.com /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
```
### Step 3: Generate SSL Certificate
```bash
certbot --nginx -d whitelist.firefrostgaming.com
```
---
## 📝 PHASE 5: TESTING
**Time Estimate:** 15 minutes
### Test Plan
**Test 1: Application Health**
```bash
# Check service running
systemctl status whitelist-manager
# Check logs
tail -f /opt/firefrost/whitelist-manager/logs/whitelist-manager.log
# Test local access
curl http://127.0.0.1:5001
```
**Test 2: Web Access**
- Navigate to https://whitelist.firefrostgaming.com
- Verify SSL certificate valid
- Login with credentials
- Dashboard loads correctly
**Test 3: Single Server Operations**
Choose one server (recommend Vanilla 1.21.11 - lowest risk):
- [ ] Toggle whitelist ON
- [ ] Verify in Pterodactyl console
- [ ] Add test player
- [ ] Verify player added
- [ ] Remove test player
- [ ] Verify player removed
- [ ] Toggle whitelist OFF
**Test 4: Bulk Operations**
- [ ] Add player to all servers
- [ ] Verify added to all 11 servers
- [ ] Remove player from all servers
- [ ] Verify removed from all 11 servers
**Test 5: Error Handling**
- [ ] Test with invalid player name
- [ ] Test with server down
- [ ] Test with wrong API key (temporarily)
- [ ] Verify error messages displayed
---
## 📝 PHASE 6: DEPLOY & DOCUMENT
**Time Estimate:** 15 minutes
### Step 1: Roll Out to All Servers
Once testing passes:
- [ ] Verify all 11 servers accessible via dashboard
- [ ] Test whitelist status on each
- [ ] Document any server-specific quirks
### Step 2: Add Link to Wiki.js Staff Portal
1. Log into Wiki.js Staff (staff.firefrostgaming.com)
2. Create new page or edit home page
3. Add section: "Server Management Tools"
4. Add link/button to whitelist manager
5. Include brief usage instructions
**Example Wiki.js Content:**
```markdown
## Server Management Tools
### Whitelist Manager
Manage player whitelists across all Minecraft servers from one interface.
[Open Whitelist Manager →](https://whitelist.firefrostgaming.com)
**Features:**
- Toggle whitelist on/off per server
- Add/remove players from individual servers
- Bulk add/remove across all servers
- View current whitelist status
**Access:** Admin/Staff only (same credentials as Wiki.js)
```
### Step 3: Document in Git Repository
Create comprehensive documentation:
**File 1:** `docs/tools/whitelist-manager-usage.md`
- User guide for staff
- How to add/remove players
- How to toggle whitelists
- Troubleshooting common issues
**File 2:** `docs/deployment/whitelist-manager-deployment.md`
- Technical deployment guide
- Server configuration
- Maintenance procedures
- Recovery procedures
**File 3:** Update `DOCUMENT-INDEX.md`
- Add references to new documentation
### Step 4: Commit Code to Git
```bash
# In whitelist-manager directory
git init
git add .
git commit -m "Initial commit: Whitelist Manager v1.0"
git remote add origin https://git.firefrostgaming.com/firefrost-gaming/whitelist-manager.git
git push -u origin master
```
---
## 🔒 SECURITY CONSIDERATIONS
### Authentication & Authorization
- ✅ Basic HTTP authentication (username/password)
- ✅ HTTPS enforced (no HTTP access)
- ✅ API key stored server-side (never exposed to browser)
- ⏳ Future: OAuth/SSO integration with Wiki.js
- ⏳ Future: Role-based permissions (admin vs staff)
### API Security
- ✅ Pterodactyl API key with minimal required permissions
- ✅ API key in environment variables (not config files)
- ✅ Timeout on API requests (prevent hanging)
- ✅ Error handling (don't expose internal details)
### Network Security
- ✅ Application bound to localhost (127.0.0.1)
- ✅ Only accessible via Nginx reverse proxy
- ✅ SSL/TLS encryption on all traffic
- ✅ Firewall allows only 80/443 (Ghost VPS)
### Logging & Auditing
- ✅ All whitelist changes logged with timestamp
- ✅ User actions logged (who added/removed what)
- ✅ Failed authentication attempts logged
- ✅ Log rotation configured
---
## 📊 MAINTENANCE & OPERATIONS
### Daily Operations
**Staff Usage:**
1. Navigate to https://whitelist.firefrostgaming.com
2. Login with credentials
3. View server dashboard
4. Add/remove players as needed
5. Toggle whitelist enforcement if needed
**No maintenance required for normal operation**
### Weekly Tasks
- [ ] Review logs for errors
- [ ] Verify all servers responding
- [ ] Check disk space for logs
### Monthly Tasks
- [ ] Review and archive old logs
- [ ] Update Python dependencies (security patches)
- [ ] Test backup/restore procedures
### Monitoring
- [ ] Add to Uptime Kuma (monitor whitelist.firefrostgaming.com)
- [ ] Set up alerts for service down
- [ ] Monitor log file size
---
## 🔄 FUTURE ENHANCEMENTS
### Phase 2 Features
1. **Discord Bot Integration**
- `/whitelist add player` in Discord
- Automated whitelist for paid subscribers
- Notifications when players added/removed
2. **Paymenter Integration**
- Auto-whitelist on subscription payment
- Auto-remove on subscription cancellation
- Grace period handling
3. **Advanced Features**
- Whitelist sync verification (ensure all servers match)
- Player activity tracking
- Automated backups of whitelist.json files
- Whitelist import/export
- Bulk CSV upload
4. **UI Improvements**
- Real-time server status indicators
- Player search/filter
- Recent changes history
- Multi-server selection (checkbox select)
5. **Authentication Upgrades**
- SSO integration with Wiki.js
- Role-based permissions (admin/moderator/viewer)
- 2FA support
- API tokens for automation
---
## 🐛 TROUBLESHOOTING
### Common Issues
**Issue: Dashboard won't load**
- Check systemd service: `systemctl status whitelist-manager`
- Check Nginx: `nginx -t && systemctl status nginx`
- Check logs: `tail -f /opt/firefrost/whitelist-manager/logs/whitelist-manager.log`
- Verify DNS: `nslookup whitelist.firefrostgaming.com`
**Issue: Authentication fails**
- Verify credentials in `.env` file
- Check Flask secret key set
- Clear browser cache
- Try incognito mode
**Issue: Commands not executing**
- Verify Pterodactyl API key valid
- Check API key permissions
- Test API manually with curl
- Check server UUID correct in config.json
**Issue: SSL certificate errors**
- Re-run certbot: `certbot renew --force-renewal`
- Check certificate files exist
- Verify Nginx config pointing to correct cert paths
### Recovery Procedures
**Complete Service Restart:**
```bash
systemctl stop whitelist-manager
systemctl stop nginx
systemctl start nginx
systemctl start whitelist-manager
systemctl status whitelist-manager
```
**Reset to Clean State:**
```bash
cd /opt/firefrost/whitelist-manager
git pull origin master
source venv/bin/activate
pip install -r requirements.txt
systemctl restart whitelist-manager
```
**Emergency Fallback:**
If dashboard completely broken, use Pterodactyl console directly:
1. Log into Pterodactyl panel
2. Navigate to server console
3. Execute commands manually:
- `/whitelist add PlayerName`
- `/whitelist remove PlayerName`
- `/whitelist on`
- `/whitelist off`
---
## ✅ COMPLETION CHECKLIST
### Pre-Deployment
- [ ] Pterodactyl API key generated and tested
- [ ] Ghost VPS SSH access verified
- [ ] DNS A record created and propagated
- [ ] Authentication credentials chosen
- [ ] Whitelist enforcement method confirmed
### Deployment
- [ ] Application directory created
- [ ] Python virtual environment set up
- [ ] Dependencies installed
- [ ] Configuration files created
- [ ] Environment variables set
- [ ] Flask app coded and tested locally
- [ ] systemd service created and enabled
- [ ] Nginx configured and tested
- [ ] SSL certificate generated
- [ ] Application accessible via HTTPS
### Testing
- [ ] Service health check passed
- [ ] Web dashboard loads correctly
- [ ] Authentication working
- [ ] Single server whitelist toggle works
- [ ] Add player to single server works
- [ ] Remove player from single server works
- [ ] Bulk add to all servers works
- [ ] Bulk remove from all servers works
- [ ] Error handling tested
### Documentation
- [ ] Usage guide created in Git
- [ ] Deployment guide created in Git
- [ ] Link added to Wiki.js Staff portal
- [ ] Code committed to Git repository
- [ ] DOCUMENT-INDEX.md updated
- [ ] tasks.md updated with completion
### Operations
- [ ] Uptime Kuma monitor added
- [ ] Staff trained on usage
- [ ] Credentials stored in Vaultwarden
- [ ] Maintenance schedule documented
---
## 📚 REFERENCES
### Documentation
- Pterodactyl API: https://dashflo.net/docs/api/pterodactyl/v1/
- Flask Documentation: https://flask.palletsprojects.com/
- Nginx Reverse Proxy: https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
- Let's Encrypt: https://letsencrypt.org/docs/
### Related Firefrost Docs
- `docs/troubleshooting/nc1-cleanup-guidelines.md` - Server cleanup best practices
- `docs/troubleshooting/hytale-troubleshooting-guide.md` - Game server troubleshooting
- `docs/core/tasks.md` - Master task list
- `docs/core/project-scope.md` - Infrastructure overview
---
**Document Status:** Ready for execution
**Next Steps:** Begin Phase 1 - Information Gathering
**Owner:** Michael "Frostystyle" Krause
**Implementation Partner:** The Chronicler
💙🔥❄️
**Fire + Frost + Foundation = Where Love Builds Legacy**