- Environment-based configuration (no hardcoded secrets) - OAuth authentication via Authentik - ElevenLabs TTS integration via SAG CLI - FCM push notification support - User preferences sync system - Multi-user support with per-user context files - No internal IPs or service accounts in tracked files
357 lines
8.0 KiB
Markdown
357 lines
8.0 KiB
Markdown
# Alfred Mobile Proxy Deployment Guide
|
|
|
|
## Overview
|
|
|
|
Your setup:
|
|
- **Client ID:** `QeSNaZPqZUz5pPClZMA2bakSsddkStiEhqbE4QZR`
|
|
- **Authentik URL:** `https://auth.dnspegasus.net`
|
|
- **Gateway token:** `9b87d15fee3922ecfbe77b0ea1744851757cda618beceeba`
|
|
- **Mobile URL:** `wss://alfred-app.dnspegasus.net`
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Android App
|
|
↓ OAuth: auth.dnspegasus.net
|
|
↓ WebSocket: wss://alfred-app.dnspegasus.net
|
|
HAProxy (192.168.1.20)
|
|
↓ Proxy backend → 192.168.1.169:18790
|
|
Alfred Proxy (localhost:18790)
|
|
↓ Validates OAuth token
|
|
↓ Injects gateway token
|
|
OpenClaw (localhost:18789)
|
|
```
|
|
|
|
---
|
|
|
|
## Step 1: Configure Proxy
|
|
|
|
```bash
|
|
cd ~/.openclaw/workspace/alfred-proxy
|
|
|
|
# Create .env file
|
|
cat > .env << 'EOF'
|
|
PROXY_PORT=18790
|
|
OPENCLAW_URL=ws://127.0.0.1:18789
|
|
OPENCLAW_TOKEN=9b87d15fee3922ecfbe77b0ea1744851757cda618beceeba
|
|
AUTHENTIK_URL=https://auth.dnspegasus.net
|
|
AUTHENTIK_CLIENT_ID=QeSNaZPqZUz5pPClZMA2bakSsddkStiEhqbE4QZR
|
|
REQUIRE_AUTH=true
|
|
EOF
|
|
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Test locally first
|
|
npm run dev
|
|
```
|
|
|
|
In another terminal:
|
|
```bash
|
|
# Test health
|
|
curl http://localhost:18790/health
|
|
|
|
# Should return: {"status":"ok","service":"alfred-proxy"}
|
|
```
|
|
|
|
---
|
|
|
|
## Step 2: Switch OpenClaw to Localhost
|
|
|
|
```bash
|
|
# Check current setting
|
|
openclaw config get gateway.bind
|
|
|
|
# Switch to localhost only
|
|
cat >> ~/.openclaw/openclaw.json << 'EOF'
|
|
{
|
|
"gateway": {
|
|
"bind": "loopback"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Restart OpenClaw
|
|
systemctl --user restart openclaw-gateway.service
|
|
|
|
# Verify
|
|
openclaw config get gateway.bind
|
|
# Should show: "loopback"
|
|
|
|
# Test local connection
|
|
wscat -c ws://127.0.0.1:18789
|
|
# Should see connect challenge
|
|
```
|
|
|
|
---
|
|
|
|
## Step 3: Install Proxy as Service
|
|
|
|
```bash
|
|
cd ~/.openclaw/workspace/alfred-proxy
|
|
|
|
# Install systemd service
|
|
mkdir -p ~/.config/systemd/user
|
|
cp alfred-proxy.service ~/.config/systemd/user/
|
|
|
|
# Create override with your client ID
|
|
mkdir -p ~/.config/systemd/user/alfred-proxy.service.d
|
|
cat > ~/.config/systemd/user/alfred-proxy.service.d/override.conf << 'EOF'
|
|
[Service]
|
|
Environment="AUTHENTIK_CLIENT_ID=QeSNaZPqZUz5pPClZMA2bakSsddkStiEhqbE4QZR"
|
|
EOF
|
|
|
|
# Reload and start
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable alfred-proxy.service
|
|
systemctl --user start alfred-proxy.service
|
|
|
|
# Check status
|
|
systemctl --user status alfred-proxy.service
|
|
|
|
# View logs
|
|
journalctl --user -u alfred-proxy.service -f
|
|
```
|
|
|
|
---
|
|
|
|
## Step 4: Verify DNS (Already Done!)
|
|
|
|
You already have a wildcard DNS record pointing to HAProxy, so `alfred-app.dnspegasus.net` should already resolve!
|
|
|
|
**Test DNS:**
|
|
```bash
|
|
nslookup alfred-app.dnspegasus.net
|
|
# Should resolve to your HAProxy IP (via wildcard *.dnspegasus.net)
|
|
```
|
|
|
|
If it doesn't work, you may need to explicitly add:
|
|
```
|
|
Type: A
|
|
Host: alfred-app
|
|
Value: <your HAProxy IP>
|
|
TTL: 300
|
|
```
|
|
|
|
---
|
|
|
|
## Step 5: Configure HAProxy
|
|
|
|
**SSH to HAProxy:**
|
|
```bash
|
|
ssh root@192.168.1.20
|
|
```
|
|
|
|
**Edit HAProxy config:**
|
|
```bash
|
|
docker exec -it haproxy-manager bash
|
|
nano /etc/haproxy/haproxy.cfg
|
|
```
|
|
|
|
**Add this configuration** (based on `haproxy-alfred-app.cfg`):
|
|
|
|
```haproxy
|
|
# In your frontend section (around line ~50):
|
|
|
|
frontend https_frontend
|
|
# ... existing config ...
|
|
|
|
# NEW: alfred-app subdomain ACL
|
|
acl alfred_app_acl hdr(host) -i alfred-app.dnspegasus.net
|
|
acl is_websocket hdr(Upgrade) -i WebSocket
|
|
acl is_websocket_connection hdr_beg(Connection) -i Upgrade
|
|
|
|
# Route alfred-app subdomain
|
|
use_backend alfred_mobile_proxy-backend if alfred_app_acl is_websocket is_websocket_connection
|
|
use_backend alfred_mobile_redirect-backend if alfred_app_acl
|
|
|
|
# At the end of the file, add new backends:
|
|
|
|
backend alfred_mobile_proxy-backend
|
|
mode http
|
|
option forwardfor
|
|
|
|
http-request add-header X-CLIENT-IP %[var(txn.real_ip)]
|
|
http-request set-header X-Real-IP %[var(txn.real_ip)]
|
|
http-request set-header X-Forwarded-For %[var(txn.real_ip)]
|
|
http-request set-header X-Forwarded-Proto https if { ssl_fc }
|
|
|
|
timeout tunnel 1h
|
|
timeout client 1h
|
|
timeout server 1h
|
|
|
|
# IMPORTANT: Your desktop IP where proxy runs
|
|
# IP: 192.168.1.169 Port: 18790
|
|
server alfred_proxy 192.168.1.169:18790 check
|
|
|
|
backend alfred_mobile_redirect-backend
|
|
mode http
|
|
http-request return status 200 content-type "text/html" string '<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="refresh" content="0;url=https://alfred.dnspegasus.net"><title>Alfred Mobile</title><style>body{font-family:system-ui;text-align:center;padding:50px;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}h1{font-size:2.5rem;margin-bottom:1rem}p{font-size:1.1rem;opacity:0.9}</style></head><body><h1>🤵 Alfred Mobile</h1><p>This endpoint is for the mobile app.</p><p>Redirecting to web interface...</p></body></html>'
|
|
```
|
|
|
|
**Test HAProxy config:**
|
|
```bash
|
|
haproxy -c -f /etc/haproxy/haproxy.cfg
|
|
# Should show: Configuration file is valid
|
|
```
|
|
|
|
**Reload HAProxy:**
|
|
```bash
|
|
# If using Docker container:
|
|
docker exec haproxy-manager kill -HUP 1
|
|
|
|
# Or restart:
|
|
docker restart haproxy-manager
|
|
```
|
|
|
|
---
|
|
|
|
## Step 6: Open Firewall (if needed)
|
|
|
|
On your desktop (where proxy runs):
|
|
|
|
```powershell
|
|
# PowerShell (Admin)
|
|
New-NetFirewallRule -DisplayName "Alfred Proxy" -Direction Inbound -LocalPort 18790 -Protocol TCP -Action Allow
|
|
```
|
|
|
|
Or use your existing scripts:
|
|
```powershell
|
|
.\open-openclaw-port.ps1
|
|
# Then modify for port 18790
|
|
```
|
|
|
|
---
|
|
|
|
## Step 7: Test End-to-End
|
|
|
|
**From outside your network:**
|
|
|
|
```bash
|
|
# Test DNS
|
|
nslookup alfred-app.dnspegasus.net
|
|
|
|
# Test HTTPS redirect (browser should redirect)
|
|
curl -I https://alfred-app.dnspegasus.net
|
|
|
|
# Test WebSocket (requires valid OAuth token)
|
|
# Get token from Authentik first, then:
|
|
wscat -c "wss://alfred-app.dnspegasus.net" -H "Authorization: Bearer YOUR_TOKEN"
|
|
```
|
|
|
|
**Expected flow:**
|
|
1. Browser → `https://alfred-app.dnspegasus.net` → Redirects to `https://alfred.dnspegasus.net` ✅
|
|
2. Mobile app → `wss://alfred-app.dnspegasus.net` → Connects to proxy ✅
|
|
|
|
---
|
|
|
|
## Step 8: Android App Configuration
|
|
|
|
Update your Android app:
|
|
|
|
```kotlin
|
|
// OAuthConfig.kt
|
|
object OAuthConfig {
|
|
const val AUTHENTIK_URL = "https://auth.dnspegasus.net"
|
|
const val CLIENT_ID = "QeSNaZPqZUz5pPClZMA2bakSsddkStiEhqbE4QZR"
|
|
const val REDIRECT_URI = "alfredmobile://oauth/callback"
|
|
const val SCOPE = "openid profile email"
|
|
|
|
const val AUTHORIZATION_ENDPOINT = "$AUTHENTIK_URL/application/o/authorize/"
|
|
const val TOKEN_ENDPOINT = "$AUTHENTIK_URL/application/o/token/"
|
|
}
|
|
|
|
// AlfredConfig.kt
|
|
object AlfredConfig {
|
|
const val GATEWAY_URL = "wss://alfred-app.dnspegasus.net"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Proxy won't start
|
|
```bash
|
|
# Check logs
|
|
journalctl --user -u alfred-proxy.service -n 50
|
|
|
|
# Test manually
|
|
cd ~/.openclaw/workspace/alfred-proxy
|
|
npm run dev
|
|
```
|
|
|
|
### Can't connect from mobile
|
|
```bash
|
|
# Check proxy is listening
|
|
ss -tuln | grep 18790
|
|
|
|
# Check firewall
|
|
sudo iptables -L -n | grep 18790
|
|
|
|
# Check HAProxy backend
|
|
curl http://192.168.1.169:18790/health
|
|
```
|
|
|
|
### "Invalid token" errors
|
|
```bash
|
|
# Verify Authentik config
|
|
curl https://auth.dnspegasus.net/.well-known/openid-configuration
|
|
|
|
# Test token validation
|
|
curl -H "Authorization: Bearer TOKEN" \
|
|
https://auth.dnspegasus.net/application/o/userinfo/
|
|
```
|
|
|
|
### DNS not resolving
|
|
```bash
|
|
# Check DNS record exists (should work via wildcard)
|
|
nslookup alfred-app.dnspegasus.net
|
|
|
|
# Try public DNS
|
|
nslookup alfred-app.dnspegasus.net 8.8.8.8
|
|
```
|
|
|
|
---
|
|
|
|
## Security Checklist
|
|
|
|
- [x] OpenClaw bound to localhost only
|
|
- [x] Proxy validates OAuth tokens
|
|
- [x] Gateway token not exposed
|
|
- [ ] HTTPS/WSS for external access
|
|
- [ ] Firewall rules configured
|
|
- [ ] Monitoring set up
|
|
- [ ] Test token revocation
|
|
|
|
---
|
|
|
|
## Monitoring
|
|
|
|
**Watch proxy logs:**
|
|
```bash
|
|
journalctl --user -u alfred-proxy.service -f
|
|
```
|
|
|
|
**Watch OpenClaw logs:**
|
|
```bash
|
|
journalctl --user -u openclaw-gateway.service -f
|
|
```
|
|
|
|
**Watch HAProxy logs:**
|
|
```bash
|
|
ssh root@192.168.1.20
|
|
docker logs -f haproxy-manager
|
|
```
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. **Test locally** (proxy + OpenClaw)
|
|
2. **Configure HAProxy** (add mobile subdomain)
|
|
3. **Add DNS record**
|
|
4. **Test from outside** (mobile network)
|
|
5. **Implement OAuth in Android app**
|
|
6. **Test full flow**
|