docs: add Pangolin tunnel setup guide for webhook endpoint
User confirmed they use Pangolin (similar to Cloudflare Tunnel), so created a comprehensive Pangolin-specific configuration guide. Complete guide includes: - Pangolin agent installation - Tunnel configuration with path-based access control - DNS setup - Systemd service configuration - Security settings (rate limiting, IP whitelisting) - Testing procedures - Troubleshooting guide - Performance optimization - High availability setup Configuration features: - Only /api/webhooks/autotask exposed - Rate limiting: 100 req/min, burst 20 - Automatic SSL/TLS via Pangolin - All other paths return 404 - No firewall changes needed - No open ports required Benefits over other approaches: - No public IP needed - Zero Trust security model - Automatic DDoS protection - Built-in load balancing - Simple configuration File: docs/WEBHOOK_PANGOLIN_SETUP.md
This commit is contained in:
parent
80d8d40f06
commit
8e83347138
1 changed files with 686 additions and 0 deletions
686
docs/WEBHOOK_PANGOLIN_SETUP.md
Normal file
686
docs/WEBHOOK_PANGOLIN_SETUP.md
Normal file
|
|
@ -0,0 +1,686 @@
|
|||
# Webhook Setup with Pangolin
|
||||
|
||||
## Overview
|
||||
|
||||
Pangolin provides secure tunneling similar to Cloudflare Tunnel, allowing you to expose your webhook endpoint without opening firewall ports or making your entire application public.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Internet → Pangolin Edge → Pangolin Agent → Pulse App (Internal)
|
||||
No open ports! Port 3100
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- ✅ No firewall changes needed
|
||||
- ✅ No public IP required
|
||||
- ✅ Automatic SSL/TLS
|
||||
- ✅ Only webhook endpoint exposed
|
||||
- ✅ Built-in DDoS protection
|
||||
- ✅ Zero Trust security
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Pangolin Account**
|
||||
- Active Pangolin subscription
|
||||
- Access to Pangolin dashboard
|
||||
|
||||
2. **Domain/Subdomain**
|
||||
- Example: `webhooks.yourdomain.com`
|
||||
- DNS managed by Pangolin or pointed to Pangolin
|
||||
|
||||
3. **Pulse Application Running**
|
||||
- Accessible on internal network (e.g., `localhost:3100`)
|
||||
|
||||
---
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### **Step 1: Install Pangolin Agent**
|
||||
|
||||
On the server running Pulse:
|
||||
|
||||
```bash
|
||||
# Download Pangolin agent (adjust URL for your version)
|
||||
curl -O https://download.pangolin.com/agent/latest/pangolin-agent-linux-amd64
|
||||
|
||||
# Make executable
|
||||
chmod +x pangolin-agent-linux-amd64
|
||||
sudo mv pangolin-agent-linux-amd64 /usr/local/bin/pangolin-agent
|
||||
|
||||
# Verify installation
|
||||
pangolin-agent --version
|
||||
```
|
||||
|
||||
### **Step 2: Authenticate Pangolin Agent**
|
||||
|
||||
```bash
|
||||
# Login to Pangolin
|
||||
pangolin-agent login
|
||||
|
||||
# Follow the prompts to authenticate
|
||||
# This will open a browser window or provide a URL
|
||||
```
|
||||
|
||||
### **Step 3: Create Tunnel Configuration**
|
||||
|
||||
Create `/etc/pangolin/config.yml`:
|
||||
|
||||
```yaml
|
||||
# Pangolin Tunnel Configuration for Pulse Webhooks
|
||||
|
||||
# Tunnel name
|
||||
name: pulse-webhooks
|
||||
|
||||
# Ingress rules - define what gets exposed
|
||||
ingress:
|
||||
# Webhook endpoint - the only exposed path
|
||||
- hostname: webhooks.yourdomain.com
|
||||
path: /api/webhooks/autotask
|
||||
service: http://localhost:3100
|
||||
|
||||
# Optional: Webhook logs endpoint (for monitoring)
|
||||
- hostname: webhooks.yourdomain.com
|
||||
path: /api/webhooks/logs
|
||||
service: http://localhost:3100
|
||||
|
||||
# Optional: Webhook stats endpoint (for monitoring)
|
||||
- hostname: webhooks.yourdomain.com
|
||||
path: /api/webhooks/stats
|
||||
service: http://localhost:3100
|
||||
|
||||
# Catch-all - deny everything else
|
||||
- service: http_status:404
|
||||
|
||||
# Security settings
|
||||
security:
|
||||
# Rate limiting
|
||||
rateLimit:
|
||||
enabled: true
|
||||
requestsPerMinute: 100
|
||||
burstSize: 20
|
||||
|
||||
# Optional: IP whitelist for Autotask
|
||||
# Get Autotask IP ranges from their documentation
|
||||
# ipWhitelist:
|
||||
# - "1.2.3.4/24"
|
||||
# - "5.6.7.8/24"
|
||||
|
||||
# Logging
|
||||
logging:
|
||||
level: info
|
||||
file: /var/log/pangolin/tunnel.log
|
||||
```
|
||||
|
||||
### **Step 4: Create Tunnel**
|
||||
|
||||
```bash
|
||||
# Create tunnel with configuration
|
||||
sudo pangolin-agent tunnel create \
|
||||
--config /etc/pangolin/config.yml \
|
||||
--name pulse-webhooks
|
||||
|
||||
# This will output a tunnel ID - save it!
|
||||
# Example: tun_abc123xyz
|
||||
```
|
||||
|
||||
### **Step 5: Configure DNS**
|
||||
|
||||
In Pangolin dashboard or via CLI:
|
||||
|
||||
```bash
|
||||
# Route your subdomain to the tunnel
|
||||
pangolin-agent dns create \
|
||||
--hostname webhooks.yourdomain.com \
|
||||
--tunnel pulse-webhooks
|
||||
```
|
||||
|
||||
Or in Pangolin dashboard:
|
||||
1. Go to DNS settings
|
||||
2. Add CNAME record: `webhooks.yourdomain.com` → `<tunnel-id>.pangolin.io`
|
||||
|
||||
### **Step 6: Start Tunnel**
|
||||
|
||||
**Option A: Run in foreground (for testing)**
|
||||
```bash
|
||||
sudo pangolin-agent tunnel run pulse-webhooks
|
||||
```
|
||||
|
||||
**Option B: Install as systemd service (recommended)**
|
||||
|
||||
Create `/etc/systemd/system/pangolin-tunnel.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Pangolin Tunnel for Pulse Webhooks
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
ExecStart=/usr/local/bin/pangolin-agent tunnel run pulse-webhooks --config /etc/pangolin/config.yml
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Enable and start:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable pangolin-tunnel
|
||||
sudo systemctl start pangolin-tunnel
|
||||
sudo systemctl status pangolin-tunnel
|
||||
```
|
||||
|
||||
### **Step 7: Verify Tunnel**
|
||||
|
||||
```bash
|
||||
# Check tunnel status
|
||||
pangolin-agent tunnel list
|
||||
|
||||
# Test endpoint
|
||||
curl https://webhooks.yourdomain.com/api/webhooks/autotask
|
||||
# Expected: {"status":"active"...}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alternative: Minimal Configuration
|
||||
|
||||
If you prefer a simpler setup without a config file:
|
||||
|
||||
```bash
|
||||
# Create and start tunnel in one command
|
||||
pangolin-agent tunnel \
|
||||
--hostname webhooks.yourdomain.com \
|
||||
--url http://localhost:3100 \
|
||||
--path /api/webhooks/autotask
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Configuration
|
||||
|
||||
### **1. Path-Based Access Control**
|
||||
|
||||
Only expose specific paths in `config.yml`:
|
||||
|
||||
```yaml
|
||||
ingress:
|
||||
# Allow webhook endpoint
|
||||
- hostname: webhooks.yourdomain.com
|
||||
path: /api/webhooks/autotask
|
||||
service: http://localhost:3100
|
||||
|
||||
# Block everything else
|
||||
- service: http_status:404
|
||||
```
|
||||
|
||||
### **2. Rate Limiting**
|
||||
|
||||
Protect against abuse:
|
||||
|
||||
```yaml
|
||||
security:
|
||||
rateLimit:
|
||||
enabled: true
|
||||
requestsPerMinute: 100 # Adjust based on expected traffic
|
||||
burstSize: 20 # Allow bursts of 20 requests
|
||||
```
|
||||
|
||||
### **3. IP Whitelisting (Optional)**
|
||||
|
||||
If you have Autotask's IP ranges:
|
||||
|
||||
```yaml
|
||||
security:
|
||||
ipWhitelist:
|
||||
- "1.2.3.4/24" # Autotask IP range 1
|
||||
- "5.6.7.8/24" # Autotask IP range 2
|
||||
```
|
||||
|
||||
### **4. Request Headers**
|
||||
|
||||
Add security headers:
|
||||
|
||||
```yaml
|
||||
ingress:
|
||||
- hostname: webhooks.yourdomain.com
|
||||
path: /api/webhooks/autotask
|
||||
service: http://localhost:3100
|
||||
headers:
|
||||
X-Frame-Options: DENY
|
||||
X-Content-Type-Options: nosniff
|
||||
X-XSS-Protection: "1; mode=block"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring
|
||||
|
||||
### **View Tunnel Logs**
|
||||
|
||||
```bash
|
||||
# Systemd journal
|
||||
sudo journalctl -u pangolin-tunnel -f
|
||||
|
||||
# Or log file (if configured)
|
||||
tail -f /var/log/pangolin/tunnel.log
|
||||
```
|
||||
|
||||
### **Tunnel Statistics**
|
||||
|
||||
```bash
|
||||
# Get tunnel stats
|
||||
pangolin-agent tunnel stats pulse-webhooks
|
||||
|
||||
# List active connections
|
||||
pangolin-agent tunnel connections pulse-webhooks
|
||||
```
|
||||
|
||||
### **Webhook Logs**
|
||||
|
||||
Monitor webhook processing:
|
||||
|
||||
```bash
|
||||
# Via API (if exposed)
|
||||
curl https://webhooks.yourdomain.com/api/webhooks/logs?limit=10
|
||||
|
||||
# Via database
|
||||
docker exec pulse-postgres psql -U pulse_user -d pulse_autotask -c \
|
||||
"SELECT event_id, entity_type, status, processing_time_ms
|
||||
FROM webhook_logs
|
||||
ORDER BY received_at DESC
|
||||
LIMIT 10;"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### **1. Health Check**
|
||||
|
||||
```bash
|
||||
curl https://webhooks.yourdomain.com/api/webhooks/autotask
|
||||
```
|
||||
|
||||
Expected response:
|
||||
```json
|
||||
{
|
||||
"status": "active",
|
||||
"endpoint": "/api/webhooks/autotask",
|
||||
"message": "Autotask webhook receiver is ready"
|
||||
}
|
||||
```
|
||||
|
||||
### **2. Test Webhook POST**
|
||||
|
||||
```bash
|
||||
curl -X POST https://webhooks.yourdomain.com/api/webhooks/autotask \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"eventId": "test_pangolin_123",
|
||||
"eventType": "create",
|
||||
"entityType": "Tickets",
|
||||
"entityId": 99999,
|
||||
"eventTimestamp": "2026-01-24T10:00:00Z",
|
||||
"entity": {
|
||||
"id": 99999,
|
||||
"title": "Test Ticket via Pangolin"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Expected response:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"eventId": "test_pangolin_123",
|
||||
"action": "created",
|
||||
"processingTime": 45
|
||||
}
|
||||
```
|
||||
|
||||
### **3. Verify Path Blocking**
|
||||
|
||||
```bash
|
||||
# These should return 404
|
||||
curl https://webhooks.yourdomain.com/
|
||||
curl https://webhooks.yourdomain.com/admin
|
||||
curl https://webhooks.yourdomain.com/api/sync
|
||||
```
|
||||
|
||||
### **4. Test Rate Limiting**
|
||||
|
||||
```bash
|
||||
# Send 150 requests quickly
|
||||
for i in {1..150}; do
|
||||
curl -s https://webhooks.yourdomain.com/api/webhooks/autotask > /dev/null
|
||||
echo "Request $i"
|
||||
done
|
||||
|
||||
# Should see rate limit errors after ~100 requests
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configure Autotask
|
||||
|
||||
Once your Pangolin tunnel is working:
|
||||
|
||||
1. **Log in to Autotask** as administrator
|
||||
2. **Navigate to:** Admin → Features & Settings → API & Integrations → Webhooks
|
||||
3. **Create New Webhook:**
|
||||
- **Name:** `Pulse - Tickets` (or entity name)
|
||||
- **Endpoint URL:** `https://webhooks.yourdomain.com/api/webhooks/autotask`
|
||||
- **Entity Type:** Select entity (e.g., Tickets)
|
||||
- **Events:** ✅ Create, ✅ Update
|
||||
- **Include Entity Data:** ✅ **Enable this!**
|
||||
- **Active:** ✅ Enabled
|
||||
4. **Test Webhook** from Autotask UI
|
||||
5. **Verify** in Pulse webhook logs
|
||||
|
||||
Repeat for each entity: Companies, Tasks, Projects, Time Entries, Contacts
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### **Tunnel Not Starting**
|
||||
|
||||
**Check 1: Agent Status**
|
||||
```bash
|
||||
pangolin-agent status
|
||||
```
|
||||
|
||||
**Check 2: Configuration**
|
||||
```bash
|
||||
# Validate config file
|
||||
pangolin-agent tunnel validate --config /etc/pangolin/config.yml
|
||||
```
|
||||
|
||||
**Check 3: Logs**
|
||||
```bash
|
||||
sudo journalctl -u pangolin-tunnel -n 50
|
||||
```
|
||||
|
||||
### **Webhooks Not Received**
|
||||
|
||||
**Check 1: Tunnel is Running**
|
||||
```bash
|
||||
pangolin-agent tunnel list
|
||||
# Should show pulse-webhooks as "active"
|
||||
```
|
||||
|
||||
**Check 2: DNS Resolution**
|
||||
```bash
|
||||
nslookup webhooks.yourdomain.com
|
||||
# Should resolve to Pangolin edge
|
||||
```
|
||||
|
||||
**Check 3: Pulse App is Accessible**
|
||||
```bash
|
||||
# Test from same server
|
||||
curl http://localhost:3100/api/webhooks/autotask
|
||||
# Should return health check response
|
||||
```
|
||||
|
||||
**Check 4: Webhook Logs**
|
||||
```bash
|
||||
# Check if webhooks are being received but failing
|
||||
docker exec pulse-postgres psql -U pulse_user -d pulse_autotask -c \
|
||||
"SELECT * FROM webhook_logs WHERE status = 'failed' ORDER BY received_at DESC LIMIT 5;"
|
||||
```
|
||||
|
||||
### **502 Bad Gateway**
|
||||
|
||||
Pulse app is not reachable from Pangolin agent:
|
||||
|
||||
```bash
|
||||
# Verify Pulse app is running
|
||||
docker ps | grep pulse-app
|
||||
|
||||
# Check port
|
||||
netstat -tlnp | grep 3100
|
||||
|
||||
# Test direct connection
|
||||
curl http://localhost:3100/api/webhooks/autotask
|
||||
```
|
||||
|
||||
**Fix:** Ensure `service: http://localhost:3100` in config matches your Pulse app's actual address and port.
|
||||
|
||||
### **Rate Limiting Issues**
|
||||
|
||||
If legitimate webhooks are being rate limited:
|
||||
|
||||
```yaml
|
||||
# Increase limits in config.yml
|
||||
security:
|
||||
rateLimit:
|
||||
enabled: true
|
||||
requestsPerMinute: 200 # Increased from 100
|
||||
burstSize: 50 # Increased from 20
|
||||
```
|
||||
|
||||
Then restart tunnel:
|
||||
```bash
|
||||
sudo systemctl restart pangolin-tunnel
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### **Multiple Paths**
|
||||
|
||||
Expose additional endpoints if needed:
|
||||
|
||||
```yaml
|
||||
ingress:
|
||||
# Webhook receiver
|
||||
- hostname: webhooks.yourdomain.com
|
||||
path: /api/webhooks/autotask
|
||||
service: http://localhost:3100
|
||||
|
||||
# Monitoring endpoints (optional)
|
||||
- hostname: webhooks.yourdomain.com
|
||||
path: /api/webhooks/logs
|
||||
service: http://localhost:3100
|
||||
# Optional: Add authentication
|
||||
auth:
|
||||
type: basic
|
||||
username: admin
|
||||
password: ${WEBHOOK_ADMIN_PASSWORD}
|
||||
|
||||
- hostname: webhooks.yourdomain.com
|
||||
path: /api/webhooks/stats
|
||||
service: http://localhost:3100
|
||||
auth:
|
||||
type: basic
|
||||
username: admin
|
||||
password: ${WEBHOOK_ADMIN_PASSWORD}
|
||||
```
|
||||
|
||||
### **Custom Domain**
|
||||
|
||||
If using your own domain (not Pangolin subdomain):
|
||||
|
||||
1. Add CNAME in your DNS provider:
|
||||
```
|
||||
webhooks.yourdomain.com → <tunnel-id>.pangolin.io
|
||||
```
|
||||
|
||||
2. Update Pangolin configuration:
|
||||
```bash
|
||||
pangolin-agent dns create \
|
||||
--hostname webhooks.yourdomain.com \
|
||||
--tunnel pulse-webhooks \
|
||||
--custom-domain
|
||||
```
|
||||
|
||||
### **High Availability**
|
||||
|
||||
Run multiple Pangolin agents for redundancy:
|
||||
|
||||
**Server 1:**
|
||||
```bash
|
||||
pangolin-agent tunnel run pulse-webhooks --config /etc/pangolin/config.yml
|
||||
```
|
||||
|
||||
**Server 2:**
|
||||
```bash
|
||||
pangolin-agent tunnel run pulse-webhooks --config /etc/pangolin/config.yml
|
||||
```
|
||||
|
||||
Pangolin will automatically load balance between agents.
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### **Connection Pooling**
|
||||
|
||||
```yaml
|
||||
# In config.yml
|
||||
performance:
|
||||
connectionPool:
|
||||
maxConnections: 100
|
||||
keepAliveTimeout: 60s
|
||||
```
|
||||
|
||||
### **Compression**
|
||||
|
||||
```yaml
|
||||
# Enable compression for responses
|
||||
compression:
|
||||
enabled: true
|
||||
minSize: 1024 # Only compress responses > 1KB
|
||||
```
|
||||
|
||||
### **Caching**
|
||||
|
||||
```yaml
|
||||
# Cache health check responses
|
||||
cache:
|
||||
enabled: true
|
||||
rules:
|
||||
- path: /api/webhooks/autotask
|
||||
method: GET
|
||||
ttl: 60s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Maintenance
|
||||
|
||||
### **Update Pangolin Agent**
|
||||
|
||||
```bash
|
||||
# Download latest version
|
||||
curl -O https://download.pangolin.com/agent/latest/pangolin-agent-linux-amd64
|
||||
|
||||
# Stop service
|
||||
sudo systemctl stop pangolin-tunnel
|
||||
|
||||
# Replace binary
|
||||
sudo mv pangolin-agent-linux-amd64 /usr/local/bin/pangolin-agent
|
||||
sudo chmod +x /usr/local/bin/pangolin-agent
|
||||
|
||||
# Start service
|
||||
sudo systemctl start pangolin-tunnel
|
||||
|
||||
# Verify
|
||||
pangolin-agent --version
|
||||
```
|
||||
|
||||
### **Rotate Credentials**
|
||||
|
||||
```bash
|
||||
# Re-authenticate
|
||||
pangolin-agent logout
|
||||
pangolin-agent login
|
||||
|
||||
# Restart tunnel
|
||||
sudo systemctl restart pangolin-tunnel
|
||||
```
|
||||
|
||||
### **Backup Configuration**
|
||||
|
||||
```bash
|
||||
# Backup config
|
||||
sudo cp /etc/pangolin/config.yml /etc/pangolin/config.yml.backup
|
||||
|
||||
# Backup tunnel info
|
||||
pangolin-agent tunnel info pulse-webhooks > ~/pangolin-tunnel-info.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cost Optimization
|
||||
|
||||
Pangolin typically charges based on:
|
||||
- Number of tunnels
|
||||
- Bandwidth usage
|
||||
- Number of requests
|
||||
|
||||
**Tips to minimize costs:**
|
||||
|
||||
1. **Use rate limiting** to prevent abuse
|
||||
2. **Enable compression** to reduce bandwidth
|
||||
3. **Cache static responses** (health checks)
|
||||
4. **Monitor usage** regularly
|
||||
5. **Use single tunnel** for all webhook endpoints
|
||||
|
||||
---
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. ✅ **Only expose webhook endpoint** - block all other paths
|
||||
2. ✅ **Enable rate limiting** - prevent DDoS
|
||||
3. ✅ **Use HTTPS only** - Pangolin provides this automatically
|
||||
4. ✅ **Monitor logs** - watch for suspicious activity
|
||||
5. ✅ **IP whitelist** - if Autotask provides IP ranges
|
||||
6. ✅ **Keep agent updated** - apply security patches
|
||||
7. ✅ **Rotate credentials** - periodically re-authenticate
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Pangolin Setup for Pulse Webhooks:**
|
||||
|
||||
1. ✅ Install Pangolin agent
|
||||
2. ✅ Create tunnel configuration (expose only `/api/webhooks/autotask`)
|
||||
3. ✅ Start tunnel as systemd service
|
||||
4. ✅ Configure DNS to point to tunnel
|
||||
5. ✅ Test endpoint
|
||||
6. ✅ Configure webhooks in Autotask
|
||||
7. ✅ Monitor logs and statistics
|
||||
|
||||
**Result:**
|
||||
- Webhook endpoint accessible at `https://webhooks.yourdomain.com/api/webhooks/autotask`
|
||||
- No firewall changes needed
|
||||
- No open ports
|
||||
- Automatic SSL/TLS
|
||||
- Rest of application remains private
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For Pangolin-specific issues:
|
||||
- Pangolin Documentation: Check your Pangolin dashboard
|
||||
- Pangolin Support: Contact via your support channel
|
||||
|
||||
For Pulse webhook issues:
|
||||
- Check webhook logs: `/api/webhooks/logs`
|
||||
- Review database: `webhook_logs` table
|
||||
- See main documentation: `WEBHOOK_SETUP.md`
|
||||
Loading…
Add table
Add a link
Reference in a new issue