Michael Horowitz
Home => VPNs on iOS are a scam
NOTE: I will be giving a presentation on Defensive Computing at the HOPE conference in New York City in July 2022. The talk is based on my DefensiveComputingChecklist.com website. The conference runs from July 22nd thru the 24th, I am scheduled for the 23rd at 1PM ET. Attending in person costs $200 for all three days. You can also stream the entire conference live for $99. More about the talk here.
[Formatted for Printing] From the personal web site of  Michael Horowitz

VPNs on iOS are a scam

May 25, 2022 first published
May 28, 2022 totally re-wrote the Work-Arounds section
May 30, 2022 minor edits and new section on Testing Airplane Mode
May 31, 2022 expanded the My Suggestion section at the end
June 16, 2022 added details on yet another test

The VPN page of my DefensiveComputingChecklist.com site has a section with assorted tires that can be kicked to verify that a VPN is working. Some things are obvious, like checking for a new public IP address, new DNS servers and checking that WebRTC is disabled. This blog is about a less than obvious VPN test, one that requires a professional class router.

The basis for this is quite simple. Once a VPN connection (the official term is a "tunnel") is established, all data coming and going from the VPN-connected device is supposed to go through the VPN. Does it? That's what I set out to verify. Certainly most data passes through the VPN tunnel, but I was curious about all data.

Granted, some VPN software supports an option called split tunneling which breaks this simple rule, but that does not interest me. I just want to verify that the VPN tunnel is the all-consuming thing it's supposed to be. That resistance to it is futile. That the tunnel assimilates all the bits and bytes coming and going between the device in question and the Internet.

I don't come to the topic at random. In researching my VPN writeup, I ran across a March 2020 blog by ProtonVPN, VPN bypass vulnerability in Apple iOS, that describes a bug in iOS 13 and 14. The nature of the bug is that the VPN tunnel does not assimilate all the bits. Some escape. The Borg would not be happy.

What ProtonVPN wrote about is a VPN leak, rather than a DNS leak. Connections that exist at the time the VPN tunnel is created, should be terminated and re-started so that they travel through the VPN tunnel. In iOS 13 and 14, this does not happen, at least not by default.

Interestingly, the Windscribe desktop VPN client software has an option for this, called "Kill TCP sockets after connection" (see TCP Socket Termination). However, the option does not exist in their iOS software. I checked a handful of iOS VPN clients for other VPN providers and found none with an option about terminating existing connections/sockets when establishing the VPN tunnel.

I am following up on the ProtonVPN blog for a couple reasons. For one, it was last updated in October 2020 when iOS 14 was first released. iOS is now at version 15. And, the last update said that a new iOS feature would soon be included in their app to fix the problem. But, ProtonVPN never followed up on this. Did they add this new feature? Does it fix the problem? They left the issue hanging.

METHODOLOGY

My methodology is simple, I will log every new outbound request from my iPad (in other contexts a "request" might be called a socket, a session, a connection or a thread). I will start the logging, establish a VPN connection and use the iPad normally. If all goes well, I should see the outbound request(s) that establish the VPN tunnel and nothing else afterwards. If all data travels through the VPN connection/tunnel, the router will see no new outbound requests from the iPad, after the VPN tunnel has been established.

Although the testing is simple, it is not something that most people can do. Consumer routers, and those provided by an ISP, are not going to have the ability to log outbound requests. This may well have contributed to the bug in iOS going undetected for a long time.

The outbound firewall rule that logged requests from the iPad is shown below. It keys off the LAN side IP address of my iPad and logs any new outbound request that it makes. (the LAN side address of my iPad was not actually 10.1.2.3). I tested with a Peplink Balance 20x router running firmware 8.2.0.

Outbound Firewall rule in Peplink router
 Outbound Firewall rule in Peplink router 

FIRST TEST

During the first test, the iPad was running iOS version 15.4.1. I tested using version 3.1.3 (2205050847) of the ProtonVPN app. The app made an IKEv2 connection to a VPN server in Spain at IP address 37.19.214.3. Both the app (screen shot) and a couple web sites confirmed that the public IP address was 37.19.214.3.

