我正在遵循文档并尝试连接 IKEv2,但下面的代码始终返回日志“无 VPN 接口”
package com.mehrab.examplevpn;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.VpnService;
import android.net.ipsec.ike.SaProposal;
import android.net.Ikev2VpnProfile;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
import java.net.InetSocketAddress;
import java.nio.channels.DatagramChannel;
public class MyVpnService extends VpnService {
private static final String VPN_SERVER_IP = "example.info";
private static final String VPN_USERNAME = "[email protected]";
private static final String VPN_PASSWORD = "secret";
private static final String VPN_ROUTE = "0.0.0.0"; // Default route
private ParcelFileDescriptor vpnInterface;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "NonConn!", Toast.LENGTH_SHORT).show();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
vpnInterface = establishVPN();
if (vpnInterface != null) {
// Connect to VPN server
InetSocketAddress serverAddress = new InetSocketAddress(VPN_SERVER_IP, 5000);
DatagramChannel tunnel = DatagramChannel.open();
tunnel.connect(serverAddress);
Log.d("mytag", "Connected");
// Close resources when done
tunnel.close();
} else {
Log.d("mytag", "No vpn interface");
}
} catch (Exception e) {
Log.d("mytag", "Try Catch Error");
e.printStackTrace();
}
}
});
thread.start();
return START_STICKY;
}
private ParcelFileDescriptor establishVPN() throws Exception {
String identity = "yourIdentity";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
Ikev2VpnProfile profile = new Ikev2VpnProfile.Builder(VPN_SERVER_IP, identity)
.setAuthUsernamePassword(VPN_USERNAME, VPN_PASSWORD, null) // Replace null with the root CA if available
.setBypassable(false)
.setMaxMtu(1400)
.setMetered(false)
.build();
}
VpnService.Builder vpnBuilder = new VpnService.Builder();
vpnBuilder.setSession("MyIKEv2VPN")
.addAddress("192.168.0.2", 32) // Virtual IP address
.addRoute(VPN_ROUTE, 0) // Default route
.setConfigureIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_IMMUTABLE));
// Configure the VPN interface using the IKEv2 profile
vpnInterface = vpnBuilder.establish();
return vpnInterface;
}
@Override
public void onDestroy() {
super.onDestroy();
try {
if (vpnInterface != null) {
vpnInterface.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
我尝试通过 IKEv2 连接 VPN。但它无法连接并返回我的日志“无 VPN 接口”
如果您使用的是 SDK 33,您可以尝试我的 kotlin 代码,使用 eap_mschapv2 连接到像 Strongswan 这样的 VPN 服务器。
// Define an SA Proposal with encryption, integrity, and DH group
val saProposal = IkeSaProposal.Builder()
.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, 256)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
.addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256)
.addDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP)
.build()
val childSaProposal = ChildSaProposal.Builder()
.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, 256)
.addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
.addDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP)
.build()
val remoteIdentification = IkeFqdnIdentification(vpn_server)
val localIdentification = IkeFqdnIdentification(username)
// Create EAP configuration (customize according to your requirements)
val eapConfig = EapSessionConfig.Builder()
.setEapMsChapV2Config(username, password)
.build()
val ikeSessionParams = IkeSessionParams.Builder()
.setServerHostname(vpn_server)
.addIkeSaProposal(saProposal) // Security association proposal
.setLocalIdentification(localIdentification)
.setRemoteIdentification(remoteIdentification)
.setAuthEap(null, eapConfig) // Use EAP for authentication with CA certificate
.setDpdDelaySeconds(30)
.setNattKeepAliveDelaySeconds(20)
.build()
val childSessionParams = TunnelModeChildSessionParams.Builder()
.addChildSaProposal(childSaProposal)
.addInternalAddressRequest(OsConstants.AF_INET)
.build()
val tunnelConnectionParams = IkeTunnelConnectionParams(ikeSessionParams, childSessionParams)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val ikev2VpnProfile = Ikev2VpnProfile.Builder(tunnelConnectionParams).build()
vpnManager.provisionVpnProfile(ikev2VpnProfile)
vpnManager.startProvisionedVpnProfileSession()
}
您可以在我的存储库中找到完整的代码https://github.com/moukail/ike_eap_mschapv2_vpn_demo