streamflow/docs/VPN_FIX_SUMMARY.md
2025-12-17 00:42:43 +00:00

6.9 KiB

VPN Implementation Fix - Summary

Problem

Users connecting to ProtonVPN were experiencing:

  1. IP Leaks: Real IP address visible instead of VPN IP
  2. DNS Leaks: DNS queries going to ISP instead of VPN DNS servers
  3. No Traffic Routing: VPN connected but traffic not going through tunnel

Root Causes

1. DNS Script Issues

The DNS update script was incorrectly parsing OpenVPN's DNS environment variables:

# BEFORE (broken)
echo "nameserver ${foreign_option_1#*DNS }" > /etc/resolv.conf

# AFTER (fixed)
for opt in ${!foreign_option_*}; do
  if echo ${!opt} | grep -q "DNS"; then
    DNS_IP=$(echo ${!opt} | awk '{print $3}')
    echo "nameserver $DNS_IP" >> /etc/resolv.conf
  fi
done

2. Missing Kill Switch

No firewall rules to prevent traffic from leaking outside the VPN tunnel when connected.

3. Incomplete VPN Configuration

Missing critical OpenVPN directives:

  • block-outside-dns - Prevents DNS leaks
  • redirect-gateway def1 bypass-dhcp - Ensures all traffic routes through VPN
  • No VPN connection verification

4. No Diagnostic Tools

No way to verify VPN was actually working or diagnose leak issues.

Solutions Implemented

1. Fixed DNS Update Script (Dockerfile)

  • Properly parse foreign_option_* environment variables
  • Iterate through all DNS options from OpenVPN
  • Fallback to ProtonVPN DNS (10.2.0.1) if needed
  • Added logging for debugging

2. Added Kill Switch (backend/routes/vpn.js)

// Firewall rules to block non-VPN traffic
iptables -A OUTPUT -o lo -j ACCEPT              // Allow loopback
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT // Allow DNS
iptables -A OUTPUT -o tun+ -j ACCEPT            // Allow VPN
// Implicit: Everything else blocked

3. Enhanced OpenVPN Configuration (backend/routes/vpn.js)

Added/improved:

dhcp-option DNS 10.2.0.1
dhcp-option DNS 10.2.0.2
block-outside-dns                     // NEW: Prevent DNS leaks
redirect-gateway def1 bypass-dhcp     // IMPROVED: Better routing
pull-filter ignore "dhcp-option DOMAIN"
pull-filter ignore "block-outside-dns"
pull-filter ignore route-ipv6         // NEW: Disable IPv6 leaks

4. VPN Verification (backend/routes/vpn.js)

After connection, verify:

  • Get public IP and compare
  • Check DNS configuration
  • Log connection details

5. Diagnostic Tools

New File: backend/utils/vpnDiagnostics.js

Comprehensive VPN diagnostics class:

  • getPublicIP() - Get current public IP
  • getIPInfo() - Get location, ISP, etc.
  • getDNSServers() - Check current DNS
  • checkVPNInterface() - Verify tun0 exists
  • getRoutingTable() - Check traffic routing
  • checkDNSLeaks() - Detect DNS leaks
  • runFullDiagnostics() - Complete analysis

New API Endpoint: /api/vpn/diagnostics

Returns comprehensive diagnostics:

{
  "publicIP": "X.X.X.X",
  "ipInfo": { "country": "US", "org": "ProtonVPN" },
  "dnsServers": ["10.2.0.1", "10.2.0.2"],
  "vpnInterface": { "exists": true },
  "routingTable": ["default via ... dev tun0"],
  "dnsLeakCheck": { "potentialLeak": false },
  "summary": {
    "vpnActive": true,
    "ipLeak": false,
    "dnsLeak": false,
    "issues": []
  }
}

6. Enhanced Frontend (frontend/src/components/VPNSettings.jsx)

Added "Check IP" button that displays:

  • Current public IP
  • Location (city, country)
  • ISP/Organization
  • DNS servers in use
  • VPN interface status
  • Warning if interface not active

7. Documentation

Created comprehensive troubleshooting guide: docs/VPN_TROUBLESHOOTING.md

Files Modified

  1. Dockerfile

    • Fixed DNS update script to properly parse OpenVPN variables
    • Added better logging
  2. backend/routes/vpn.js

    • Added kill switch (firewall rules)
    • Enhanced OpenVPN configuration
    • Added VPN verification after connect
    • Cleanup firewall on disconnect
    • Improved status and check-ip endpoints
    • Added diagnostics endpoint
    • Import VPNDiagnostics utility
  3. backend/utils/vpnDiagnostics.js (NEW)

    • Comprehensive VPN diagnostic tools
    • IP/DNS leak detection
    • Interface and routing verification
  4. frontend/src/components/VPNSettings.jsx

    • Added "Check IP" button
    • Display connection details panel
    • Show IP, location, DNS, interface status
    • Warning alerts for issues
  5. docs/VPN_TROUBLESHOOTING.md (NEW)

    • Complete troubleshooting guide
    • Common issues and solutions
    • Testing procedures
    • Architecture explanation

How to Use

1. Rebuild Container

docker-compose down
docker-compose build
docker-compose up -d

2. Connect to VPN

  1. Go to Settings > VPN
  2. Enter ProtonVPN credentials
  3. Click "Connect"
  4. Wait for "VPN Connected" message

3. Verify Connection

Click "Check IP" button and verify:

  • ✓ Public IP is different from your real IP
  • ✓ Location matches VPN country
  • ✓ ISP shows ProtonVPN or VPN-related
  • ✓ DNS servers are 10.2.0.1, 10.2.0.2
  • ✓ VPN Interface shows "Active"

4. Run Diagnostics (Optional)

curl -H "Authorization: Bearer YOUR_TOKEN" \
  http://localhost:12345/api/vpn/diagnostics

Testing Checklist

  • Container rebuilds successfully
  • VPN connects without errors
  • Check IP shows VPN IP (not real IP)
  • Location matches selected country
  • DNS servers are ProtonVPN DNS
  • VPN interface (tun0) is active
  • Can browse internet while connected
  • Streams work through VPN
  • Disconnect works properly
  • Firewall rules cleaned up on disconnect

Security Improvements

  1. Kill Switch: Traffic blocked if VPN drops
  2. DNS Security: Forced to VPN DNS only
  3. No IPv6 Leaks: IPv6 filtered out
  4. Proper Routing: All traffic through tunnel
  5. Verification: Connection verified after connect

Performance Considerations

  • Free tier VPN has speed limits
  • Kill switch adds minimal overhead
  • DNS lookup uses VPN DNS (may be slower)
  • Firewall rules are lightweight

Troubleshooting

If still experiencing issues:

  1. Check logs: docker logs streamflow
  2. Run diagnostics: Use /api/vpn/diagnostics endpoint
  3. Verify credentials: Ensure ProtonVPN login is correct
  4. Try different server: Switch countries
  5. Check Docker: Ensure NET_ADMIN and NET_RAW capabilities
  6. Rebuild: docker-compose build --no-cache

Next Steps (Optional Enhancements)

  1. Auto-reconnect: Reconnect VPN if connection drops
  2. Multiple servers: Load balance across servers
  3. Connection testing: Periodic leak checks
  4. WireGuard support: Alternative to OpenVPN
  5. Split tunneling: Route only specific traffic through VPN
  6. IPv6 support: Proper IPv6 over VPN

Notes

  • VPN connection is per-user (not container-wide)
  • Each user can connect to different VPN servers
  • Free tier has bandwidth/speed limitations
  • Some services may detect/block VPN traffic
  • Credentials stored encrypted in database