ID:
HOST_ROUTECategory: Routes and network stack Status in RKNHardering 2.10.0: Active check Role in the verdict: Medium
This page describes the actual implementation in RKNHardering 2.10.0. It distinguishes what can be done without root, what requires root, and where a mitigation only reduces one signal without hiding the VPN as a whole.
isVpnServerHostRouteCandidate() considers only netlink rows that are not default routes, have a /32 or /128 prefix, use the unicast type and global or link scope, are not in local table 255, and do not use the kernel protocol. The destination must be publicly routable and the interface must be a standard physical interface. Such a route resembles pinning a VPN server address outside the tunnel, but it can also be created by carrier and system services.
A matching public host route sets needsReview=true with medium confidence. detected remains false.
This is a candidate, not proof. On typical Android, a VpnService server socket is usually excluded from the VPN through protect() or fwmark without a separate host route, so the signal is more relevant to root/kernel VPNs or nonstandard clients.
How the line affects the report: The line does not produce a final verdict on its own, but it sets needsReview=true and adds medium-confidence evidence.
A CDN, captive portal, carrier IMS, OEM security service, or static network configuration may legitimately create a /32 route. Without process or socket correlation, the address cannot be identified as a VPN endpoint.
This line must be evaluated together with neighboring signals. A clean result from a single API does not simultaneously cover Java Binder, libc, raw netlink/syscalls, procfs/sysfs, local sockets, and server-side indicators.
First identify the route’s owner by when it appears: compare snapshots before the VPN starts, after it starts, and after it is disabled. If your client creates the route, prefer its standard VpnService.protect() or split-route mechanism; do not delete the route manually. An external gateway removes the local host route from the phone.
A kernel backend can hide this route shape, but shape-based filtering risks removing a legitimate /32. Upstream VPNHide documents host-route logic primarily for desktop-style or rooted VPNs. Verify that target traffic truly uses the physical network and that the server socket does not route back into the tunnel.
adb shell ip -4 route show table all | grep -E '(^| )/32| scope link'
adb shell ip -6 route show table all | grep '/128'
Capture three states: VPN off, VPN on, and client stopped. Do not publish the address in an issue without redacting it.
After any change, force-stop both RKNHardering and the VPN client, start them again, and repeat the full scan. Zygisk, Xposed, and kernel modules usually require a reboot. Compare not only this line but also neighboring signals: a partial hook often creates inconsistencies between APIs.
The probe itself runs with ordinary app permissions and does not request root. The ADB commands below are for orientation only: adb shell runs under a different UID and may see either more or less than the app process. The decisive test is to run the check again after a force-stop.
Deleting the host route may send the VPN connection into its own tunnel and break it. Filtering too broad a class of routes can disrupt carrier services.
Restart the VPN client or the network so that it recreates the route. Disable any root hook through its manager and reboot.
Medium. Verified against the strict allowlist conditions in isVpnServerHostRouteCandidate() and the host-route unit tests. The signal is intentionally review-only.
The status of a third-party solution does not automatically carry over to this device. A module developer’s claim is only the initial hypothesis; confirmation requires a reproducible RKNHardering result on the specific Android version, firmware, and kernel.
NativeSignsChecker.kt — main native/legacy verdict logic.native_signs_probe.cpp — native probe implementation.NativeSignalId.kt — complete ID registry.NativeSignalCatalog.kt — category, slug, and line mapping.Related signals: route-table, vpn-policy-rules-netlink, established-vpn-socket.