Replacing ngrok with frp
Tags: tutorial, beginners
Published: 2021-03-21 17:03:28

**ngrok** is a popular tool used for tunneling to a local environment, e.g. accessing your computer's localhost from a mobile device.

As of now, **ngrok** is a free/paid service. The free service has limitations of 40 requests per minute and only one tunnel at a time. It also gives you a randomized subdomain on their servers. Like many services, it's great on the surface but not good enough to be practical with.

[**frp**](https://github.com/fatedier/frp) is an open source version of **ngrok**. More OSS of a similar variety can be found here: (https://github.com/anderspitman/awesome-tunneling).

### Let's get started

_Obviously, you must have your own server online somewhere; perhaps a Linode, DigitalOcean, or EC2._

For this tutorial, I'm going to assume you're running an Ubuntu environment on your server and a Mac environment on your dev machine.

#### Setup FRP on your server (Ubuntu)

Go to the Releases page of the **frp** repo: https://github.com/fatedier/frp/releases

Grab a compatible version for your system. In our case, that's the Linux AMD64 version. 

Let's pull that down and extract it:

    wget https://github.com/fatedier/frp/releases/download/v0.36.1/frp_0.36.1_linux_amd64.tar.gz
    tar vxf frp_0.36.1_linux_amd64 
    cd frp_0.36.1_linux_amd64

There are several files here. You should be concerned with frp**s**. FRPS = Server, FRPC = Client.

Edit the `frps.ini` file and add the lines:

    [common]
    bind_port = 7000
    vhost_http_port = 9888

The `vhost_http_port` is the port you'll use when accessing it remotely, like: `http://www.example.com:9888`

Now we can start the server. Do it manually or put it in a process manager, doesn't matter.

    ./frps -c ./frps.ini

And you'll see output like this:

    2021/03/21 16:52:18 [I] [root.go:108] frps uses config file: ./frps.ini
    2021/03/21 16:52:18 [I] [service.go:192] frps tcp listen on 0.0.0.0:7000
    2021/03/21 16:52:18 [I] [service.go:235] http service listen on 0.0.0.0:9888
    2021/03/21 16:52:18 [I] [root.go:209] frps started successfully


#### Setup FRP on your client (OS X)

Go to the Releases page of the **frp** repo again: https://github.com/fatedier/frp/releases

Grab a compatible version for your system. In our case, that's the Darwin AMD64 version. 

Let's pull that down and extract it:

    wget https://github.com/fatedier/frp/releases/download/v0.36.1/frp_0.36.1_darwin_amd64.tar.gz
    tar vxf frp_0.36.1_darwin_amd64 
    cd frp_0.36.1_darwin_amd64

Edit the `frpc.ini` file. Remember, the CLIENT not the server. `frpC`.

    [common]
    server_addr = *your server ip*
    server_port = 7000

    [web]
    type = http
    local_port = 8080
    custom_domains = www.yourservername.com

The `server_port` should match what we used above on in the `frps.ini`. The `local_port` should be wherever your code is; so it could be `80` if you're using OSX's built-in Apache, but sometimes it'll be `8080` or `8081` if you're using something like `http-server`, `npm run serve`, etc depending on your project.

Now we start the client tunnel similar to the server:

    ./frpc -c ./frpc.ini

And you'll see output like this:

    2021/03/21 12:57:19 [I] [service.go:304] [5fb3865334a6b46a] login to server success, get run id [5fb3865334a6b46a], server udp port [0]
    2021/03/21 12:57:19 [I] [proxy_manager.go:144] [5fb3865334a6b46a] proxy added: [web]
    2021/03/21 12:57:19 [I] [control.go:180] [5fb3865334a6b46a] [web] start proxy success


#### Visit your project

You should now be able to see your project online. Go to:

    http://www.yourservername.com:9888 

and it will be showing the contents of:

    http://localhost:8080 (or whatever port you chose)

Now you have full control of your own tunnel. Don't have to pay for ngrok, aren't bound by limitations port limitations or requests, and most importantly, all of your traffic goes through **your** servers.

### Further reading

ngrok and frp are capable of a lot more than this, so if you want to learn more, continue reading documentation on their repo. https://github.com/fatedier/frp