Looking for alternatives to Argo Tunnel reddit / selfhosted ---------------------------------------------------------------------- CStfford14 · 2023-11-26 17:09 TL;DR: I'm making a game with 3 components and I need two of them to have a virtual network connection similar to Argo tunnel. It has to be something I can distribute and I have complete control over the network without port forwarding one of the components. I'm developing a game framework similar to Jackbox games. I already have a basic structure for how the game will work. It contains the following 3 parts: - Client - Player's devices - Proxy - A basic server to proxy traffic between the host and the clients - Host - The machine that actually runs the game I want to be able to distribute the host software to family and have it "just work," which is why I have the proxy server. The idea is that the host will connect to the proxy and provide the game through the proxy to the players. This begs the question, how am I going to pull this off? The proxy will have open ports, but in order to provide two- way communication between the proxy and the host, the host has to have exposed ports as well, right? I'll break it down this way for clarification. Let's say the host is a simple web server providing files for a website. The proxy is cloudflare. You can run the `cloudflared` program on the host to create an Argo tunnel, exposing your web server to cloudflare's network without port forwarding, which in turn forwards traffic onto the clients. That's the basic model I want to achieve, but I'm not sure how to make a system similar to an Argo tunnel since traffic needs to be proxied to a server I control rather than cloudflare's. I've done a bit of research and have narrowed potential solutions to the following 3 ideas: - Make a small OpenVPN server on the proxy server, distribute an OpenVPN client with the host that connects to the OpenVPN server on the proxy - Instead of OpenVPN use ZeroTier as a similar configuration (in this case, I would need to run the controller myself if possible) - Use websockets (This one I don't think would work since I don't think you can use websockets from within other websockets) ---------------------------------------------------------------------- jeffjose · 2023-11-26 22:32 I think you're over complicating things. Why cant you just do the connection over HTTP? If you use H3, you'd be building on top of UDP which would be much much faster than H1/H2 and you dont have to worry about opening up ports. In other words, Client, Host & Proxy communicate on 80 (unencrypted) or 443 (encrypted). ---------------------------------------------------------------------- jeffjose · 2023-11-26 22:39 I'll expand a bit incase if my reply isnt clear. **Proxy / Coordinator:** Runs on [coordinator.myjackbox.com](https://coordinator.myjackbox.com), and has a database backing the server. **Host / Game Host:** Runs on "family members", and when the game starts up, contacts [coordinator.myjackbox.com](https://coordinator.myjackbox.com) and registers itself with its IP and optionally a passpharse. **Client:** When started by gamers, contacts [coordinator.myjackbox.com](https://coordinator.myjackbox.com) and provides the correct passphrase, and it is provided with the IP of the game host. Client then proceeds to connect to Game Host. As you can see you're using regular ol' HTTP(s) for comms, and no need to open up and any ports. I dont see any advantage you get by having Game Host and Client be on the same "network". *Alternate:* If you dont want Game Host IP to be handed over to Client, then your Proxy / Coordinator will need to .. ahem, proxy.. the connections. So Client is always connected to Proxy ([coordinator.myjackbox.com](https://coordinator.myjackbox.com)) and it is the Proxy's responsibility to proxy that connection to Game Host. `[client] [proxy [game host]` ---------------------------------------------------------------------- CStfford14 · 2023-11-26 23:18 The particular way I'm setting things up may not work without exposing ports on the Host's system, and to avoid needing everyone on the same network, it would be best to have everything connect to the proxy server (hence the name) However, if those problems wouldn't be problems by connecting directly to the Host (even if on different networks), the only problem would be if I want to hide the host's IP from the clients. Considering my target audience is family, this is fine, but I am considering distribution to anyone that wants it, which could be problematic for people that don't want that information exposed. ---------------------------------------------------------------------- jeffjose · 2023-11-26 23:39 Can you describe what your usecase is for you to expose a non-standard port? By going down the non-standard port route, you have to build a protocol like TCP/UDP and even an HTTP yourself. If your goal is to build a game, I'd caution against going down that route. However, if your usecase is so unique that you \*have\* to invest in developing a proprietary protocol, go for it - but I highly doubt it. ---------------------------------------------------------------------- CStfford14 · 2023-11-26 23:45 So you're saying that if I offer my service over 80 or 443, it should work without port forwarding? I've always had to forward those ports, regardless of what I'm serving. ---------------------------------------------------------------------- CStfford14 · 2023-11-26 23:52 To explain specifically what's happening, the host will run a basic web server providing the game's pages (in either HTML/JS or PHP) to the client. The port doesn't matter here. The clients receive these game pages, display them, and send user input back to the host. My concern is even if the host is able to connect to the proxy, the clients won't be able to communicate with the host unless the host is proxied through the proxy or the host has ports 80 or 443 exposed. ---------------------------------------------------------------------- jeffjose · 2023-11-26 23:52 Choice of port & port forwarding are two different things. Using 80 doesnt mean you dont have to forward-port, and in the same way using 3843 doesnt mean you have to forward-port. Port, at the end of the day, is a synthetic concept to separate out packets reaching a computer. When a packet is headed for [1.2.3.4](https://1.2.3.4), you want the right program to consume it. If it is an SSH packet, it cannot be handled by `telnet`, but instead needs `sshd.` That's why packets have a IP+port combo. Packets headed for 80 are understood to be TCP or UDP packets. Whether a computer is accepting packets at all is what port-forwarding is meant to do. Most computers behind a router allows HTTP packets through. This still doesnt mean from the outside internet someone can reach your computer's port 80. ---------------------------------------------------------------------- CStfford14 · 2023-11-26 23:54 That's the point is so that port 80 can be reached from outside the network. Example: playing with friends over Discord. They would only be able to connect to the proxy, but not the host unless port 80 is forwarded, correct? ---------------------------------------------------------------------- jeffjose · 2023-11-26 23:54 Thanks for the details. I think you might have an incomplete understanding of computer networking. Here's the bottom-line. Make sure your proxy/coordination server is accessible from both host and client. This typically means port 80/443, communicating using HTTP packets. This is how most of the internet works. ---------------------------------------------------------------------- CStfford14 · 2023-11-26 23:56 I could do that- but like I said, ports 80 and 443 (this the host) are inaccessible from outside the host's network unless I port forward ---------------------------------------------------------------------- jeffjose · 2023-11-27 00:03 Not quite. Lets take an example of you going to [yahoo.com](https://yahoo.com), which is essentially your computer making a connection to [yahoo.com](https://yahoo.com) so that [yahoo.com](https://yahoo.com) can send you packets back. Your computer randomly picks a high port number to connect to [yahoo.com](https://yahoo.com)'s 80. This is easily demonstrable using telnet. %> telnet yahoo.com 80 Trying 74.6.231.20... Connected to yahoo.com. Escape character is '^]'. If I then look at connections from my computer, I see sudo ss -n | grep 74.6.231.20 tcp ESTAB 0 0 192.168.3.184:57918 74.6.231.20:80 As you can see, my computer is [192.168.3.184](https://192.168.3.184) and it is using port 57918 to connect to port 80 of yahoo.com ---------------------------------------------------------------------- CStfford14 · 2023-11-27 00:06 I see, and I think I understand networking a bit better now. I can send data to the proxy server from either the clients or the host, but how would the proxy know how to request or send data to the host? ---------------------------------------------------------------------- jeffjose · 2023-11-27 00:10 Smart question! As long as clients are initiating the request (web browser, telnet, your game host, your game client) it is all OK, because your original packet will tell [yahoo.com](https://yahoo.com) what IP + Port it should send the request to. (There's a small nuance here with router and NAT, but lets ignore that for now). Lets flip the story on the head. If I am running a webserver on my computer, I need to make sure requests from the outside world can come in, and that's where port-forwarding is important. If I have a webserver running on port 8000, I need to ensure that my router is accepting packets on port 80 (because that's what chrome/telnet is going to send packets to) and then your router needs to forward port 80 to port 8000 on my computer. To repeat, port-forwarding is only needed if the other party is initiating the request. It isnt needed when YOU make the request because of NAT (think of it as the router *automatically* forwards the packets to the port) ---------------------------------------------------------------------- CStfford14 · 2023-11-27 00:17 Ah! There's the thing- the other party (client or the proxy, depending on how I set things up) would be making the request, correct? The way I understand it is that the host is running a webserver and requests from the outside world need to find their way in. If I run the host directly on 80 or 443, can any random connection request what's being hosted on the webserver? It's absolutely true that if the host makes a request, it doesn't matter what ports are forwarded or not, since it's making the request. But what if the client is making the request? To give more information, the game pages have to be provided on port 80 or 443 so that a web browser can get them; that we've established. Now, to make sure I can understand what direction you're leading me, you're saying I can send packets from the clients or the host to the proxy, and vice versa, because both the host and the clients have already made connections with the proxy? ---------------------------------------------------------------------- jeffjose · 2023-11-27 00:18 Here's NAT in action, with the same example of me connecting to [yahoo.com](https://yahoo.com). ​ Screenshot of my NAT table - https://imgur.com/a/YtKWqU2 ​ * My computer picked a random high port (60704) to initiate connection to [yahoo.com](https://yahoo.com) port 80 * Since I'm behind my router, the router takes that packet and makes an entry in its NAT table ([192.168.3.184:60704](https://192.168.3.184:60704)) * Router then randomly selects another high port (14527) and initiates the actual connection to [yahoo.com](https://yahoo.com) port 80 * From yahoo's perspective, the incoming packet is from my public IP (redacted) and port 14527. * Yahoo's response would be headed for my public IP (redacted) port 14527 * My router receives the packet, and then sends that packet to [192.168.3.184](https://192.168.3.184) port 60704. ---------------------------------------------------------------------- jeffjose · 2023-11-27 00:23 The simplest architecture here would be to have the proxy server, proxy, the packets. A true middle man. Client connect to Proxy, Host connects to Proxy. And the most important bit, the Proxy never initiates the connection. Client and Host initiates the connection. \--- If that doesnt fit your needs, take a look at WebRTC ([https://en.wiki pedia.org/wiki/WebRTC](https://en.wikipedia.org/wiki/WebRTC)) And if you want to read more gory details of packets going back and forth, I highly recommend https://tailscale.com/blog/how-nat- traversal-works/ ---------------------------------------------------------------------- CStfford14 · 2023-11-27 00:28 Correct. So then without manually messing with the NAT table on each router that's running a host, how would the client request and send information to the host? Would it be through the proxy or directly to the host? I'm having trouble understanding the flow of information. Actually- Would I record the source IP and port on the proxy when the host connects and send that to all the clients? For instance, say yahoo is my proxy. The router picks a random high port (57202) when connecting to yahoo and keeps it open. Would all clients connect to the host's public IP address at that port? ---------------------------------------------------------------------- CStfford14 · 2023-11-27 00:34 Ok, this sounds a lot more like what I was going towards initially. Ignore my last comment since it's utterly wrong. Since they both are connecting to the proxy, I assume the proxy only has to match up incoming packets from the clients or the host and send them to the correct recipient. No need to have any particular software expose a port virtually (such as a VPN) running on the host since it is already directly connected to port 443 on the proxy server. Is that what you're indicating? ---------------------------------------------------------------------- jeffjose · 2023-11-27 00:43 Correct. And proxies are purpose built software to do just this. I'd start by looking at programmable proxies. A quick design might be something like providing a unique URL for each game host. Something like [proxy.jackbox.com/2dkdu3284](https://proxy.jackbox.com/2dkdu3284) for a particular host. Client and Host connects to that URL, and then the proxy passes packets back and forth. You dont then have to worry about cross-talk. ---------------------------------------------------------------------- jeffjose · 2023-11-27 00:45 You can also consider DERP server, which is what tailscale users as a fallback. https://tailscale.com/kb/1232/derp-servers/ ---------------------------------------------------------------------- CStfford14 · 2023-11-27 00:49 I was already planning on having unique addresses for each game anyway! This shouldn't be that hard to implement. I believe I can consider this solved. Thank you for your help and your patience! ---------------------------------------------------------------------- PhilipLGriffiths88 · 2023-11-27 17:38 You could use OpenZiti instead. This replaces OpenZiti/ZeroTier, implements strong zero trust principles for the highest security, and even allows you to embed the overlay directly into you game/app using an SDK. If you prefer to share publically, you can use zrok.io, [zrok.i](https://zrok.io)a Ngrok replacement for public sharing (incl. TCP/UDP tunnels) which is built on top of Ziti.