In simplified form, this is what the router log showed just after I started the VPN connection:

11:57:52 SRC=10.1.2.3 DST=37.19.214.1    LEN=408 PROTO=UDP SPT=4500  DPT=4500
11:57:52 SRC=10.1.2.3 DST=23.200.168.178 LEN=64  PROTO=TCP SPT=57025 DPT=443 SYN
11:57:52 SRC=10.1.2.3 DST=37.19.214.1    LEN=300 PROTO=UDP SPT=500   DPT=500
11:57:52 SRC=10.1.2.3 DST=137.220.51.178 LEN=589 PROTO=TCP SPT=57024 DPT=443 SYN
Establishing the IKEv2 VPN tunnel

The most important take-away from this is that the VPN tunnel was established at 11:57:52.

As for the data items in the log: SRC is the source IP address, DST is the destination IP address, LEN is the length of the outgoing data, PROTO is the protocol (TCP or UDP), SPT is source port, and DPT is the destination port. Not sure what SYN is.

It is interesting to note that while the public IP address is 37.19.214.3, the two UDP outbound connections were made to 37.19.214.1. I have seen this before with assorted VPNs (not just IKEv2 but also with OpenVPN) and I can't explain it. Also, establishing the IKEv2 connection was done with two outbound UDP requests, first to port 4500 (from port 4500) and then to port 500 (from port 500). I am no expert on the IKEv2 protocol and can not explain why it does this.

We also see that there were two other outbound requests made the same second that the VPN tunnel was established. For my purposes, neither was important. One was a TCP request to 23.200.168.178 on port 443 (HTTPS). According to Shodan, this IP address is mesu.apple.com. The other was a TCP request to 137.220.51.178 also on port 443. This is dns.nextdns.io and not a surprise to see since the router is using NextDNS with DoH.

Curious about the difference between the reported public IP address and the one that the router log showed it connecting to, I checked what Peplink calls the Active Sessions for the iPad. As shown below, this was the first indication of trouble.

Active Sessions for iPad after VPN established
 Active Sessions for iPad after VPN established 

While this confirms that the iPad is actually connected to the IP address ending in 1 rather than 3, it also shows a connection/session that is not the VPN tunnel. Although the tunnel was established when I made this screen shot, the iPad was still communicating with port 5223 at IP address 17.57.144.12. Peplink identified this as Apple Push.

The bug that ProtonVPN first wrote about in March 2020, still exists. iOS 15.4.1 still does not terminate existing connections/sessions when it creates a VPN tunnel. This presents assorted dangers. Connections outside the VPN communicate your real public IP address and there is no guarantee that they are encrypted. They are also vulnerable to ISP spying. And, a VPN provides what should be a trustworthy DNS service. Outside the VPN, anything goes.

Next, I used assorted apps on the iPad and watched the router log.

Twenty eight minutes after the VPN connection was established, this showed up in the log.

12:26:33 SRC=10.1.2.3 DST=137.220.51.178 LEN=589 PROTO=TCP SPT=57026 DPT=443 SYN
A request to NextDNS outside the VPN tunnel

Another request to dns.nextdns.io. Not good.

A FLOOD

Twelve minutes later, a flood.

