Skip to main content

Network Protection

Kill Switch

The Kill Switch controls what happens to network traffic when the VPN connection drops unexpectedly. Configure it on the KapeVPNManager before connecting:

vpn.killSwitchMode = .off // or .standard / .advanced

Modes

ModeBehaviourWhen to use
.offIf the VPN tunnel drops, traffic continues over the regular internet connection uninterrupted.Suitable when uninterrupted connectivity matters more than privacy, e.g. during development.
.standardThe SDK continuously attempts to reconnect. All internet traffic is blocked until the tunnel is restored. System services such as CarPlay, AirDrop, and local network communication remain functional.Recommended default for consumer VPN apps.
.advancedAll traffic without exception must be routed through the tunnel. Any traffic that cannot be tunnelled — including system services and local network communication — is blocked until the tunnel is restored.High-security scenarios where any unprotected traffic is unacceptable.
warning

.advanced mode forces all traffic — including system services like AirDrop, push notifications, and CarPlay — through the VPN tunnel. However, these services rely on local network communication, which is inherently unreachable via a VPN tunnel. As a result, they will stop functioning whenever the tunnel is active or recovering. This mode causes significant restrictions for everyday device usage and should be used only when the security requirement explicitly demands it.

Connect on Demand

Connect on Demand lets iOS start the VPN tunnel automatically as soon as the device generates internet traffic — without any user interaction. Enable it on the KapeVPNManager before connecting:

vpn.connectOnDemand = true

When enabled, iOS monitors outgoing connections and triggers the VPN tunnel the moment traffic is detected. The VPN stays active as long as Connect on Demand is enabled; disabling it returns to manual connect/disconnect control.

info

Connect on Demand is implemented via iOS NEOnDemandRule. The VPN profile must be installed (installProfile()) before this setting takes effect.

warning

Combining Connect on Demand with Kill Switch .standard or .advanced means that after an unexpected tunnel drop, traffic is blocked and iOS will immediately try to re-establish the tunnel automatically. This is the recommended combination for maximum privacy.

Connect on Demand Rules

For finer control, you can define an ordered list of rules that determine when the VPN connects automatically. Rules are evaluated in order — the first matching rule wins.

vpn.onDemandRules = [
// Disconnect on a trusted home network
KapeOnDemandRule(condition: .ssid("Home WiFi"), action: .disconnect),
// Connect on any other WiFi
KapeOnDemandRule(condition: .wifi, action: .connect),
// Connect on cellular
KapeOnDemandRule(condition: .cellular, action: .connect),
]

Each KapeOnDemandRule has a condition and an action:

Conditions

ConditionMatches
.ssid("Name")A specific WiFi network by SSID
.wifiAny WiFi network
.cellularAny cellular (mobile data) connection

Actions

ActionBehaviour
.connectStart the VPN tunnel automatically when this condition is met
.disconnectPrevent automatic connection (or disconnect if currently active)

When onDemandRules is empty and connectOnDemand is true, iOS uses a single catch-all connect rule — equivalent to setting connectOnDemand = true without any rules.

Rules are persisted automatically and restored on the next app launch. They take effect immediately whenever connectOnDemand is true.

info

Rule order matters. Put more specific .ssid rules before broad .wifi or .cellular rules, otherwise the specific rules will never be reached.

Split Tunneling

Split Tunneling lets you control which traffic is routed through the VPN and which bypasses it. Define rules as a list of IP ranges in CIDR notation, either as a whitelist (only matching traffic goes through the VPN) or a blacklist (matching traffic bypasses the VPN).

// Whitelist — only these ranges are routed through the VPN
vpn.splitTunnel = .whitelist([
"10.0.0.0/8",
"192.168.1.0/24"
])

// Blacklist — these ranges bypass the VPN
vpn.splitTunnel = .blacklist([
"203.0.113.0/24",
"198.51.100.0/24"
])

Domain-based rules

Instead of hardcoding IP ranges, you can provide a domain name. The SDK resolves its IP addresses automatically before the tunnel is established and applies the resolved ranges to the rule:

vpn.splitTunnel = .whitelist([
.cidr("10.0.0.0/8"),
.domain("internal.example.com")
])
warning

IP addresses are resolved at connection time only. If a domain's DNS records change while the tunnel is active, the split tunnel rules are not updated until the next connection.