0

I’ve been working on an Android app that uses a custom VPN service to connect via a SOCKS5 proxy on my VPS. However, I’m encountering the following error:

Connection failed: Connection reset by peer

I suspect the problem is that the SOCKS5 proxy is not being properly created or initialized in my app.

Here’s the code I’m using:

class MyVpnService : android.net.VpnService() {
    private val TAG = "VpnService"
    private val sshClient = SSHClient()

    private var vpnInterface: ParcelFileDescriptor? = null

    override fun onCreate() {
        super.onCreate()
        GlobalScope.launch {
            showNotification()
            startVPN()
        }
    }

    private fun startVPN() {
        // Step 1: Start the SOCKS proxy (SSH connection)
        sshClient.startSSH(
            host = "my.ssh.service",
            port = 22,
            username = "root",
            password = "password",
            socksPort = 1080
        )

        // Step 2: Configure and establish the VPN interface
        val builder = Builder()
        builder.setSession("MyVPN")
            .addAddress("10.0.0.2", 24) // VPN IP address
            .addDnsServer("8.8.8.8") // DNS server
            .addRoute("0.0.0.0", 0) // Route all traffic through VPN
            .setMtu(1500)

        vpnInterface = builder.establish()
        if (vpnInterface == null) {
            Log.e(TAG, "Failed to establish VPN interface")
            return
        }
        Log.d(TAG, "VPN interface established")

        // Step 3: Redirect traffic through the SOCKS proxy
        redirectTraffic(vpnInterface!!)
        Log.d(TAG, "Traffic redirection started")
    }

    override fun onDestroy() {
        super.onDestroy()
        stopVPN()
    }

    private fun stopVPN() {
        sshClient.stopSSH()
        vpnInterface?.close()
        vpnInterface = null
    }

    private fun showNotification() {
        val notification = NotificationCompat.Builder(this, "my_channel")
            .setSmallIcon(com.sy.onboarding_ui.R.drawable.ic_next)
            .setContentTitle("Run is active")
            .setContentText("Hello world")
            .build()
        startForeground(1, notification)
    }
}

fun redirectTraffic(vpnInterface: ParcelFileDescriptor) {
    val buffer = ByteBuffer.allocate(32767)

    try {
        // Connect to the SOCKS5 proxy
        val tunnel = SocketChannel.open(InetSocketAddress("127.0.0.1", 1080))
        if (!tunnel.isConnected) {
            Log.e("redirectTraffic", "Failed to connect to SOCKS5 proxy")
            return
        }
        Log.d("redirectTraffic", "Connected to SOCKS5 proxy")

        val inputStream = ParcelFileDescriptor.AutoCloseInputStream(vpnInterface)
        val outputStream = ParcelFileDescriptor.AutoCloseOutputStream(vpnInterface)

        while (true) {
            // Read packets from the VPN interface
            val length = inputStream.read(buffer.array())
            if (length > 0) {
                buffer.limit(length)

                // Forward packets to the SOCKS5 proxy
                tunnel.write(buffer)
                Log.d("redirectTraffic", "Forwarded $length bytes to SOCKS5 proxy")

                // Clear the buffer for the next read
                buffer.clear()
            }

            // Read responses from the SOCKS5 proxy
            val bytesRead = tunnel.read(buffer)
            if (bytesRead > 0) {
                // Write responses back to the VPN interface
                outputStream.write(buffer.array(), 0, bytesRead)
                Log.d("redirectTraffic", "Received $bytesRead bytes from SOCKS5 proxy")

                // Clear the buffer for the next read
                buffer.clear()
            }
        }
    } catch (e: IOException) {
        Log.e("redirectTraffic", "Connection failed: ${e.message}")
        e.printStackTrace()
    }
}

Logs:

SSH connection established
SOCKS5 proxy started on port 1080
VPN interface established
Connected to SOCKS5 proxy
Forwarded 76 bytes to SOCKS5 proxy
Connection failed: Connection reset by peer
4
  • Does the remote server enable the user root enabled in SSH? Most forbid that user from connecting remotely. Your problem is most likely caused by the remote system dropping (terminating) the connection. Find out why before trying to debug your code. Commented Jan 1 at 4:48
  • If it's your SSH daemon, you can enable debug logging, and with high probability, it will define the reason. A connection reset by a peer means that the other end of the TCP sessions sends you a segment with an RST byte. So, it intentionally telling you that it killing the connection. Commented Jan 1 at 14:36
  • @JohnHanley Yes, the root user can SSH to the server. Commented Jan 4 at 5:27
  • 1) I recommend immediately fixing that. You should never allow the root user over SSH. I realize that is not your problem, but you will pay about $0.10 (or more) per GB while hackers try to break into your server. At least use Google VPC firewall rules only allowing specific IP addresses. 2) Review the OpenSSH server logs. The reason for the dropped connection will be logged. Commented Jan 4 at 5:36

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.