12:41:21 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=57740 DPT=57740
12:41:21 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=57740 DPT=57740
12:41:16 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=65009 DPT=65009
12:41:16 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=65009 DPT=65009
12:41:05 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=57740 DPT=57740
12:41:00 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=65009 DPT=65009
12:41:00 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=65009 DPT=65009
12:41:00 SRC=10.1.2.3 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=65009 DPT=16386
12:40:57 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=57740 DPT=57740
12:40:57 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=57740 DPT=57740
12:40:55 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:55 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:53 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=57740 DPT=57740
12:40:53 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=57740 DPT=57740
12:40:52 SRC=10.1.2.3 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=57740 DPT=16386
12:40:52 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=57740 DPT=16384
12:40:52 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=65009 DPT=65009
12:40:51 SRC=10.1.2.3 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=65009 DPT=16386
12:40:51 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:51 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:50 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=57740 DPT=57740
12:40:50 SRC=10.1.2.3 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=57740 DPT=16386
12:40:50 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=57740 DPT=16385
12:40:50 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=57740 DPT=16384
12:40:47 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=65009 DPT=65009
12:40:47 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=65009 DPT=65009
12:40:47 SRC=10.1.2.3 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=65009 DPT=16386
12:40:47 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=65009 DPT=16384
12:40:46 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:46 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:46 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:45 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=65009 DPT=65009
12:40:45 SRC=10.1.2.3 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=65009 DPT=16386
12:40:45 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=65009 DPT=16385
12:40:45 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=65009 DPT=16384
12:40:42 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:42 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:42 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:42 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=16403 DPT=16385
12:40:40 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:40 SRC=10.1.2.3 DST=99.99.99.99 LEN=44 PROTO=UDP SPT=16403 DPT=16403
12:40:40 SRC=10.1.2.3 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=16403 DPT=16386
12:40:40 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=16403 DPT=16385
12:40:40 SRC=10.1.2.3 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=16403 DPT=16384
12:38:58 SRC=10.1.2.3 DST=37.19.214.1 LEN=408 PROTO=UDP SPT=4500 DPT=4500
12:38:58 SRC=10.1.2.3 DST=37.19.214.1 LEN=300 PROTO=UDP SPT=500 DPT=500
12:38:58 SRC=10.1.2.3 DST=17.253.99.99 LEN=76 PROTO=UDP SPT=123 DPT=123
12:38:58 SRC=10.1.2.3 DST=17.253.99.99 LEN=76 PROTO=UDP SPT=123 DPT=123
12:38:58 SRC=10.1.2.3 DST=17.253.99.99 LEN=76 PROTO=UDP SPT=123 DPT=123
12:38:58 SRC=10.1.2.3 DST=137.220.51.178 LEN=589 PROTO=TCP SPT=57027 DPT=443
The flood gates are open!

At this point I stopped the activity logging to avoid flooding the router log.

My first thought was that the VPN connection had failed. But no, ProtonVPN reported that the connection to Madrid had been active for 49 minutes. The flood started at roughly 12:39 PM and VPN connection was first made at 11:58 AM. To borrow a phrase from Apollo 13: Cupertino, we have a problem.

Speaking of the VPN, the iPad made the same two IKEv2 connections at 12:38:58 - a UDP request to port 4500 and a UDP request to port 500, both to the currently in-use VPN server (37.19.214.1). Maybe there are keys that need to re-established? I don't know.

There is so much else to look at in the 2.5 minutes of activity shown above.

Perhaps the biggest mystery is the 28 requests to IP address 99.99.99.99. That was not the actual IP address; I changed it because the actual address was my public IP. This makes no sense at all, at least not to me. All the requests were UDP and the same length (44). Looking at just those 28 requests a pattern emerges, as shown below. There were three different target ports and the source port number was always the same as the destination port number. Stranger still.

12:41:21 SPT=57740 DPT=57740
12:41:21 SPT=57740 DPT=57740
12:41:05 SPT=57740 DPT=57740
12:40:57 SPT=57740 DPT=57740
12:40:57 SPT=57740 DPT=57740
12:40:53 SPT=57740 DPT=57740
12:40:53 SPT=57740 DPT=57740
12:40:50 SPT=57740 DPT=57740
12:41:16 SPT=65009 DPT=65009
12:41:16 SPT=65009 DPT=65009
12:41:00 SPT=65009 DPT=65009
12:41:00 SPT=65009 DPT=65009
12:40:52 SPT=65009 DPT=65009
12:40:47 SPT=65009 DPT=65009
12:40:47 SPT=65009 DPT=65009
12:40:45 SPT=65009 DPT=65009
12:40:55 SPT=16403 DPT=16403
12:40:55 SPT=16403 DPT=16403
12:40:51 SPT=16403 DPT=16403
12:40:51 SPT=16403 DPT=16403
12:40:46 SPT=16403 DPT=16403
12:40:46 SPT=16403 DPT=16403
12:40:46 SPT=16403 DPT=16403
12:40:42 SPT=16403 DPT=16403
12:40:42 SPT=16403 DPT=16403
12:40:42 SPT=16403 DPT=16403
12:40:40 SPT=16403 DPT=16403
12:40:40 SPT=16403 DPT=16403
  iPad requests to my public IP address  

