DEV Community

PrxPass - A reverse-proxy self-hosted solution (aka local tunnel)

I finally passed the burnout thing and started coding different things. I've had a need for a reverse-proxy server that works like ngrok or localtunnel but self-hosted (I know localtunnel IS self-hosted but it's in JavaScript...) so I wrote my own.

The idea is simple: you simply start the prxpass-server on your server, then on your local machine, you start the prxpass-client that connects to the server and proxies every request made to <your_id>.<hostname> to your local web application (e.g. localhost:4000).

So for example if you're working on a bot that uses webhooks (e.g. a Telegram bot), you can tell Telegram to send stuff to e.g. mysuperduperbot.prxpass.defman.me (you can set up custom IDs if the server instance allows that) and prxpass will proxy every request to e.g. localhost:9000. In your bot, you only have to listen for POST requests at localhost:9000 in that case and you can even setup a HTTPS once LetsEncrypt rolls out their wildcard certs.

There are other ways to use prxpass, for example if you want to give someone a live demo of your web app without uploading it to the server.

prxpass is not limited to HTTP but to TCP atm (planning to add UDP proxying in the future), so in idea you can proxypass anything that works over the TCP stack. I've not tested it though.

If you have any ideas how I can improve my program - feel free to write the idea in the comments or open an issue on GitHub. If you're interested in using it (it's alpha atm) - please tell me so I'd build the binaries for you. (I didn't bother to build anything but the windows client and the linux server).

Links:

Discussion (10)

Collapse
bernhardberger profile image
Bernhard Berger

I'm having more issues with prxpass..

My goal is to create a tunnel for a mysql-server running on docker (for local development purposes only). Idea:

local-dev-proxy (accessible through local.mydomain.tld -> 127.0.0.1):

  • traefik: 80,443
  • prxpass-server: 3306

compose_project_a:

  • web:80 -> traefik reverse proxy (http(s)://project-a.local.mydomain.tld)
  • db:3306 -> prxpass-server (tcp://project-a.local.mydomain.tld:3306)

compose_project_b:

  • web:80 -> traefik reverse proxy (http(s)://project-b.local.mydomain.tld)
  • db:3306 -> prxpass-server (tcp://project-b.local.mydomain.tld:3306)

By the documentation this is exactly the scenario that should be achievable with prxpass, I however have a few issues:

1) starting the server with app -tcp actually opens the HTTP config as written in config.toml (creates only an http tunnel)

2) I fire up the client with

app -server prxpass-server:<TCP_PORT> -proxy-to db:3306 -id db -password mysecret results in
a) "connection refused (as only the http tunnel configured on port 8000 is opened)"
and b) it completely ignores the part which would be vital in my case..

Any ideas on how I could achieve this?

Collapse
defman profile image
Sergey Kislyakov πŸ‡·πŸ‡Ί πŸ‡ΊπŸ‡Έ Author • Edited

TCP is not yet supported. I kinda don't understand your problem though. Are you running a MySQL server on your machine (127.0.0.1:3306) and you want to access it from the Internet at e.g. db.whatever.com? At least that's the idea of PrxPass - you expose your local stuff to the Internet via your public server. You can only achieve something like this:

lol

Collapse
bernhardberger profile image
Bernhard Berger

I'm running multiple docker projects on my host (each in a private closed network, e.g. 172.16.x.x) and I want to expose it through a tcp proxy on my local network (127.0.0.x) for convinience (external DB tools like DBeaver/HeidiSQL/Navicat) and mysql command line clients.

The *.local.domain.tld is just an A-Record pointing to 127.0.0.1..

I basically need a tcp reverse proxy solution that I can automate on environment start and stop.

I know HAproxy and nginx (to some extent) can handle TCP routing, but it's a massive overhead I'd like to avoid.

Thread Thread
defman profile image
Sergey Kislyakov πŸ‡·πŸ‡Ί πŸ‡ΊπŸ‡Έ Author

I've updated my reply. What you're trying to achieve is not the intended usage of PrxPass (at least at the moment). You want to expose your hosts docker network to your local network and I guess you can do that by setting up a VPN tunnel to your host.

Collapse
msoedov profile image
Alex Miasoiedov

What is the advantage comparing to traditional

ssh -D 8123  username@hostname

?

Collapse
defman profile image
Sergey Kislyakov πŸ‡·πŸ‡Ί πŸ‡ΊπŸ‡Έ Author • Edited

I've not used ssh in this way, so could you tell me how it works?

If I understand the man page correctly, this will give you a tunnel to the remote server, but an user won't be able to access you. PrxPass allows you to share localhost to public by creating a dial tunnel (client <-> server) with your remote server.

PrxPass works in this way:

  1. User requests <id>.example.com/hello.html
  2. The HTTP request (GET /hello.html) is being sent to the associated prxpass client.
  3. The prxpass client sends the HTTP request to localhost (GET /hello.html; Host: localhost) and waits for a response.
  4. The response is being sent back to the server.
  5. User sees localhost/hello.html.
Collapse
msoedov profile image
Alex Miasoiedov • Edited

It's a TCP proxy over ssh

jguru.com/faq/view.jsp?EID=227532

Thread Thread
defman profile image
Sergey Kislyakov πŸ‡·πŸ‡Ί πŸ‡ΊπŸ‡Έ Author

I don't see a way to route the traffic from a remote server from a specific domain (13.37.13.37, mylocaltunnel.mysite.com) to a local web server (e.g. localhost:8000). PrxPass is a reverse-proxy server, not a simple proxy server.

I'd be happy to see if it's possible to setup a ssh tunnel in this way.

Collapse
bernhardberger profile image
Bernhard Berger

..how do I build this thing? :) New to go..

Would love to pack this inside a docker container..

Collapse
defman profile image
Sergey Kislyakov πŸ‡·πŸ‡Ί πŸ‡ΊπŸ‡Έ Author

git clone the repo and run go build.