6.9 KiB
6.9 KiB
VPN Implementation Fix - Summary
Problem
Users connecting to ProtonVPN were experiencing:
- IP Leaks: Real IP address visible instead of VPN IP
- DNS Leaks: DNS queries going to ISP instead of VPN DNS servers
- 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 leaksredirect-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 IPgetIPInfo()- Get location, ISP, etc.getDNSServers()- Check current DNScheckVPNInterface()- Verify tun0 existsgetRoutingTable()- Check traffic routingcheckDNSLeaks()- Detect DNS leaksrunFullDiagnostics()- 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
-
Dockerfile
- Fixed DNS update script to properly parse OpenVPN variables
- Added better logging
-
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
-
backend/utils/vpnDiagnostics.js (NEW)
- Comprehensive VPN diagnostic tools
- IP/DNS leak detection
- Interface and routing verification
-
frontend/src/components/VPNSettings.jsx
- Added "Check IP" button
- Display connection details panel
- Show IP, location, DNS, interface status
- Warning alerts for issues
-
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
- Go to Settings > VPN
- Enter ProtonVPN credentials
- Click "Connect"
- 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
- Kill Switch: Traffic blocked if VPN drops
- DNS Security: Forced to VPN DNS only
- No IPv6 Leaks: IPv6 filtered out
- Proper Routing: All traffic through tunnel
- 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:
- Check logs:
docker logs streamflow - Run diagnostics: Use
/api/vpn/diagnosticsendpoint - Verify credentials: Ensure ProtonVPN login is correct
- Try different server: Switch countries
- Check Docker: Ensure
NET_ADMINandNET_RAWcapabilities - Rebuild:
docker-compose build --no-cache
Next Steps (Optional Enhancements)
- Auto-reconnect: Reconnect VPN if connection drops
- Multiple servers: Load balance across servers
- Connection testing: Periodic leak checks
- WireGuard support: Alternative to OpenVPN
- Split tunneling: Route only specific traffic through VPN
- 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