iOS заметки

Настройка автоподключения к VPN

Используя L2TP сервер (напр. docker ipsec-vpn-server) можно настроить устройства на iOS с опцией автоподключения к сети при разрыве с любых сетей, используя функционал “VPN On Demand”.

Функционал не вынесен в GUI т.к. он очень широк (поднимаем VPN при подкл. к определенным хостам, SSID, при использовании Wi-Fi, etc). Поэтому нужно создавать XML profile с расширением mobileconfig (только так, иначе iOS не распознает его как файл настроек) и применить его на устройстве. Подробнее о функционале можно прочитать на оф. сайте Apple.

VPN On Demand allows the system to automatically start or stop a VPN connection based on various criteria. For example, you can use VPN On Demand to configure an iPhone to start a VPN connection when it’s on Wi-Fi and stop the connection when it’s on cellular. Or, you can start the VPN connection when an app tries to connect to a specific service that’s only available via VPN.

Criteria/Value for Parameter
n Interface Match – Select the type of connection that matches device's network current adapter. Values available are any, Wifi, Ethernet, and Cellular.
n URL Probe – Enter the specified URL for criteria to be met. When criteria is met, a 200 HTTP status code is returned. This format includes protocol (https).
n SSID Match – Enter the device's current network ID. For the criteria to be met, it must match at least one of the values in the array. Use the + icon to enter multiple SSIDs as needed.
n DNS Domain Match – Enter the device's current network search domain. A wildcard is supported
(*.example.com).
n DNS Address Match – Enter the DNS address that matches the device's current DNS server's IP address. For criteria to be met, all the device's listed IP addresses must be entered. Matching with a single wildcard is supported (17.*).

Для создания profile можно использовать “рыбу” ниже или, например, специальный сайт (недостаток в том, что имя Autoreconnect будет). Данные с сайта не передаются никуда (проверено) даже при submit (скрипт полностью на базе js), поэтому можно не переживать что ваша учетная запись будет скомпроментирована. Причем Profile можно использовать и в Mac OS, не только в iOS.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array> <dict>
<key>UserDefinedName</key>
<string>VPN-NAME</string>
<key>PayloadDisplayName</key>
<string>VPN-NAME</string>
<key>PayloadIdentifier</key>
<string>VPN-NAME</string>
<key>PayloadUUID</key>
<string>8762AB04-53F0-8760-A51C-76363F1A0FB6</string>
<key>VPNType</key>
<string>L2TP</string>
<key>IPSec</key>
<dict>
<key>AuthenticationMethod</key>
<string>SharedSecret</string>
<key>LocalIdentifierType</key>
<string>KeyID</string>
<key>SharedSecret</key>
<string>SHARED-SECRET</string>
</dict>
<key>PPP</key>
<dict>
<key>AuthName</key>
<string>USERNAME</string>
<key>AuthPassword</key>
<string>USER-PASSWORD</string>
<key>CommRemoteAddress</key>
<string>VPN-SERVER-ADDRESS</string>
</dict>
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<!-- VPN Default state -->
<key>Action</key>
<string>Connect</string>
</dict>
</array>
<key>OverridePrimary</key>
<true/>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>VPN Configurations</string>
<key>PayloadIdentifier</key>
<string>7A1620DF-BA17-6060-B1DD-4E2161232E61</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>4E26140A-5990-750E-EE69-0A210A6D78D5</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

Для передачи файла на устройство используем почту/airdrop/files. После этого применяем profile (Settings -> Profile Downloaded -> Install) и пользуемся 🙂

В случае проблем с подключением к VPN серверу интернет работать не будет. При необходимости (напр. недоступность VPN сервера) поведение клиента можно вернуть в default (без reconnect), просто убрав "Connect On Demand" в настройках профиля VPN.

Так же можно удалить VPN connect через удаление profile (General -> Profile) в iOS и поиском по profiles в MAC OS.

Always on VPN & battery life

С настройками выше VPN коннект будет активен даже в Sleep режиме (с заблокированным экраном, Always on VPN), в том числе iOS будет:

  • отправлять keepalive
  • переподключаться при разрыве

Что в совокупности приводит к неполноценному sleep и, как итог, дополнительному расходу батареи – “на глаз” рост потребления в сравнении со стандартной работой vpn на 30-50%.

Если нам не нужен Always on VPN, то есть как минимум два работающих варианта, которые сохранят переподключения при разрывах, но при этом экономят батарею в sleep mode:

  • DisconnectOnSleep
  • DisconnectOnIdle

В обоих вариантах нужно добавить строки в mobileconfig профайл  – добавляем их в словарь с конфигом VPN, сразу после указания адреса сервера VPN-SERVER-ADDRESS. Операции в итоге в обоих случаях становятся менее “smooth” (за счет появления паузы на подключение к vpn после определенного периода сна), но нет больших издержек по батарее из-за неполноценного sleep.

Keeping the VPN active in the background provides smoother operation, but may be tough for the battery.

Так же рекомендую отключить полностью background app refresh. По факту он редко нужен, все важное приходит через push (напр. сообщения мессенжеров). Иначе sleep вашего телефона даже без контекста VPN всегда будет неполноценным.

документация apple

DisconnectOnSleep

Рекомендую использовать именно его – как только устройство блокируется (уходит в sleep), vpn отключается до разблокировки/прихода push notification (они приходят без туннеля)/background app refresh процесса. В интернете, как ни странно, освещен мало в контексте настройки VPN с использованием mobileconfig профайлов в отличии от нижестоящего DisconnectOnIdle.

You might want to use this feature if you're concerned about battery life. When the device goes to sleep, the VPN will disconnect to then reconnect on device wake-up.
<key>DisconnectOnSleep</key>
<integer>1</integer>

DisconnectOnIdle

Включаем DisconnectOnIdle и настраиваем IdleTimer в 2 минуты (120 секунд).

<key>DisconnectOnIdle</key> <integer>1</integer> <key>DisconnectOnIdleTimer</key> <integer>120</integer>

При его настройке нужно не забывать, что Idle timeout подразумевает отсутствие трафика в туннеле. Если телефон получает push notification и работают background app refresh процессы в sleep режиме, 2-ух минутный idle может наступить почти никогда. При этом, если настроить 10-и секундный idle, то мы будем получать постоянные reconnect не только в режиме Sleep, но и при обычной работе. В итоге настройка превращается в тонкий тюнинг и менее универсальна в сравнении с DisconnectOnSleep.

Параметр фигурирует в документации VMware и PaloAlto. Примеры настроек есть на git и в openVPN community 1 2.

<!-- Disconnect VPN when Idle for [amount of seconds] -->
--idle-timer TIME    Disconnect from VPN when idle for a certain period of time (in seconds) scenarios. Requires disabling "Reconnect On Wakeup" on OpenVPN.app.

Leave a Reply