{"id":22261003,"url":"https://github.com/obaraelijah/ngok","last_synced_at":"2025-03-25T13:26:23.302Z","repository":{"id":236006736,"uuid":"791712066","full_name":"obaraelijah/ngok","owner":"obaraelijah","description":"A minimal ngrok like reverse proxy .","archived":false,"fork":false,"pushed_at":"2024-04-30T07:29:14.000Z","size":46,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-30T12:26:10.299Z","etag":null,"topics":["async-io","rust","tokio","tunnel"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/obaraelijah.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-25T08:18:08.000Z","updated_at":"2024-05-22T12:16:09.000Z","dependencies_parsed_at":"2024-12-03T09:11:13.271Z","dependency_job_id":null,"html_url":"https://github.com/obaraelijah/ngok","commit_stats":null,"previous_names":["obaraelijah/ngok"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obaraelijah%2Fngok","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obaraelijah%2Fngok/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obaraelijah%2Fngok/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obaraelijah%2Fngok/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/obaraelijah","download_url":"https://codeload.github.com/obaraelijah/ngok/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245469715,"owners_count":20620633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async-io","rust","tokio","tunnel"],"created_at":"2024-12-03T09:11:07.309Z","updated_at":"2025-03-25T13:26:23.268Z","avatar_url":"https://github.com/obaraelijah.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Ngok\n\nA minimal `ngrok` implementation in Rust, for educational purpose.\nThis work is largely based on [rathole][0], especially [the very first commit][1].\n_This is by no mean an idiomatic or correct Rust implementation. I am mastering\nRust and fairly new to writing networking code with `tokio`_.\n\n## Quick Start\n\nThere are two components in `ngok`:\n\n- `src/server.rs`: the server consists of two part, the control server and the proxy server.\n  - The control server take in request from the clients, assign domain name and setup proxy server\n  for each clients.\n  - The proxy server will receive requests through the provided domain name and proxy it to the client.\nrunning locally in the user machine.\n- `src/client.rs`: the client receive the requests from the internet through the server,\nand further proxy it to the web server running locally by the user.\n\n### Setting Up\n\nSo in order to see this code in action, you'll have to run 3 service:\n\n#### Running the server\n\nThe `server` binary expect the `domains` to be provided. These are the domains that\nusers from the internet will send requests to. Since we are running locally, we could\nmock those domains and have it work locally by manually editing our hosts file at\n`/etc/hosts`. Hence, this would only work in your local machine\n\n```\n# /etc/hosts\n\n127.0.0.1 a.domain.com\n127.0.0.1 b.domain.com\n127.0.0.1 c.domain.com\n```\nThen, we can pass these to the `server` and run it:\n\n```bash\nRUST_LOG=info cargo run --bin server -- --domains a.domain.com --domains b.domain.com --domains c.domain.com\n```\n\nBy default, the server start at port 3001.\n\n```\nApr 30 09:58:49.694  INFO server: Listening on TCP: 0.0.0.0:3001\n```\n\nYou could customize it by passing it into `--port`.\n\n#### Running the client\n\nThe client, on the other hand, only required the `--domain-name` to be passed in, which is the\ndomain/IP for your `ngok` server above:\n\n```bash\n# Since we are running our server locally, we can just pass in 127.0.0.1\ncargo run --bin client -- --domain-name 127.0.0.1\n```\n\nSimilarly, by default, it assumed the `ngok` server is start at port 3001 and can be customize\nby passing the value at `--port`. You shall see the following output once it start successfully:\n\n```\ntunnel up!\nHost: c.domain.com\n```\n\nOn the `ngok` server side, you will see the following logs:\n\n```\nApr 30 09:59:55.722  INFO server: Accepting new client...\nApr 30 09:59:55.723  INFO server: Accepting new client...\nApr 30 09:59:55.723  INFO server: Listening to 0.0.0.0:3004\nApr 30 10:02:08.773  INFO server: Accept incoming from visitor_rx\n```\nThis mean that the `ngok` server has spin up another server at port 3004 to proxy the requests for the above `client`.\n\n#### Running a web server\n\nThe last piece of it is a working webserver running locally at port 4000. _(Yes, it is currently\nhardcoded at port 4000...)_.\n\n### Playing around with it\n\nOnce you have the above servers running, you can now `curl` the provided domain on the client\noutput and see your requests going through the proxy:\n\n```\n# The reason we are hitting port 3004, is because the `ngok` server\n# spin up the proxy server at port 3004.\ncurl http://c.domain.com:3004\n```\n\nYou'll now see the `ngok` client show some information about\nthe request we just send:\n\n```\nGET /                7.973482ms      200 OK\n```\n\n\nThat's all. Hope you enjoy it. Once again, these only works locally.\n\nIf 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.\n\n\n[0]: https://github.com/rapiz1/rathole\n[1]: https://github.com/rapiz1/rathole/commit/8f3bf5c7c7109821d737a6a67a7fd51fdf3b0917","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobaraelijah%2Fngok","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobaraelijah%2Fngok","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobaraelijah%2Fngok/lists"}