rapiz1 / rathole

A lightweight and high-performance reverse proxy for NAT traversal, written in Rust. An alternative to frp and ngrok.
Apache License 2.0
8.82k stars 441 forks source link

How to use rathole to convert connected devices into proxy servers #281

Closed sam3961 closed 9 months ago

sam3961 commented 10 months ago

Hi, I am already using frp on my linux server to convert the connected devices into a proxy server themselves. Now i am thinking of switching to rathole. Can you please guide me step by step on how to install it on ubuntu server and achieve the above objective of coverting the connected devices to proxy servers.

Response needed asap. Thank you.

fernvenue commented 10 months ago

Could you please provide your frp configuration files?

sam3961 commented 10 months ago

Hi @fernvenue i am using this in my server.ini file

[common]
bind_port = 7000
authentication_method=token
token = 89614138

image

fernvenue commented 10 months ago

And what about client side?

sam3961 commented 10 months ago

Client Side i am using android app where i am using FRPC lib where i get from there https://github.com/proxidize/proxidize-android/tree/main/app/libs And using there code to create a proxy server

Reference File : https://github.com/proxidize/proxidize-android/blob/main/app/src/main/java/com/legacy/android/LoginActivity.kt

   private fun startConnection() {
        CoroutineScope(Dispatchers.IO).launch {
            Frpclib.touch()
            Frpclib.run(activity?.cacheDir.toString() + "/config.ini")
        }
    }
fernvenue commented 10 months ago

I mean your configuration file on client side.

sam3961 commented 10 months ago

For Client Side i am using android app there is no code on server for client side What i am doing is setting up server.ini config file loaded in android app and then create a proxy server

private fun writeToConfigFile(server: ProxyServer, resetPorts: Boolean) {
        val logFile = File(requireContext().cacheDir, configLogFile)
        if (logFile.exists()) {
            logFile.delete()
        }
        if (!logFile.exists()) {
            try {
                logFile.createNewFile()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        var out: FileOutputStream? = null
        val file = File(requireContext().cacheDir, configFileName)
        if (file.exists()) {
            file.delete()
        }
        if (!file.exists()) {
            try {
                file.createNewFile()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        try {
            out = FileOutputStream(file, true)
            initializePorts(resetPorts)
            out.write("[common]\r\n".toByteArray())
            out.write("server_addr = ${server.IP}\r\n".toByteArray())
            out.write("server_port = ${server.port}\r\n".toByteArray())
            out.write("token = ${server.token}\r\n".toByteArray())
            out.write("log_file = ${logFile.absolutePath}\r\n".toByteArray())
            out.write("log_level = info\r\n".toByteArray())
            out.write("log_max_days = 3\r\n".toByteArray())
            out.write("pool_count = 5\r\n".toByteArray())
            out.write("tcp_mux = true\r\n".toByteArray())
            out.write("login_fail_exit = true\r\n".toByteArray())
            out.write("protocol = tcp\r\n".toByteArray())
            out.write("[api_$mRandomPortWeb]\r\n".toByteArray())
            out.write("type=tcp\r\n".toByteArray())
            out.write("local_ip = 0.0.0.0\r\n".toByteArray())
            out.write("local_port = 8080\r\n".toByteArray())
            out.write("remote_port = $mRandomPortWeb\r\n".toByteArray())
            out.write("[android_http_proxy_$mRandomPortHttp]\r\n".toByteArray())
            out.write("type=tcp\r\n".toByteArray())
            out.write("remote_port=$mRandomPortHttp\r\n".toByteArray())
            out.write("plugin=http_proxy\r\n".toByteArray())
            out.write("plugin_http_user=$proxyUser\r\n".toByteArray())
            out.write("plugin_http_passwd=$proxyPassword\r\n".toByteArray())
            out.write("[android_socks_proxy_$mRandomPortSocks]\r\n".toByteArray())
            out.write("type=tcp\r\n".toByteArray())
            out.write("remote_port=$mRandomPortSocks\r\n".toByteArray())
            out.write("plugin=socks5\r\n".toByteArray())
            out.write("plugin_http_user=$proxyUser\r\n".toByteArray())
            out.write("plugin_http_passwd=$proxyPassword\r\n".toByteArray())
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                out?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
    private fun startConnection() {
        CoroutineScope(Dispatchers.IO).launch {
            Frpclib.touch()
            Frpclib.run(activity?.cacheDir.toString() + "/config.ini")
        }
    }
fernvenue commented 10 months ago

A huge difference between rathole and frp here is that rathole requires explicit definition of each service and port on both the server and client sides. So you need to read the README in detail, especially the section about the configuration file.

Additionally, I noticed that you are using the plugin feature of frp for proxying, which in rathole needs to be done through an additional proxy application because rathole does not interfere with application layer traffic.

By the way, you can find an explanation about communication security in this section.

Since this issue is not a bug report or feature request, I suggest you go discussions.

sam3961 commented 10 months ago

okay @fernvenue But it would be very helpful for me if we can get in touch directly to discuss this matter as i am in lot of rush to deliver this product.

Thanks.