Adding to the mystery is the port numbers the iPad tried to contact. To say the least, they are off the beaten path. Since the activity log is from the router, we can not tell if the outbound requests were from iOS itself or a third party app. Apple documents the TCP and UDP ports used by Apple software products and the only port documented to be used by iOS is 16403 which is used by the Game Center. I have never installed or played a game on the iPad in question. The two other ports, 57740 and 65009, have no standard usage.

The 20 outbound requests that were not to my public IP address and not the in-use VPN server are shown below.

12:41:00 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=65009 DPT=16386
12:40:52 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=57740 DPT=16386
12:40:52 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=57740 DPT=16384
12:40:51 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=65009 DPT=16386
12:40:50 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=57740 DPT=16386
12:40:50 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=57740 DPT=16385
12:40:50 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=57740 DPT=16384
12:40:47 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=65009 DPT=16386
12:40:47 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=65009 DPT=16384
12:40:45 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=65009 DPT=16386
12:40:45 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=65009 DPT=16385
12:40:45 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=65009 DPT=16384
12:40:42 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=16403 DPT=16385
12:40:40 DST=17.178.104.183 LEN=44 PROTO=UDP SPT=16403 DPT=16386
12:40:40 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=16403 DPT=16385
12:40:40 DST=17.178.104.182 LEN=44 PROTO=UDP SPT=16403 DPT=16384
12:38:58 DST=17.253.99.99   LEN=76  PROTO=UDP SPT=123 DPT=123
12:38:58 DST=17.253.99.99   LEN=76  PROTO=UDP SPT=123 DPT=123
12:38:58 DST=17.253.99.99   LEN=76  PROTO=UDP SPT=123 DPT=123
12:38:58 DST=137.220.51.178 LEN=589 PROTO=TCP SPT=57027 DPT=443
The parts of the flood that were not to my public IP address

The first request (12:38:58) mimics one we have seen before, the target is NextDNS on the expected port (443). Interestingly, this was the only TCP request, all the rest were UDP.

The next three requests were to UDP port 123, which is the Time of Day port. The target IP addresses all start with 17.253 and are clearly NTP time servers owned by Apple. Here again, the 99 is a placeholder for a number, I am not publishing the exact IP addresses for reasons that are off topic. These requests occurred in the same second as the call out to NextDNS.

The remaining 16 requests were to only two IP addresses: 17.178.104.182 and 17.178.104.183. Both belong to Apple. Certainly it is fair to say, at this point, that the flood of outbound requests that bypassed the VPN tunnel came from iOS itself.

The destination ports at the two Apple IP addresses were 16384, 16385 and 16386 so they clearly have a common purpose. According to Apple these UDP ports are used for either the Real-Time Transport Protocol or Real-Time Control Protocol by either FaceTime or Game Center. I was not using FaceTime or playing a game on the iPad. Also, the source port numbers look awfully familiar.

SECOND TEST

To verify that the bug is in iOS itself, I ran a second test under different conditions.

The first thing I changed was the OS; the iPad was updated to version 15.5, which, as I write this, is the latest version. I also changed VPN providers, software and protocols. This test used an iOS app from OVPN that only supports WireGuard.

The OVPN app was version 0.5.0 from Feb. 19, 2022. The VPN server that I connected to was 139.28.219.36 in France. My test procedure was the same: I configured the Peplink Balance 20x router to log all outbound connections made by the iPad, I connected to the VPN, used the iPad and watched the router log.

This time, the establishing of the VPN tunnel seemed to be done with a single outbound UDP connection (shown below) to port 9929 at 139.28.219.35.

16:08:59 SRC=10.1.2.3 DST=139.28.219.35 LEN=176 PROTO=UDP SPT=50700 DPT=9929
Establishing the WireGuard VPN tunnel

