Detect the active VPN interface from a macOS application in Swift

I need a way of detecting the active VPN interface in macOS. Using

ifconfig -v
you can easily spot the application responsible for a virtual interface (e.g.
ipsec0
). Is it possible to get this information from the app level, preferably in Swift.

Using the following code I'm able to get any running

ipsecX
interfaces, but can't get any related information to them (only the name of the interface):


import CFNetwork

guard let cfProxySettings = CFNetworkCopySystemProxySettings()?.takeRetainedValue(),
      let proxySettings = cfProxySettings as? [String: AnyObject],
      let connectedInterfaces = proxySettings["__SCOPED__"] as? [String: AnyObject] else { return }

connectedInterfaces.keys.forEach { interface in
    if interface.hasPrefix("ipsec") {
        print(interface)
    }
}


Any help would be much appreciated. Thanks in advance 🙂

Using

ifconfig -v
you can easily spot the application responsible for a virtual interface (e.g.
ipsec0
).

Can you post an example of this? I’m on VPN right now, and I’m not seeing any app information reported by

ifconfig -v
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yup, here's the output for ipsec0. It identifies the application responsible (in this case ProtonVPN):``



ipsec0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1400 index 12

eflags=1002080<TXSTART,NOAUTOIPV6LL,ECN_ENABLE>

inet 10.6.6.39 --> 10.6.6.39 netmask 0xff000000

agent domain:NetworkExtension type:VPN flags:0xf desc:"VPN: ProtonVPN"

state availability: 0 (true)

scheduler: FQ_CODEL

effective interface: en0

qosmarking enabled: no mode: none

low power mode: disabled

Oh wow, my

ifconfig
output has that but I completely missed it. Thanks for setting me straight.

I had a look at the

ifconfig
source code in Darwin and it gets this info via a private ioctl. I don’t think there’s any equivalent public API.

What do you need this info for?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I'm creating a VPN kill switch for a VPN application. I'm using pfctl to establish firewall rules to prevent all external IPs aside from a specified VPN IP and any traffic over the associated ipsec interface. I want to determine the exact interface used for the VPN tunnel and apply that to my pf configuration file, incase there are multiple ipsec interfaces.


Ultimately I'd like to avoid using pfctl as well and instead use an API to create a firewall (even if it's using low level C interfaces) and not require privilege escalation to do so.

Interesting. Alas, I can’t help you with that. There’s a whole bunch of things that you can do with low-level services on macOS that just aren’t supported as APIs by Apple. PF is one example of this. PF is not suitable for use in third-party products because there’s no way to arbitrate the PF rules between the various folks who might be using PF (the system and N third-party products).

The only supported way to build a firewall right now is with an NKE, and that has its own problems. Recent macOS releases have tightly restricted KEXT development in general, and on the NKE front in particular we’ve given notice that we intend to deprecate that technology because it’s incompatible with our user-space networking stack.

IMPORTANT While we’ve announced a general plan here (see WWDC 2017 Session 707 Advances in Networking, Part 1), we’ve not announced a specific timeline.

Ultimately we would like to migrate folks using NKEs to NetworkExtension providers. Feedback since this announcement has made it very clear that the current NE provider architecture is missing important functionality, and this migration can’t happen until that’s resolved.

Such a resolution is in The Future™, and thus I can’t talk about the specifics. The one thing I can say is that, if you’re building a product that integrates with the lower levels of macOS’s networking stack, you should file an enhancement request for a way to achieve your goals using the NE provider architecture. Make sure to include a detailed description of your requirements, so that we can integrate those into our plans.

Please post your bug number, just for the record.

Right now all I can say is that change is coming, and that you should attempt to build isolation layers within your product so that you can more easily adapt to that change.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

That's great to hear that the networking team is looking to add these kinds of critical changes, especially if they can be used across iOS as well as macOS.


Our requirements are pretty straight forward. We need a mechanism of preventing a user’s IP from leaking when connected to VPN (commonly referred to as a VPN Kill Switch). This could be added to the Connect On Demand feature such that all traffic (except to the VPN server so that it can establish the connection) is prevented when the VPN tunnel isn’t currently established.


Here is my enhancement request number: 47881110


Thanks for all your help!

all traffic (except to the VPN server so that it can establish the connection) is prevented when the VPN tunnel isn’t currently established.

This sound like much like Always-on VPN. Alas, Always-on VPN is currently restricted to the built-in IKEv2 VPN transport; there’s no support for third-party VPN transports (r. 21363342).

Here is my enhancement request number: 47881110

Thanks for that.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I haven't been able to find solid confirmation that Always-on VPN protects against IP leaks when not connected to the VPN server, but if it does do that, then making it available to third-parties would solve my problem. For comparisons sake, Always-on VPN in Android actually does the same as Connect On Demand in iOS/macOS (in that it doens't prevent IP leaks when not connected to VPN), so they have added an additional setting called "Block connections without VPN" that addresses this issue.


Fingers crossed. Thanks

Detect the active VPN interface from a macOS application in Swift
 
 
Q