fix: 透明代理状态检测 - 读取实际iptables规则而非仅数据库
This commit is contained in:
@@ -472,12 +472,10 @@ const TransparentProxy = {
|
||||
const list = settings.transparentProxy.interfaces || [];
|
||||
if (list.includes(iface)) return { ok: true, message: 'Already enabled' };
|
||||
|
||||
// Add iptables rules for this interface
|
||||
// Add iptables rules for this interface (PRIVATE_RANGES already includes 192.168.10.1)
|
||||
const rules = [
|
||||
`iptables -t nat -C PREROUTING -i ${iface} -d 192.168.10.1 -j RETURN 2>/dev/null || iptables -t nat -I PREROUTING 1 -i ${iface} -d 192.168.10.1 -j RETURN`,
|
||||
...this.PRIVATE_RANGES.map(r => {
|
||||
const checkR = r.replace('-A', '-C');
|
||||
return `iptables -t nat -C PREROUTING -i ${iface} ${checkR} 2>/dev/null || iptables -t nat -I PREROUTING 1 -i ${iface} ${r}`;
|
||||
return `iptables -t nat -C PREROUTING -i ${iface} ${r} 2>/dev/null || iptables -t nat -I PREROUTING 1 -i ${iface} ${r}`;
|
||||
}),
|
||||
`iptables -t nat -C PREROUTING -i ${iface} -p tcp -j REDIRECT --to-ports ${this.REDIR_PORT} 2>/dev/null || iptables -t nat -A PREROUTING -i ${iface} -p tcp -j REDIRECT --to-ports ${this.REDIR_PORT}`,
|
||||
`iptables -t nat -C PREROUTING -i ${iface} -p udp --dport 53 -j REDIRECT --to-ports ${this.DNS_PORT} 2>/dev/null || iptables -t nat -A PREROUTING -i ${iface} -p udp --dport 53 -j REDIRECT --to-ports ${this.DNS_PORT}`,
|
||||
@@ -543,13 +541,54 @@ const TransparentProxy = {
|
||||
},
|
||||
|
||||
async getStatus() {
|
||||
const interfaces = await this.getActiveInterfaces();
|
||||
const rules = [];
|
||||
// Check actual iptables rules to determine which interfaces have transparent proxy
|
||||
const activeFromIptables = new Set();
|
||||
try {
|
||||
const output = await this._exec('iptables -t nat -L PREROUTING -n -v --line-numbers 2>/dev/null || echo ""');
|
||||
rules.push(output);
|
||||
const output = await this._exec('iptables -t nat -L PREROUTING -n 2>/dev/null || echo ""');
|
||||
const lines = output.split('\n');
|
||||
for (const line of lines) {
|
||||
// Match lines like: REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp redir ports 7893
|
||||
// preceded by interface match
|
||||
const ifaceMatch = line.match(/iif\s+(\S+)/);
|
||||
if (!ifaceMatch) {
|
||||
// iptables -L format: look for interface in the "in" column
|
||||
// Format: target prot opt in out source destination
|
||||
const parts = line.trim().split(/\s+/);
|
||||
if (parts.length >= 6 && parts[0] === 'REDIRECT' && parts[4] !== '*' && parts[4] !== 'lo') {
|
||||
activeFromIptables.add(parts[4]);
|
||||
}
|
||||
// Also check RETURN rules for private ranges
|
||||
if (parts.length >= 6 && parts[0] === 'RETURN' && parts[4] !== '*' && parts[4] !== 'lo') {
|
||||
activeFromIptables.add(parts[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Also check nft format
|
||||
const nftOutput = await this._exec('nft list chain ip nat PREROUTING 2>/dev/null || echo ""');
|
||||
for (const line of nftOutput.split('\n')) {
|
||||
const m = line.match(/iifname\s+"([^"]+)".*redirect/);
|
||||
if (m && m[1] !== 'lo') activeFromIptables.add(m[1]);
|
||||
const m2 = line.match(/iifname\s+"([^"]+)".*return/);
|
||||
if (m2 && m2[1] !== 'lo') activeFromIptables.add(m2[1]);
|
||||
}
|
||||
} catch {}
|
||||
return { interfaces, rules: rules.join('\n') };
|
||||
|
||||
// Sync database with actual iptables state
|
||||
const settings = DB.settings;
|
||||
const dbInterfaces = settings.transparentProxy.interfaces || [];
|
||||
|
||||
// If iptables shows rules but DB doesn't, sync DB
|
||||
if (activeFromIptables.size > 0) {
|
||||
for (const iface of activeFromIptables) {
|
||||
if (!dbInterfaces.includes(iface)) {
|
||||
dbInterfaces.push(iface);
|
||||
}
|
||||
}
|
||||
settings.transparentProxy.interfaces = dbInterfaces;
|
||||
DB.save();
|
||||
}
|
||||
|
||||
return { interfaces: [...new Set([...dbInterfaces, ...activeFromIptables])] };
|
||||
},
|
||||
|
||||
async restoreFromSettings() {
|
||||
|
||||
Reference in New Issue
Block a user