As with the first test, which used IKEv2, the IP address that the world sees is one off from the IP address that the router connected to. I made a screen shot of the OVPN app which shows a public IP address of 139.28.219.36, one higher than the IP the router connected to. Other web sites confirmed this as the public IP. Some day, I have learn why this happens.

After the VPN was established, I checked the Active Sessions for the iPad. The only connection the router showed was the VPN tunnel. No Apple Push this time.

I used the iPad and watched the log...

Seven minutes later another flood of requests are seen traveling outside the VPN tunnel. I stopped the router logging after the flood shown below. I am simply interested in whether there is a problem, yes or no. I am not interested in fully defining/debugging the problem. That's for Apple.

As before, there were many requests to my public IP address. Quite the puzzlement. They were all UDP and the Source Port number (SPT) was always the same as the Destination Port number (DPT). The table below shows these connections. It is sorted by destination/target port, rather than time of day, to better show the three destination ports: 16403, 51941 and 52666. Just for fun, a Google search for "Apple iOS UDP port 52666" turned up nothing.

16:16:46 SRC=10.1.2.3 ID=59313 PROTO=UDP SPT=16403 DPT=16403
16:16:46 SRC=10.1.2.3 ID=55901 PROTO=UDP SPT=16403 DPT=16403
16:16:38 SRC=10.1.2.3 ID=40208 PROTO=UDP SPT=16403 DPT=16403
16:16:38 SRC=10.1.2.3 ID=28964 PROTO=UDP SPT=16403 DPT=16403
16:16:34 SRC=10.1.2.3 ID=35868 PROTO=UDP SPT=16403 DPT=16403
16:16:34 SRC=10.1.2.3 ID=8209  PROTO=UDP SPT=16403 DPT=16403
16:16:31 SRC=10.1.2.3 ID=39229 PROTO=UDP SPT=16403 DPT=16403
16:17:18 SRC=10.1.2.3 ID=63831 PROTO=UDP SPT=51941 DPT=51941
16:17:18 SRC=10.1.2.3 ID=40276 PROTO=UDP SPT=51941 DPT=51941
16:17:02 SRC=10.1.2.3 ID=50924 PROTO=UDP SPT=51941 DPT=51941
16:16:54 SRC=10.1.2.3 ID=52733 PROTO=UDP SPT=51941 DPT=51941
16:16:54 SRC=10.1.2.3 ID=18792 PROTO=UDP SPT=51941 DPT=51941
16:16:46 SRC=10.1.2.3 ID=18096 PROTO=UDP SPT=51941 DPT=51941
16:16:46 SRC=10.1.2.3 ID=40090 PROTO=UDP SPT=51941 DPT=51941
16:16:46 SRC=10.1.2.3 ID=31786 PROTO=UDP SPT=51941 DPT=51941
16:16:38 SRC=10.1.2.3 ID=50271 PROTO=UDP SPT=51941 DPT=51941
16:16:38 SRC=10.1.2.3 ID=50661 PROTO=UDP SPT=51941 DPT=51941
16:16:38 SRC=10.1.2.3 ID=36010 PROTO=UDP SPT=51941 DPT=51941
16:16:48 SRC=10.1.2.3 ID=6173  PROTO=UDP SPT=52666 DPT=52666
16:16:44 SRC=10.1.2.3 ID=14513 PROTO=UDP SPT=52666 DPT=52666
16:16:40 SRC=10.1.2.3 ID=4581  PROTO=UDP SPT=52666 DPT=52666
16:16:40 SRC=10.1.2.3 ID=30535 PROTO=UDP SPT=52666 DPT=52666
16:16:40 SRC=10.1.2.3 ID=16925 PROTO=UDP SPT=52666 DPT=52666
16:16:36 SRC=10.1.2.3 ID=43384 PROTO=UDP SPT=52666 DPT=52666
16:16:36 SRC=10.1.2.3 ID=38165 PROTO=UDP SPT=52666 DPT=52666
16:16:36 SRC=10.1.2.3 ID=17988 PROTO=UDP SPT=52666 DPT=52666
16:16:34 SRC=10.1.2.3 ID=53627 PROTO=UDP SPT=52666 DPT=52666
16:16:34 SRC=10.1.2.3 ID=42495 PROTO=UDP SPT=52666 DPT=52666
16:16:31 SRC=10.1.2.3 ID=57859 PROTO=UDP SPT=52666 DPT=52666
16:16:31 SRC=10.1.2.3 ID=62414 PROTO=UDP SPT=52666 DPT=52666
16:16:31 SRC=10.1.2.3 ID=16697 PROTO=UDP SPT=52666 DPT=52666
Outbound iPad requests to my Public IP address (WireGuard)

