Properly support proper VPNs

It turns out that not using masquerade will not work with real VPNs (as opposed to dummy ones, including adblockers and sockifiers).

Fixes #10.
This commit is contained in:
Mygod
2018-03-08 00:41:50 -08:00
parent 4d58183168
commit c7e1abb585
3 changed files with 22 additions and 6 deletions

View File

@@ -296,7 +296,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnMonitor.Ca
val strict = app.pref.getBoolean("service.repeater.strict", false)
return if (strict && upstream == null || // in this case, nothing to be done
routing.ipForward() // Wi-Fi direct doesn't enable ip_forward
.rule().forward(strict).dnsRedirect(dns).start()) true else {
.rule().forward(strict).masquerade(strict).dnsRedirect(dns).start()) true else {
routing.stop()
Toast.makeText(this, getText(R.string.noisy_su_failure), Toast.LENGTH_SHORT).show()
false

View File

@@ -52,7 +52,7 @@ class TetheringService : Service(), VpnMonitor.Callback, IpNeighbourMonitor.Call
for ((downstream, value) in routings) if (value == null) try {
// system tethering already has working forwarding rules
// so it doesn't make sense to add additional forwarding rules
val routing = Routing(upstream, downstream).rule().forward().dnsRedirect(dns)
val routing = Routing(upstream, downstream).rule().forward().masquerade().dnsRedirect(dns)
if (routing.start()) routings[downstream] = routing else {
failed = true
routing.stop()

View File

@@ -26,9 +26,11 @@ class Routing(val upstream: String?, val downstream: String, ownerAddress: InetA
fun clean() = noisySu(
"$IPTABLES -t nat -F PREROUTING",
"quiet while $IPTABLES -D FORWARD -j vpnhotspot_fwd; do done",
"quiet while $IPTABLES -t nat -D POSTROUTING -j MASQUERADE; do done",
"$IPTABLES -F vpnhotspot_fwd",
"$IPTABLES -X vpnhotspot_fwd",
"quiet while $IPTABLES -t nat -D POSTROUTING -j vpnhotspot_masquerade; do done",
"$IPTABLES -t nat -F vpnhotspot_masquerade",
"$IPTABLES -t nat -X vpnhotspot_masquerade",
"quiet while ip rule del priority 17900; do done")
fun dump(): InputStream? {
@@ -95,19 +97,33 @@ class Routing(val upstream: String?, val downstream: String, ownerAddress: InetA
stopScript.addFirst("$IPTABLES -D vpnhotspot_fwd -i $downstream -o $upstream -j ACCEPT")
} else {
// for not strict mode, allow downstream packets to be redirected to anywhere
// also enable unconditional NAT masquerade
// because we don't wanna keep track of default network changes
startScript.add("$IPTABLES -A vpnhotspot_fwd -o $downstream -m state --state ESTABLISHED,RELATED -j ACCEPT")
startScript.add("$IPTABLES -A vpnhotspot_fwd -i $downstream -j ACCEPT")
startScript.add("$IPTABLES -t nat -A POSTROUTING -j MASQUERADE")
stopScript.addFirst("$IPTABLES -D vpnhotspot_fwd -o $downstream -m state --state ESTABLISHED,RELATED -j ACCEPT")
stopScript.addFirst("$IPTABLES -D vpnhotspot_fwd -i $downstream -j ACCEPT")
stopScript.addFirst("$IPTABLES -t nat -D POSTROUTING -j MASQUERADE")
}
startScript.add("$IPTABLES -I FORWARD -j vpnhotspot_fwd")
stopScript.addFirst("$IPTABLES -D FORWARD -j vpnhotspot_fwd")
return this
}
fun masquerade(strict: Boolean = true): Routing {
startScript.add("quiet $IPTABLES -t nat -N vpnhotspot_masquerade 2>/dev/null")
// note: specifying -i wouldn't work for POSTROUTING
if (strict) {
check(upstream != null)
startScript.add("$IPTABLES -t nat -A vpnhotspot_masquerade -o $upstream -j MASQUERADE")
stopScript.addFirst("$IPTABLES -t nat -D vpnhotspot_masquerade -o $upstream -j MASQUERADE")
} else {
startScript.add("$IPTABLES -t nat -A vpnhotspot_masquerade -j MASQUERADE")
stopScript.addFirst("$IPTABLES -t nat -D vpnhotspot_masquerade -j MASQUERADE")
}
startScript.add("$IPTABLES -t nat -I POSTROUTING -j vpnhotspot_masquerade")
stopScript.addFirst("$IPTABLES -t nat -D POSTROUTING -j vpnhotspot_masquerade")
return this
}
fun dnsRedirect(dnses: List<InetAddress>): Routing {
val hostAddress = hostAddress.hostAddress
val dns = dnses.firstOrNull { it is Inet4Address }?.hostAddress