12 KiB
Генерация .mobileconfig для WireGuard VPN (On-Demand)
Как собрать Apple-профиль конфигурации (.mobileconfig) для WireGuard с правилами On-Demand: автоматическое подключение VPN вне домашней сети и отключение на домашнем Wi‑Fi.
Зачем нужен .mobileconfig
- Обычный конфиг WireGuard — пользователь сам включает/выключает туннель.
- Профиль .mobileconfig — ставится в «Настройки» → «Профили» (macOS) или «Основные» → «VPN и управление устройством» (iOS). Туннель появляется в приложении WireGuard и может управляться On-Demand: система сама поднимает VPN, когда устройство не в доверенной сети (например не дома), и отключает на домашнем Wi‑Fi.
В итоге: за пределами дома — всегда VPN, дома — без VPN, без ручного переключения.
Что должно быть готово на сервере
- WireGuard поднят (например на контейнере 109).
- Для каждого клиента (macOS, iOS и т.д.):
- своя пара ключей (приватный + публичный);
- в
wg0.confна сервере добавлен[Peer]сPublicKeyиAllowedIPs(один адрес из подсети VPN, например10.10.99.2/32для iOS,10.10.99.3/32для macOS).
- Внешний IP и порт сервера (например
185.35.193.144:43123), проброс UDP на роутере на CT 109.
Подсеть VPN в примерах: 10.10.99.0/24; DNS в туннеле — AdGuard на 192.168.1.100.
Структура профиля
Файл .mobileconfig — это XML plist (Property List) с корневым словарём:
| Ключ | Назначение |
|---|---|
PayloadContent |
Массив payload’ов (в нашем случае один — VPN). |
PayloadDisplayName |
Название профиля в списке профилей. |
PayloadIdentifier |
Уникальный идентификатор (например ru.katykhin.wireguard.local-vpn). |
PayloadType |
Configuration. |
PayloadUUID |
Уникальный UUID профиля. |
PayloadVersion |
1. |
Внутри PayloadContent — один элемент типа VPN:
| Ключ | Назначение |
|---|---|
PayloadType |
com.apple.vpn.managed |
VPNSubType |
macOS: com.wireguard.macos — iOS: com.wireguard.ios |
UserDefinedName |
Имя туннеля в приложении WireGuard (например «Local VPN (WireGuard)»). |
VendorConfig → WgQuickConfig |
Строка с конфигом WireGuard в формате INI (как в обычном конфиге). |
VPN → RemoteAddress |
Адрес сервера (хост:порт). |
OnDemandEnabled |
1 — включить On-Demand. |
OnDemandRules |
Массив правил: когда отключать VPN (например на домашнем Wi‑Fi) и когда подключать. |
Конфиг WireGuard внутри профиля (WgQuickConfig)
В WgQuickConfig вставляется ровно тот же текст, что и в обычном клиентском конфиге WireGuard, например:
[Interface]
Address = 10.10.99.3/32
PrivateKey = <приватный-ключ-этого-клиента>
DNS = 192.168.1.100
[Peer]
PublicKey = <публичный-ключ-сервера>
Endpoint = 185.35.193.144:43123
AllowedIPs = 10.10.99.0/24, 192.168.1.0/24
PersistentKeepalive = 25
Address— один адрес из подсети VPN, уникальный для каждого устройства (вwg0.confна сервере вAllowedIPsдля этого peer должен быть этот же/32).PrivateKey— приватный ключ клиента (генерируется один раз и хранится только на устройстве / в профиле).PublicKey— публичный ключ сервера (из/etc/wireguard/server.pubна сервере).Endpoint— внешний IP или домен и порт WireGuard (проброс на роутере).AllowedIPs— какие сети пускать через VPN (подсеть VPN + LAN, если нужен доступ в домашнюю сеть).PersistentKeepalive— полезно для мобильных и NAT.
Ключи в профиле — секретные; не коммитить .mobileconfig с реальными ключами в репозиторий (добавить в .gitignore).
Правила On-Demand (OnDemandRules)
Массив словарей. Порядок важен: первое сработавшее правило применяется.
-
Отключить VPN на домашнем Wi‑Fi — правило с
Action = Disconnectи условием по Wi‑Fi:InterfaceTypeMatch=WiFi;SSIDMatch= массив SSID (например["HomeWiFi"]или["Netcraze-1882"]).- Итог: если устройство в Wi‑Fi с этим SSID → VPN отключается.
-
Во всех остальных случаях — подключать — правило без условий:
Action=Connect.- Итог: любой другой сеть (другой Wi‑Fi, сотовые данные) → VPN включается.
Пример в plist:
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Disconnect</string>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>SSIDMatch</key>
<array>
<string>HomeWiFi</string>
</array>
</dict>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
Перед установкой профиля замени HomeWiFi на реальный SSID своей домашней сети.
Различия macOS и iOS
- VPNSubType:
- macOS:
com.wireguard.macos - iOS:
com.wireguard.ios
- macOS:
- Остальная структура (WgQuickConfig, OnDemandRules, SSIDMatch) — одинаковая. Обычно делают два файла:
wireguard-macos-ondemand.mobileconfigиwireguard-ios-ondemand.mobileconfig, в каждом свой клиентский ключ и свойAddress(например.2/32для iOS,.3/32для macOS), если на сервере заведены два разных peer’а.
Шаблон plist (минимум для одного туннеля)
Ниже — скелет без подстановки ключей; в WgQuickConfig и в SSIDMatch нужно подставить свои значения.
<?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>PayloadDisplayName</key>
<string>VPN</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadIdentifier</key>
<string>ru.katykhin.wireguard.local-vpn.tunnel</string>
<key>PayloadUUID</key>
<string>A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D</string>
<key>UserDefinedName</key>
<string>Local VPN (WireGuard)</string>
<key>VPNType</key>
<string>VPN</string>
<key>VPNSubType</key>
<string>com.wireguard.macos</string>
<key>VendorConfig</key>
<dict>
<key>WgQuickConfig</key>
<string>[Interface]
Address = 10.10.99.3/32
PrivateKey = ВСТАВЬ_ПРИВАТНЫЙ_КЛЮЧ_КЛИЕНТА
DNS = 192.168.1.100
[Peer]
PublicKey = ВСТАВЬ_ПУБЛИЧНЫЙ_КЛЮЧ_СЕРВЕРА
Endpoint = 185.35.193.144:43123
AllowedIPs = 10.10.99.0/24, 192.168.1.0/24
PersistentKeepalive = 25
</string>
</dict>
<key>VPN</key>
<dict>
<key>RemoteAddress</key>
<string>185.35.193.144:43123</string>
<key>AuthenticationMethod</key>
<string>Password</string>
</dict>
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Disconnect</string>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>SSIDMatch</key>
<array>
<string>HomeWiFi</string>
</array>
</dict>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>WireGuard Local VPN (On-Demand)</string>
<key>PayloadIdentifier</key>
<string>ru.katykhin.wireguard.local-vpn</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>B2C3D4E5-F6A7-5B6C-9D0E-1F2A3B4C5D6E</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
Для iOS замени VPNSubType на com.wireguard.ios и в WgQuickConfig задай свой Address (например 10.10.99.2/32) и приватный ключ того peer’а, который добавлен для этого устройства в wg0.conf.
Генерация ключей (на сервере)
На сервере WireGuard (например в CT 109):
# Приватный ключ
wg genkey | tee client.key | wg pubkey > client.pub
# Вывести для копирования в профиль
cat client.key # → PrivateKey в [Interface]
cat /etc/wireguard/server.pub # → PublicKey в [Peer]
Отдельные ключи для каждого устройства (например ios.key/macos.key) и соответствующие peer’ы в wg0.conf — см. контейнер 109.
Безопасность
- В
.mobileconfigпопадают приватные ключи клиента. Файл нужно хранить только на доверенных носителях и не коммитить в публичный репозиторий. - В этом проекте файлы
*.mobileconfigи конкретноwireguard-macos-ondemand.mobileconfig,wireguard-ios-ondemand.mobileconfigдобавлены в.gitignore. - Передавать профиль на устройство по защищённому каналу (AirDrop, личная почта, зашифрованный диск).
Установка профиля
- macOS: двойной клик по
.mobileconfig→ откроются «Системные настройки» → «Профили» → установить. Туннель появится в приложении WireGuard; при необходимости один раз включите его вручную, далее On-Demand будет управлять подключением. - iOS: отправить файл на устройство (AirDrop, почта, «Файлы») → открыть → «Установить» → при необходимости «Настройки» → «Основные» → «VPN и управление устройством» → установить профиль. Туннель появится в WireGuard; включите один раз вручную, затем работает On-Demand.
После смены SSID или ключей — удалить старый профиль и установить новый.
Связь с другими документами
- Контейнер 109 (WireGuard) — настройка сервера, ключи, клиентские конфиги, раздел «On-Demand для iOS/macOS».
- Архитектура — таблица контейнеров, CT 109.
- Схема сети — место VPN в топологии, доступ к vault.katykhin.ru.