The outbound requests to the actual Internet, shown below, fall into two categories. The last/top two requests were to IP addresses belonging to Amazon Web Services in Europe. They were TCP requests to the normal, ordinary, commonplace HTTPS port (443).

The rest were to Apple owned IP addresses on UDP ports 16384, 16385 and 16386. Same as the first test. Again, I am not publishing the exact Apple IP addresses (99.99 is a stand-in) for reasons that are off topic.

16:22:34 SRC=10.1.2.3 DST=15.160.79.209 ID=0 PROTO=TCP SPT=49173 DPT=443
16:17:22 SRC=10.1.2.3 DST=15.160.35.79  ID=0 PROTO=TCP SPT=49169 DPT=443
16:16:38 SRC=10.1.2.3 DST=17.173.99.99 ID=40457 PROTO=UDP SPT=51941 DPT=16386
16:16:38 SRC=10.1.2.3 DST=17.173.99.99 ID=51493 PROTO=UDP SPT=16403 DPT=16385
16:16:33 SRC=10.1.2.3 DST=17.173.99.99 ID=40240 PROTO=UDP SPT=51941 DPT=16386
16:16:33 SRC=10.1.2.3 DST=17.173.99.99 ID=41763 PROTO=UDP SPT=51941 DPT=16384
16:16:33 SRC=10.1.2.3 DST=17.173.99.99 ID=26637 PROTO=UDP SPT=16403 DPT=16385
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=36462 PROTO=UDP SPT=51941 DPT=16386
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=15857 PROTO=UDP SPT=51941 DPT=16385
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=39550 PROTO=UDP SPT=52666 DPT=16386
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=28383 PROTO=UDP SPT=51941 DPT=16384
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=42153 PROTO=UDP SPT=52666 DPT=16385
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=60829 PROTO=UDP SPT=52666 DPT=16384
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=20614 PROTO=UDP SPT=16403 DPT=16386
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=36357 PROTO=UDP SPT=16403 DPT=16385
16:16:31 SRC=10.1.2.3 DST=17.173.99.99 ID=32360 PROTO=UDP SPT=16403 DPT=16384
Outbound iPad requests to the Internet (WireGuard)

WRAPPING UP

Comedian Steven Wright used to joke that he had to get a new shadow because the old one wasn't doing what he was doing. That's what we have here. A VPN that is not doing what it is supposed to do. Data is leaving my iPad and not traveling through the VPN tunnel.

It is surprising to find this problem has persisted for so long. My testing took very little hardware, software or expertise. With the billions of iOS users, it is hard to imagine that no one else bothered testing this. Then again, the world was a bit distracted in March of 2020.

It also seems that Apple has a level of trust that they do not deserve. Back in March 2020, Steve Gibson said "... Apple's going to fix this. I'm sure it's already been fixed in-house. They're probably moments away from pushing out a fix to this because it's gotten a lot of attention in the industry ... I imagine within a few days this'll be fixed." A slightly more skeptical John Dunn of Sophos wrote at the time that "A patch might not appear for weeks". It has been over two years.

I emailed Apple at their special email address for reporting security issues on May 19, 2022 and, for a week, there was no response. On May 26th, I emailed again and, this time, Apple responded the next day. To be continued...

WORK-AROUNDS

[This section was totally re-written May 28, 2022]

One suggested solution was an always-on VPN. Quoting ProtonVPN: "Apple recommends using Always-on VPN to mitigate this issue. This method requires using device management, so unfortunately it doesn’t mitigate the issue for third-party applications such as Proton VPN." So, not a solution for us consumers. But, ProtonVPN had two other suggested work-arounds.

