Автоматизация L2TP на Android: скрипт может запросить, но не построить
shell-маршрут не поднимает L2TP/IPsec на Android. IPsec, L2TP, PPP и политика платформы владеют каждый своей частью, поэтому выбирайте, что может это контролировать.
Миф в том, что L2TP на Android — ещё одна вещь, которую может запустить shell-скрипт: добавить маршрут, вызвать старый сервис, готово. Так быть не может, потому что четыре разных слоя должны договориться, прежде чем туннель понесёт пакет. Слой IPsec защищает путь, L2TP несёт сессию, PPP согласует канал, а Android должен зарегистрировать результат как VPN, вокруг которого он может маршрутизировать. Я видел две попытки с копированными командами, и оба раза маршрут существовал, пока ничего не было зашифровано.
Что на самом деле даёт изменение маршрута
Добавление маршрута решает, куда пакет пойдёт дальше. Оно не согласует ассоциацию безопасности, не открывает сессию L2TP и не выполняет обмен PPP, который создаёт адрес, партнёра и настройки DNS. На телефоне видимый результат — трафик, уходящий не тем путём или уходящий и умирающий, без какого-либо состояния туннеля.
То же касается вызова сервиса, скопированного из старого выпуска. Внутренняя VPN-обвязка Android не является опубликованным API автоматизации, а нумерованная транзакция из другой версии может попасть в другую операцию или потребовать привилегий, которых у скрипта нет. Автоматизация, несущая пароль, никогда не должна зависеть от угаданных внутренних аргументов, потому что режим отказа — либо тихий no-op, либо наполовину созданный профиль, который никто не убирает.
Четыре владельца, и скрипт — ни один из них
Возьмите их по порядку. IPsec устанавливает и поддерживает защищённый путь и аутентифицирует партнёров. L2TP несёт сессию поверх него, и именно расслоение — причина, по которой стандарт считает их отдельными механизмами, а не одним протоколом. Внутри этого PPP согласует параметры канала, которые будет использовать клиент. Затем Android владеет стороной платформы: зарегистрированный интерфейс VPN, область для каждого приложения, состояние always-on и жизненный цикл, решающий, что происходит при уничтожении приложения.
Скрипт может видеть только последний из этих слоёв, и обычно косвенно. Он может попросить клиент подключиться, если тот предоставляет документированное управление, а после этого наблюдать за состоянием интерфейса. Он не может заменить три нижних слоя и не может заставить платформу считать незарегистрированный интерфейс VPN.
Почему демон тоже не короткий путь
Запуск привилегированного демона Linux на устройстве выглядит недостающей деталью, и часто он действительно поднимает туннель. Чего он не делает — не регистрирует этот туннель в Android. Интерфейс существует внутри ядра, но выбор VPN платформы, маршрутизация по приложениям, политика always-on и жизненный цикл о нём не знают, а собственные изменения маршрутов и DNS демона конкурируют с менеджером сети за одни и те же таблицы.
Результат — соединение, которое работает для трафика демона и загадочным образом не работает для приложения, которое вам было важно, или существует, пока система не переоценит свои сети. Ни один из исходов не является ошибкой платформы; это граница между владением сокетом и владением возможностью VPN.
Как выглядят поддерживаемые пути
Если организация может перейти на профиль, который предоставляет сам Android, честный путь — платформенный. Начиная с API 30, VpnManager поддерживает предоставление и управление профилями VPN платформы приложениями, с потоком авторизации, привязанным к вызывающему приложению. Это не конвертер L2TP: модель профиля, которую он предоставляет для IKEv2, не переводит существующую конфигурацию L2TP, а смена протокола — это миграция, а не переименование. Идентичности, маршруты, приватный DNS и права доступа нужно переносить осознанно.
Если сервис должен остаться на L2TP/IPsec, поддерживаемая комбинация — клиент и выпуск ОС, которые оператор действительно документирует, и его контракт автоматизации, если он есть. Когда документированного управления без участия человека нет, правильный ответ — поддерживаемое ручное подключение, а не хрупкий привилегированный скрипт, который случайно работает в одной сборке.
Что делает правильная автоматизация
При наличии документированного управления у автоматизации небольшая и защитимая задача: запросить именованное подключение, дождаться готовности, остановиться при ошибке аутентификации или настройки, выполнить нужную работу и оставить очистку компоненту, владеющему подключением. Учётные данные остаются у клиента, который умеет их хранить и ротировать.
Запишите, какой компонент владеет каждым слоем, прежде чем писать первую строку, и сверяйте результат с этим:
- IPsec и PPP обрабатывает клиент, а не маршруты скрипта.
- Подключение появляется в состоянии VPN платформы, поэтому область для каждого приложения и always-on применяются к нему.
- Ни один внутренний вызов сервиса, номер транзакции или угаданный аргумент не несёт учётные данные.
- Сбой на любом шаге не оставляет наполовину зарегистрированный профиль.