Android предоставляет пример кода ToyVpn , который вы можете посмотреть и использовать логику для своих нужд.
А вот некоторые подробности из документации
В этом классе есть два основных метода: prepare (Context) и VpnService.Builder.establish (). Первый касается действий пользователя и останавливает VPN-соединение, созданное другим приложением. Последний создает интерфейс VPN с использованием параметров, предоставленных VpnService.Builder. Приложение должно вызывать prepare (Context), чтобы предоставить право использовать другие методы в этом классе, и это право может быть отозвано в любое время. Вот общие шаги для создания VPN-соединения:
Когда пользователь нажимает кнопку для подключения, вызовите подготовку (Контекст) и запустите возвращенное намерение, если оно не равно нулю.
Когда приложение подготовится, запустите службу.
Создание туннеля для удаленного сервера и согласование параметров сети для VPN-подключения.
Предоставьте эти параметры VpnService.Builder и создайте интерфейс VPN, вызвав VpnService.Builder.establish ().
Обработка и обмен пакетами между туннелем и дескриптором возвращаемого файла.
Когда вызывается onRevoke (), закройте дескриптор файла и корректно выключите туннель.
Службы, расширяющие этот класс, должны быть объявлены с соответствующим разрешением и фильтром намерений. Их доступ должен быть защищен разрешением Manifest.permission.BIND_VPN_SERVICE, а их фильтр намерений должен соответствовать действию SERVICE_INTERFACE. Вот пример объявления службы VPN в AndroidManifest.xml:
<service android:name=".ExampleVpnService"
android:permission="android.permission.BIND_VPN_SERVICE">
<intent-filter>
<action android:name="android.net.VpnService"/>
</intent-filter>
</service>