Self-hosting zrok (on Windows) without a public IPv4?

Greetings, everyone.

I wrote quite the novel here, so TL;DR:
Can you self-host zrok on Windows 11? Can this self-hosted zrok instance be used without the host having a public IPv4, like zrok-as-a-service can? Is there a guide anywhere that would be more specific to our use-case? And if it it isn't possible, what would be the cheapest and most accessible way to utilize a self-hosted zrok instance for our purpose?

Before I begin, I must clarify that my technical knowledge about the way zrok works is very limited. I became interested in zrok as a way to play Minecraft with a few friends first and foremost. Feel free to correct me if my statements are incorrect or nonsensical.

My friend (who will be referred to as "Host" from now on) and I are using zrok to play Minecraft together. Host has the Minecraft server and a zrok environment running on the same Windows 11 machine that Host uses to play Minecraft. We are currently using zrok-as-a-service, i.e. our environments use the default apiEndpoint api.zrok.io. This works for the most part, but we would like to switch to self-hosting zrok on Host's computer for better ping and to avoid being bandwidth-limited by zrok.io's free plan (I can't find the details of said free plan anywhere, by the way, but I'm going to assume there is a bandwidth limit).

The problem (and the reason Host didn't just use port-forwarding to let me connect) is that Host's ISP does not allow Host to have a public IPv4 (without paying quite a large fee). The self-hosting guide on zrok.io presupposes having a public IPv4, however. Is there still a way to host a zrok instance which I can access on Host's computer? And if not, what other method of using zrok to play on a Minecraft server running on Host's computer would you suggest?

Edit 1: (Meta question: Does this post belong in Support/General Questions or in the zrok category? I put it in zrok for now.)

Edit 2: I would also like to mention that we have access to a Linux VPS that does have a public IPv4. However, that VPS is much too weak to actually run the Minecraft server. Maybe it would somehow be possible to connect to the Minecraft server on Host's machine through the VPS using zrok? I would need some pointers on how to set that up though...

Thanks in advance,
cromakoth

Hi @cromakoth, welcome to the community and to zrok! (and OpenZiti)

Selfhosting zrok on windows -- I'm sure you can do it but I've personally not tried it yet. zrok is a go binary and one of the best things about go is that it compiles to any OS pretty easily. There's no guide to speak of about it just yet.

"THE" problem:

At the end of the day, the crux of your problem is going to be this:

Host's ISP does not allow Host to have a public IPv4

Without a static, known IP it will be quite tricky to get this to work. Impossible I think.

Is there still a way to host a zrok instance which I can access on Host's computer?

If Host is locked behind CGNAT, with no public IP -- I don't know of any way to solve the issue.

Meta Question 0:

(I can't find the details of said free plan anywhere, by the way, but I'm going to assume there is a bandwidth limit).

At the moment, it's a very very generous 10G / day... So you probably could away with using the SaaS entirely.

Meta Question 1:

you did great! :slight_smile: zrok is perfect

Meta Question 2:

You would host the openziti overlay network and zrok on that VPS and that would solve your problem, yes. You could TRY running the 'zrok access' on this VPS and exposing that port to the world if you want too... But then you're making an extra hop along the network and that seems like it wouldn't be ideal...

The other alternative is to run your own openziti overlay network, instead of zrok. It's a lot of the same but different since zrok is built on/around openziti... You could "only" host the openziti overlay on the VPS and then you'd both go through that. That's shown in this blog Set Up a Secure Multiplayer Minecraft Server

Let me know if that doesn't answer your questions. Cheers!

Thank you for the swift response.

That's actually quite high. We would definitely use that as our fallback option if I fail to set this up correctly.

So if I understand this correctly, I would follow this guide on my Linux VPS, then have all players change the apiEndpoint in their zrok environment to the one of the new zrok instance on the VPS. Then Host would create a private share which we could all individually access through the zrok installations on our own PCs, just like before, to connect to the Minecraft server running on Host's PC. Is that correct? I will try it that way now because it seems like the simplest and most efficient solution, but I will keep your other suggestions in mind in case it doesn't work out the way I just described.

Best regards!

You have it exactly correct. Yes.

I hope it's okay to continue posting in this thread instead of making a new one for the problems I'm running into trying to set up my zrok instance.

I installed and configured OpenZiti according to the guide and everything seemed to be in order. When it was time to bootstrap OpenZiti for zrok, I ran the command with my controller config file as instructed and got this output:

$ zrok admin bootstrap ~/Desktop/zrok/ctrl.yml 
[   0.002]    INFO main.(*adminBootstrap).run: {
	v              = 3
	admin          = {
		secrets          = <SECRET>
		tou_link         = ""
		profile_endpoint = ""
	}
	bridge         = <nil>
	endpoint       = {
		host = "0.0.0.0"
		port = 18080
	}
	email          = <nil>
	invites        = {
		invites_open   = true
		token_strategy = ""
		token_contact  = ""
	}
	limits         = {
		environments = -1
		shares       = -1
		bandwidth    = {
			per_account     = {
				period  = 24h0m0s
				warning = {
					rx    = -1
					tx    = -1
					total = -1
				}
				limit   = {
					rx    = -1
					tx    = -1
					total = -1
				}
			}
			per_environment = {
				period  = 24h0m0s
				warning = {
					rx    = -1
					tx    = -1
					total = -1
				}
				limit   = {
					rx    = -1
					tx    = -1
					total = -1
				}
			}
			per_share       = {
				period  = 24h0m0s
				warning = {
					rx    = -1
					tx    = -1
					total = -1
				}
				limit   = {
					rx    = -1
					tx    = -1
					total = -1
				}
			}
		}
		cycle        = 15m0s
		enforcing    = false
	}
	maintenance    = {
		reset_password = {
			expiration_timeout = 15m0s
			check_frequency    = 15m0s
			batch_limit        = 500
		}
		registration   = {
			expiration_timeout = 24h0m0s
			check_frequency    = 1h0m0s
			batch_limit        = 500
		}
	}
	metrics        = <nil>
	passwords      = {
		length                   = 8
		require_capital          = true
		require_numeric          = true
		require_special          = true
		valid_special_characters = "!@$&*_-., "#%!'(MISSING)()+/:;<=>?[\]^{|}~"
	}
	registration   = <nil>
	reset_password = <nil>
	store          = {
		path = <SECRET>
		type = "sqlite3"
	}
	ziti           = {
		api_endpoint = "https://127.0.0.1:8441"
		username     = "admin"
		password     = <SECRET>
	}
	tls            = <nil>
}
[   0.002]    INFO zrok/controller/store.Open: database connected
[   0.010]    INFO zrok/controller/store.(*Store).migrate: applied 0 migrations
[   0.010]    INFO zrok/controller.Bootstrap: connecting to the ziti edge management api
panic: error connecting to the ziti edge management api: Get "https://127.0.0.1:8441/.well-known/est/cacerts": dial tcp 127.0.0.1:8441: connect: connection refused
 
goroutine 1 [running]:
main.(*adminBootstrap).run(0xc000448ac0, 0x0?, {0xc000449610?, 0x0?, 0x0?})
	/home/runner/work/zrok/zrok/cmd/zrok/adminBootstrap.go:40 +0xf7
github.com/spf13/cobra.(*Command).execute(0xc000391800, {0xc0004495e0, 0x1, 0x1})
	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.8.0/command.go:987 +0xaa3
github.com/spf13/cobra.(*Command).ExecuteC(0x4ea0240)
	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.8.0/command.go:1115 +0x3ff
github.com/spf13/cobra.(*Command).Execute(...)
	/home/runner/go/pkg/mod/github.com/spf13/cobra@v1.8.0/command.go:1039
main.main()

    	/home/runner/work/zrok/zrok/cmd/zrok/main.go:99 +0x1a

The problem appears to be that zrok can't access port 8441, but I opened those ports for TCP in my firewall configuration, as the OpenZiti install guide suggested. Running ufw allow 8441/tcp confirms this, as it outputs "Skipping already existing rule". However, when I run ss -ltnp to check which ports are listening for connections, only 8442 (out of the 4 ports that OpenZiti uses) is displayed. Both the OpenZiti controller and router are running normally. What now? What else could be the problem?

Sure. :slight_smile: it's "close enough"...

Hmmmm. ufw is usually only half of the equation. the cloud vendor firewall needs to be open too. If you run ss -lntp and you don't see port 8441, either the controller didn't start for "reasons" or it's on a different port.

If you want to huddle somehow, we can arrange a time. I'd be happy to spend my 'off hours' DM'ing here on discourse (discourse has 'chat' features or some other way) to try to get you up and running.

Alright, I'm sending you a message.