The last update to the ProtonVPN blog (dated Oct. 19, 2020) said "Although Apple has not fixed the VPN bypass problem directly on iOS 14, they have provided the Kill Switch capability to app developers. By enabling Kill Switch, existing connections will be blocked whenever VPN is enabled. We will be adding this capability in an upcoming release of Proton VPN." This is a puzzling statement as the purpose of a VPN Kill Switch is to disconnect the Internet should the VPN tunnel fail. It is not normally involved in existing connections at the time the VPN is enabled.

Since the blog was written, ProtonVPN has indeed added a kill switch option to their iOS app (see screen shot). The description of the feature in the app is "blocks all network traffic when VPN tunnel is lost", which is par for the course as Kill Switches go. It also has nothing to do with leaks outside the VPN tunnel while the tunnel is alive and well. Apples and Oranges.

Still, I tested for VPN leaks with the Kill Switch enabled (it is disabled by default). It made no difference, the VPN still leaked. You can see this below.

The VPN tunnel is the UDP connection from port 4500 to port 4500 at IP address 188.241.83.106, which is ProtonVPN in Paris. We also see the iPad has two TCP connections labeled "Secure IMAP/Gmail". Both connections are to port 993 at IP address 172.253.62.108. Shodan reports that this IP address is indeed used for Gmail. And Google does use port 993 for IMAP access to Gmail.

Activxxxxxxblished
 Gmail outside the VPN tunnel 

The last suggested work-around involved using Airplane Mode to disconnect the VPN. Funny thing about Airplane Mode on my Wi-Fi only iPad running iOS 15.5. It does not seem to do anything.

With the Wi-Fi on, I enabled Airplane Mode and the Wi-fi did not go off (see screen shot). I also found that Airplane Mode did not interrupt an active VPN connection. I made a WireGuard connection using OVPN, then turned on Airplane Mode and the VPN connection remained alive and well.

With that as background, here is exactly what ProtonVPN said regarding this last work-around:

Internet connections established after you connect to VPN are not affected. But connections that are already running when you connect to VPN may continue outside the VPN tunnel indefinitely. There is no way to guarantee that those connections will be closed at the moment you start a VPN connection. However, we've discovered the following technique to be almost as effective:
 1. Connect to any Proton VPN server.
 2. Turn on airplane mode. This will kill all Internet connections and temporarily disconnect Proton VPN.
 3. Turn off airplane mode. Proton VPN will reconnect, and your other connections should also reconnect inside the VPN tunnel, though we cannot guarantee this 100%.

First thing to notice is that this is something ProtonVPN discovered, it is not advice from Apple. Then, there are the hedging phrases: "almost as effective" and "we cannot guarantee".

Still, how can it be that in their testing, Airplane Mode killed all Internet connections and in my testing it did not? Perhaps another bug in iOS? Or, maybe because blog was written for iOS 13 and I tested with iOS 15.5? I dug out an old iPod running iOS 12.5.5 and, sure enough, Airplane Mode turned off the Wi-Fi.

A bit of Googling turned up this Apple support item: Use Airplane Mode on your iPhone, iPad, iPod touch, and Apple Watch from September 2021. At first, the article says "When you turn on Airplane Mode, it turns off all radios except for Bluetooth". But later it says "you can use Wi-Fi and Bluetooth while in Airplane Mode. You just need to turn them on separately" and "If you turn on Wi-Fi or Bluetooth while you're in Airplane Mode, they'll be on the next time you use Airplane Mode, unless you turn them off while in Airplane Mode." So, Airplane Mode is like a box of chocolates, you never know what you're gonna get.

All told, this a poor look for the tech support team at ProtonVPN. Even if Airplane Mode is a work-around, they failed to explain all the issues with it. And, the suggestion that the Kill Switch is applicable at all, was off-base. Worse than their blog, when I contacted them recently about this, they said I should use the Kill Switch. Ugh.

TESTING AIRPLANE MODE

Added this section on May 30, 2022

I fought through the poorly written Apple support article about Airplane Mode, such that enabling it on my iPad would disable the Wi-Fi. And, then things got ugly.

