Initial commit: StreamFlow IPTV platform
This commit is contained in:
commit
73a8ae9ffd
1240 changed files with 278451 additions and 0 deletions
245
backend/utils/vpnDiagnostics.js
Normal file
245
backend/utils/vpnDiagnostics.js
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
const axios = require('axios');
|
||||
const { exec } = require('child_process');
|
||||
const { promisify } = require('util');
|
||||
const fs = require('fs').promises;
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
/**
|
||||
* VPN Diagnostics - Check for IP and DNS leaks
|
||||
*/
|
||||
class VPNDiagnostics {
|
||||
/**
|
||||
* Get current public IP address
|
||||
*/
|
||||
static async getPublicIP() {
|
||||
try {
|
||||
const response = await axios.get('https://api.ipify.org?format=json', {
|
||||
timeout: 10000,
|
||||
validateStatus: () => true
|
||||
});
|
||||
return response.data.ip;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get public IP: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get detailed IP information (location, ISP, etc.)
|
||||
*/
|
||||
static async getIPInfo(ip) {
|
||||
try {
|
||||
const response = await axios.get(`https://ipinfo.io/${ip || ''}/json`, {
|
||||
timeout: 10000,
|
||||
validateStatus: () => true
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.warn('Could not get IP info:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current DNS servers from resolv.conf
|
||||
*/
|
||||
static async getDNSServers() {
|
||||
try {
|
||||
const resolvConf = await fs.readFile('/etc/resolv.conf', 'utf8');
|
||||
const nameservers = resolvConf
|
||||
.split('\n')
|
||||
.filter(line => line.trim().startsWith('nameserver'))
|
||||
.map(line => line.split(/\s+/)[1]);
|
||||
|
||||
return nameservers;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to read DNS servers: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if VPN interface (tun) exists
|
||||
*/
|
||||
static async checkVPNInterface() {
|
||||
try {
|
||||
const { stdout } = await execAsync('ip addr show tun0 2>/dev/null');
|
||||
return {
|
||||
exists: true,
|
||||
details: stdout.trim()
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
exists: false,
|
||||
details: null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get routing table
|
||||
*/
|
||||
static async getRoutingTable() {
|
||||
try {
|
||||
const { stdout } = await execAsync('ip route');
|
||||
return stdout.trim().split('\n');
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get routing table: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test DNS resolution through current DNS servers
|
||||
*/
|
||||
static async testDNSResolution(domain = 'google.com') {
|
||||
try {
|
||||
const { stdout } = await execAsync(`nslookup ${domain} | grep -A1 "Name:" | tail -1`);
|
||||
return {
|
||||
success: true,
|
||||
result: stdout.trim()
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for DNS leaks by testing against multiple DNS leak test services
|
||||
*/
|
||||
static async checkDNSLeaks() {
|
||||
const dnsServers = await this.getDNSServers();
|
||||
|
||||
// Check if DNS servers are common VPN DNS servers
|
||||
const commonVPNDNS = ['10.2.0.1', '10.2.0.2', '10.8.0.1', '10.0.0.1'];
|
||||
const isUsingVPNDNS = dnsServers.some(dns => commonVPNDNS.includes(dns) || dns.startsWith('10.'));
|
||||
|
||||
// Check if DNS servers match common public DNS (potential leak)
|
||||
const commonPublicDNS = [
|
||||
'8.8.8.8', '8.8.4.4', // Google
|
||||
'1.1.1.1', '1.0.0.1', // Cloudflare
|
||||
'9.9.9.9', // Quad9
|
||||
];
|
||||
const isUsingPublicDNS = dnsServers.some(dns => commonPublicDNS.includes(dns));
|
||||
|
||||
return {
|
||||
dnsServers,
|
||||
isUsingVPNDNS,
|
||||
isUsingPublicDNS,
|
||||
potentialLeak: !isUsingVPNDNS && isUsingPublicDNS
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Run comprehensive VPN diagnostics
|
||||
*/
|
||||
static async runFullDiagnostics() {
|
||||
console.log('🔍 Running VPN diagnostics...');
|
||||
|
||||
const results = {
|
||||
timestamp: new Date().toISOString(),
|
||||
publicIP: null,
|
||||
ipInfo: null,
|
||||
dnsServers: [],
|
||||
vpnInterface: null,
|
||||
routingTable: [],
|
||||
dnsLeakCheck: null,
|
||||
summary: {
|
||||
vpnActive: false,
|
||||
ipLeak: false,
|
||||
dnsLeak: false,
|
||||
issues: []
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
// Get public IP
|
||||
results.publicIP = await this.getPublicIP();
|
||||
console.log(`✓ Public IP: ${results.publicIP}`);
|
||||
|
||||
// Get IP info
|
||||
results.ipInfo = await this.getIPInfo(results.publicIP);
|
||||
if (results.ipInfo) {
|
||||
console.log(`✓ Location: ${results.ipInfo.city}, ${results.ipInfo.country}`);
|
||||
console.log(`✓ ISP: ${results.ipInfo.org}`);
|
||||
}
|
||||
|
||||
// Get DNS servers
|
||||
results.dnsServers = await this.getDNSServers();
|
||||
console.log(`✓ DNS Servers: ${results.dnsServers.join(', ')}`);
|
||||
|
||||
// Check VPN interface
|
||||
results.vpnInterface = await this.checkVPNInterface();
|
||||
if (results.vpnInterface.exists) {
|
||||
console.log('✓ VPN interface (tun0) is UP');
|
||||
results.summary.vpnActive = true;
|
||||
} else {
|
||||
console.log('✗ VPN interface (tun0) NOT found');
|
||||
results.summary.issues.push('VPN interface not found');
|
||||
}
|
||||
|
||||
// Get routing table
|
||||
results.routingTable = await this.getRoutingTable();
|
||||
const defaultRoute = results.routingTable.find(route => route.startsWith('default'));
|
||||
if (defaultRoute) {
|
||||
console.log(`✓ Default route: ${defaultRoute}`);
|
||||
if (defaultRoute.includes('tun')) {
|
||||
console.log('✓ Traffic is routed through VPN');
|
||||
} else {
|
||||
console.log('✗ Traffic NOT routed through VPN');
|
||||
results.summary.ipLeak = true;
|
||||
results.summary.issues.push('Traffic not routed through VPN interface');
|
||||
}
|
||||
}
|
||||
|
||||
// DNS leak check
|
||||
results.dnsLeakCheck = await this.checkDNSLeaks();
|
||||
if (results.dnsLeakCheck.isUsingVPNDNS) {
|
||||
console.log('✓ Using VPN DNS servers');
|
||||
} else if (results.dnsLeakCheck.potentialLeak) {
|
||||
console.log('✗ Potential DNS leak detected');
|
||||
results.summary.dnsLeak = true;
|
||||
results.summary.issues.push('Using non-VPN DNS servers');
|
||||
}
|
||||
|
||||
// Overall status
|
||||
if (results.summary.vpnActive && !results.summary.ipLeak && !results.summary.dnsLeak) {
|
||||
console.log('\n✓ VPN is working correctly - No leaks detected');
|
||||
} else {
|
||||
console.log('\n✗ VPN issues detected:');
|
||||
results.summary.issues.forEach(issue => console.log(` - ${issue}`));
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error during diagnostics:', error);
|
||||
results.summary.issues.push(error.message);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick check if VPN is working (used by status endpoint)
|
||||
*/
|
||||
static async quickCheck() {
|
||||
try {
|
||||
const [publicIP, dnsServers, vpnInterface] = await Promise.all([
|
||||
this.getPublicIP(),
|
||||
this.getDNSServers(),
|
||||
this.checkVPNInterface()
|
||||
]);
|
||||
|
||||
return {
|
||||
publicIP,
|
||||
dnsServers,
|
||||
vpnInterfaceActive: vpnInterface.exists,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(`Quick check failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = VPNDiagnostics;
|
||||
Loading…
Add table
Add a link
Reference in a new issue