175 lines
4.1 KiB
Markdown
175 lines
4.1 KiB
Markdown
|
|
# Alfred Proxy Quick Start
|
||
|
|
|
||
|
|
## Your Configuration
|
||
|
|
|
||
|
|
### Backend Details for HAProxy
|
||
|
|
|
||
|
|
**Add to HAProxy backend:**
|
||
|
|
```
|
||
|
|
Server IP: 192.168.1.169
|
||
|
|
Server Port: 18790
|
||
|
|
```
|
||
|
|
|
||
|
|
**Full HAProxy backend config:**
|
||
|
|
```haproxy
|
||
|
|
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
|
||
|
|
|
||
|
|
server alfred_proxy 192.168.1.169:18790 check
|
||
|
|
```
|
||
|
|
|
||
|
|
### URLs
|
||
|
|
|
||
|
|
- **Mobile app connects to:** `wss://alfred-app.dnspegasus.net`
|
||
|
|
- **OAuth authentication:** `https://auth.dnspegasus.net`
|
||
|
|
- **Web browser redirect:** `https://alfred.dnspegasus.net`
|
||
|
|
|
||
|
|
### DNS
|
||
|
|
|
||
|
|
Your wildcard DNS (`*.dnspegasus.net`) should already resolve `alfred-app.dnspegasus.net` to HAProxy.
|
||
|
|
|
||
|
|
Test: `nslookup alfred-app.dnspegasus.net`
|
||
|
|
|
||
|
|
### Android App Configuration
|
||
|
|
|
||
|
|
```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/"
|
||
|
|
const val USERINFO_ENDPOINT = "$AUTHENTIK_URL/application/o/userinfo/"
|
||
|
|
}
|
||
|
|
|
||
|
|
// AlfredConfig.kt
|
||
|
|
object AlfredConfig {
|
||
|
|
const val GATEWAY_URL = "wss://alfred-app.dnspegasus.net"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Start the Proxy
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd ~/.openclaw/workspace/alfred-proxy
|
||
|
|
|
||
|
|
# 1. Create .env
|
||
|
|
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
|
||
|
|
|
||
|
|
# 2. Install and start
|
||
|
|
npm install
|
||
|
|
npm run dev
|
||
|
|
|
||
|
|
# 3. Test health
|
||
|
|
curl http://localhost:18790/health
|
||
|
|
```
|
||
|
|
|
||
|
|
### HAProxy Configuration
|
||
|
|
|
||
|
|
See `haproxy-alfred-app.cfg` for complete config.
|
||
|
|
|
||
|
|
**Key points:**
|
||
|
|
- Frontend ACL: `alfred-app.dnspegasus.net`
|
||
|
|
- WebSocket connections → `alfred_mobile_proxy-backend`
|
||
|
|
- Browser visits → Redirect to main web UI
|
||
|
|
- Backend server: `192.168.1.169:18790`
|
||
|
|
|
||
|
|
### Network Diagram
|
||
|
|
|
||
|
|
```
|
||
|
|
Android App
|
||
|
|
↓
|
||
|
|
wss://alfred-app.dnspegasus.net (OAuth token in Authorization header)
|
||
|
|
↓
|
||
|
|
HAProxy (192.168.1.20:443)
|
||
|
|
↓
|
||
|
|
Alfred Proxy (192.168.1.169:18790)
|
||
|
|
- Validates OAuth token with Authentik
|
||
|
|
- Injects OpenClaw gateway token
|
||
|
|
↓
|
||
|
|
OpenClaw (127.0.0.1:18789)
|
||
|
|
↓
|
||
|
|
Alfred AI assistant
|
||
|
|
```
|
||
|
|
|
||
|
|
### Testing Flow
|
||
|
|
|
||
|
|
1. **Test proxy locally:**
|
||
|
|
```bash
|
||
|
|
curl http://localhost:18790/health
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **Test from HAProxy server:**
|
||
|
|
```bash
|
||
|
|
curl http://192.168.1.169:18790/health
|
||
|
|
```
|
||
|
|
|
||
|
|
3. **Test DNS:**
|
||
|
|
```bash
|
||
|
|
nslookup alfred-app.dnspegasus.net
|
||
|
|
```
|
||
|
|
|
||
|
|
4. **Test redirect (browser):**
|
||
|
|
```bash
|
||
|
|
curl -I https://alfred-app.dnspegasus.net
|
||
|
|
# Should redirect to alfred.dnspegasus.net
|
||
|
|
```
|
||
|
|
|
||
|
|
5. **Test WebSocket (with OAuth token):**
|
||
|
|
```bash
|
||
|
|
# Get token from Authentik first, then:
|
||
|
|
wscat -c "wss://alfred-app.dnspegasus.net" \
|
||
|
|
-H "Authorization: Bearer YOUR_TOKEN"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Troubleshooting
|
||
|
|
|
||
|
|
**Can't reach proxy from HAProxy:**
|
||
|
|
```bash
|
||
|
|
# Test direct connection
|
||
|
|
curl http://192.168.1.169:18790/health
|
||
|
|
|
||
|
|
# Check Windows firewall
|
||
|
|
# PowerShell (Admin):
|
||
|
|
New-NetFirewallRule -DisplayName "Alfred Proxy" `
|
||
|
|
-Direction Inbound -LocalPort 18790 -Protocol TCP -Action Allow
|
||
|
|
```
|
||
|
|
|
||
|
|
**WebSocket upgrade fails:**
|
||
|
|
- Check HAProxy ACL matches `alfred-app.dnspegasus.net`
|
||
|
|
- Verify WebSocket headers are present
|
||
|
|
- Check proxy logs: `journalctl --user -u alfred-proxy.service -f`
|
||
|
|
|
||
|
|
**Invalid token:**
|
||
|
|
- Verify Client ID in proxy `.env` matches Authentik
|
||
|
|
- Test token: `curl -H "Authorization: Bearer TOKEN" https://auth.dnspegasus.net/application/o/userinfo/`
|
||
|
|
|
||
|
|
### Next Steps
|
||
|
|
|
||
|
|
1. ✅ Start proxy locally
|
||
|
|
2. ✅ Configure HAProxy with correct backend
|
||
|
|
3. ✅ Test DNS resolves
|
||
|
|
4. ✅ Test redirect in browser
|
||
|
|
5. ✅ Implement OAuth in Android app
|
||
|
|
6. ✅ Test end-to-end flow
|