With Airplane Mode OFF, the Settings app shows that Wi-Fi is connected, displaying the SSID of my network. But, there is no Wi-Fi icon in the top right corner of the iPad display (the half circles next to the battery percentage). So, is it on or not? No web pages would load, in multiple browsers, so it seems not. That the Settings app tells me it is connected to Wi-Fi seems like a bug.

Interestingly, my router also reported a half-connected state. While it showed the iPad in the list of connected devices, there were no active connections from the iPad to anywhere on the Internet. I did not bother with firewall logging.

The Wi-Fi connection was defined to use a Private Wi-Fi Address (really a MAC address). I turned this off, in the hope it was part of the problem. This reset the Wi-Fi connection. The router showed the iPad as a connected device with the new MAC/WiFi address, however, web pages would still not load and there was still no Wi-Fi indicator in the top right corner.

Airplane Mode broke my iPad.

At this point I turned the iPad off, waited a minute and turned it back on. When it booted, the Wi-Fi indicator in the top right corner was on, then went off, then it came back on along with the VPN indicator. VPN? I wasn't doing anything with a VPN. I wasn't but ProtonVPN was. Their app (version 3.1.3) has an Always-on VPN option that is, sadly, not an option. It is always on.

I turned off the ProtonVPN connection and all was well with the Wi-Fi. My guess is that something went wrong between Airplane Mode and the Always-on option. You're on. You're off. You're on. You're off.

I seem to be accumulating bugs, not only on the iPad but also in my Peplink Balance 20x router. While testing Airplane Mode, I was checking all the active sessions/connections from all the devices connected to the router (there were very few). I saw an active session for a device that I did not realize was connected. So, I turned off the Wi-Fi on the device. Surprisingly, the active session remained for what seemed quite a while. The router reported that the device went off-line, but a session remained active. I reported it as a bug to Peplink. Any comments above, about Active Sessions shown by the router, are now suspect. Ugh.

YET ANOTHER TEST

Added this section on June 16, 2022

I have been in contact with Apple about this and they requested a dump of the system, after the problem happens, so I did another test. I was able to re-create the problem, this time using VPN software from Windscribe that made an OpenVPN connection. Using VPN software from three different VPN companies clearly points at iOS itself as the source of the problem.

After the VPN connection was made, I tried a number of apps and none generate traffic outside the VPN tunnel. It was not until I went into the iOS app store, to update some apps, that the flood of traffic outside the tunnel started. As before, there were requests to both Apple IP addresses and my public IP address.

Apple has not said whether they tried to re-create the problem. It takes so little time and effort to re-create it, and the problem is so consistent, that if they tried at all, they should have been able to re-create it. Perhaps they won't bother trying to re-create it without the system dump to prove that I am telling the truth? Dunno.

Dealing with Apple has been pretty disappointing on many levels. But, that's for another day.

MY SUGGESTION

At this point, I see no reason to trust any VPN on iOS. My suggestion would be to make the VPN connection using VPN client software in a router, rather than on an iOS device.

I am not a fan of making a VPN connection on your only router, but suggest having a second router dedicated to VPN connections. When you need a VPN, connect to the second router (Wi-Fi or Ethernet), when you don't need a VPN, connect to your main router.

I recommend pcWRT as a second router dedicated to VPN usage. I recently wrote up my experiences with it. There is only one model and it sells for $129 US. It offers three VPN clients, for WireGuard, OpenVPN and IKEv2. I ran the same evaluation on pcWRT that I did here for iOS. In fact, I ran it for days on end and found no data that ever traveled outside the VPN tunnels created by the pcWRT router. Here on iOS, it took only a few minutes to find a VPN leak.

 

 

 @defensivecomput TOP Home => VPNs on iOS are a scam   
 michael--at--michaelhorowitz.com   Last Updated: June 16, 2022 2PM UTC  
  License Plate
Copyright 2001-2022
Copyright 2001-2022  
Printed at:   July 1, 2022 4:41pm   ET
Viewed 1,112 times since May 25, 2022 (30/day over 37 days)