Skip to content
/ rok Public

A minimal ngrok liked reverse proxy implemented in Rust for educational purpose.

Notifications You must be signed in to change notification settings

kw7oe/rok

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rok

A minimal ngrok implementation in Rust, for educational purpose. This work is largely based on rathole, especially the very first commit. You can read the DESIGN.md to learn how this is implemented at a high level. Other honorable references are stated there.

This is by no mean an idiomatic or correct Rust implementation. I am learning Rust and fairly new to writing networking code with tokio.

Quick Start

There are two components in rok:

  • src/server.rs: the server consists of two part, the control server and the proxy server.
    • The control server take in request from the clients, assign domain name and setup proxy server for each clients.
    • The proxy server will receive requests through the provided domain name and proxy it to the client. running locally in the user machine.
  • src/client.rs: the client receive the requests from the internet through the server, and further proxy it to the web server running locally by the user.

Setting Up

So in order to see this code in action, you'll have to run 3 service:

Running the server

The server binary expect the domains to be provided. These are the domains that users from the internet will send requests to. Since we are running locally, we could mock those domains and have it work locally by manually editing our hosts file at /etc/hosts. Hence, this would only work in your local machine

# /etc/hosts

127.0.0.1 a.domain.com
127.0.0.1 b.domain.com
127.0.0.1 c.domain.com

Then, we can pass these to the server and run it:

RUST_LOG=info cargo run --bin server -- --domains a.domain.com --domains b.domain.com --domains c.domain.com

By default, the server start at port 3001.

Jul 15 21:10:13.896  INFO server: Listening on TCP: 0.0.0.0:3001

You could customize it by passing it into --port.

Running the client

The client, on the other hand, only required the --domain-name to be passed in, which is the domain/IP for your rok server above:

# Since we are running our server locally, we can just pass in 127.0.0.1
cargo run --bin client -- --domain-name 127.0.0.1

Similarly, by default, it assumed the rok server is start at port 3001 and can be customize by passing the value at --port. You shall see the following output once it start successfully:

tunnel up!
Host: c.domain.com

On the rok server side, you will see the following logs:

Jul 15 21:29:39.131  INFO server: Accpeting new client...
Jul 15 21:29:39.131  INFO server: Accpeting new client...
Jul 15 21:29:39.132  INFO server: Listening to 0.0.0.0:3004

This mean that the rok server has spin up another server at port 3004 to proxy the requsts for the above client.

Running a web server

The last piece of it is a working webserver running locally at port 4000. (Yes, it is currently hardcoded at port 4000...).

Playing around with it

Once you have the above servers running, you can now curl the provided domain on the client output and see your requests going through the proxy:

# The reason we are hitting port 3004, is because the `rok` server
# spin up the proxy server at port 3004.
curl http://c.domain.com:3004

You'll now see the rok client show some information about the request we just send:

GET /                9.973482ms      200 OK

That's all. Hope you enjoy it. Once again, these only works locally.

If you wish to see it work deploy somewhere to the cloud, let me know. If it gain enough traction, it's definitely a future work I would like to work on.

About

A minimal ngrok liked reverse proxy implemented in Rust for educational purpose.

Resources

Stars

Watchers

Forks

Languages