BohdanQQ

(Somewhat) Exotic Ways To Run A Minecraft Server

A tiny (bittersweet) writeup on my attempt to reuse my old phone to run a Java and a Bedrock server and the other time I tried to run a Minecraft server for crossplay with Nintendo Switch.

Background

A few months ago, I replaced my old and insecure OnePlus 7 with a new device. Naturally, I left my old device in a drawer and scouted for potential usage of the old phone.

Later, I discovered I could run a semi-functional Linux distro in Termux, my beloved app. As I don't care about the data on my old (wiped) device, using the AnLinux App to download and execute a random bash script in Termux does not seem like a big deal.

Running a Minecraft server

Thus, I tried running a Minecraft Java server on my phone, successfully! This came as no surprise to me because I've hosted an MC server multiple times in the past. I used to opt into the original or Fabric server. The JVM simply came in clutch this time because it spared me the hell that was about to come: architectural differences, emulation, and libraries.

Enter the Bedrock edition of Minecraft and its server! The reason you could contemplate running a Bedrock edition server might not be obvious (after all, you can run JVM on pretty much any platform) but it is significant: crossplay.

If you want to play with someone who uses a Switch (more on that later), iPad, or anything other than a PC or a Mac, you have to run a Bedrock server. The small issue is that Bedrock server binaries are only available for the x86_64 architecture. I honestly thought this was some error on the side of Microsoft - it isn't. They just do not support anything else. Mind you, ARM-based server CPUs do exist and you can even run cloud VMs on those so it is not unreasonable for such a popular game and such a large company to support such a widespread architecture target...

Luckily, there exists the box64 project that emulates x86_64 in userspace! Not so luckily, installing this project on the AnLinux's Fedora distribution omits the libgcc_s.so.1 library, resulting in errors when trying to launch the Bedrock server via box64 because the server depends on (among other libraries are properly copied onto the target system) this library.

I tried launching WSL and copying the library from there as I didn't know box64 included native libraries and did not emulate all of them. In hindsight, this was a stupid idea but I don't know much about libraries altogether and I probably should take a look into this matter sometime in the future. Anyway, after tens of minutes of searching, I found an issue/forum post that mentioned the box64's libraries were missing in some installations. I downloaded and moved box64's libgcc_s.so.1 to a designated folder and it worked! The server was running!

Connecting to a Minecraft server

There are several caveats when it comes to connecting to a Minecraft server. Some are general issues with exposing your device and/or ports to the Internet and some are device-specific. Let's take a look at the latter first.

Nintendo Switch

An innocent and game-changing device on the landscape of handheld consoles, no doubt. It is also, however, completely owned by Nintendo. No, I do not think you own the Switch if you paid for it. Think about it for a bit. You cannot install anything Nintendo does not approve and they patch their devices when a jailbreak is discovered. One could argue that customers are used to this behavior, especially people who "own" Apple's devices. What's more and directly related to our use case, though, Nintendo even controls how and if you play online.

Minecraft on Switch is no exception to this. First, (as far as I know) you have to pay a subscription to even be able to join any server. Second, only predefined servers are allowed for connection. Sure, this includes some notorious and popular servers, but it completely shatters any remaining feeling of freedom of choice. There is no choice, you pay for a restricted experience. In the case of Minecraft specifically, Nintendo (the beneficiary of your payment!) is not responsible for any server infrastructure when you play Minecraft online! They do not run the servers that the Minecraft multiplayer menu offers you, they collect the tax which allows you to merely click inside of that menu!  

So once you pay your subscription, despite running the Bedrock edition of the game, you cannot connect to any server of your choosing. The more knowledgable ones might have thought of this already, and some jailbreaks for the Switch also rely on this trick: you can just hijack the name resolving (assuming the IPs are not hard-coded, lol). You adjust your Switch'es DNS config to some either privately owned or a public instance of a modified DNS. You then click the Approved Server 1 in the multiplayer menu, which in turn resolves the adjusted approved.minecaft-server.address.xyz's IP that brings you (depending on your DNS server's config) either

  1. to a redirection server - a Bedrock server that hosts an empty world, immediately prompting you to enter the address of the server of your choosing and redirecting you to it (more on that later)
  2. or the target Bedrock server you want to connect to

Some repos that tackle this:

MC Server + DNS via Docker

MC Redirection Server with very useful README

IMPORTANT DISCLAIMERS:

Exposing the server

I experimented with exposing the phone from behind a NAT on a network, where I cannot control port forwarding. I achieved this via SSH port forwarding and as I keep forgetting how the port forwarding actually works in terms of the command syntax, I referred to this wonderful diagram.

I used the Gateway -> Client -> Local Server config from the bottom-left corner. It works... at least until you discover that this is the case only for the Java server. The Bedrock server uses UDP (Java server uses TCP) and UDP cannot be tunneled through the SSH port forwarding feature.

However, even if I could somehow tunnel the UDP connection (e.g. through a VPN), there appeared other issues along the way. I tried running the Bedrock server locally and connecting to it from my PC. Arguably, I should have tried this before even thinking about exposing the server to the internet, so how did I end up here?

Unverified Assumptions

To understand, I provide the exact order of my testing:

  1. I tried running the Java server on the phone and connecting to it via a mobile hotspot from my laptop
  2. That worked so I moved onto the tunneling part in order to verify that my idea is correct.
  3. It was! I started emulating the Bedrock server and I did not bother with the local connectin test because I blindly assumed everything would work out
  4. It did not..

And thus, I needlessly researched UDP tunneling. But hey, at least I learned that there is a solution to this problem - the SSF project! (it actually is an abandonware and I failed to compile it for arm64, just install Wireguard instead)

The Most Weird Problem...

Now, what was exactly happening, I have not discovered.

On the phone, I could clearly see that the PC has connected to the server. On the client side, however, I got this infinite "Locating server" loading message. The server was discoverable by the PC - the game showed its MOTD string as well as the player count as configured, somehow it just refused to connect!

As a sanity check, I tried running the Bedrock server on the same machine - successfully. According to various Reddit and MC Bugtracker posts/items, it seems there has been an issue regarding some invalid position of the player inside the world with the exact same on the client side. The problem seems unrelated for my usecase though, because even regenerating the world has not brought any results. I tried debugging and looking for a way to increase the server's log verbosity for a while and then I gave up.

While writing this up, I realised I have not tried to reuse one of the "working" server's worlds generated on my x86 machine. Definitely an idea to try following in the future! In the mean time:

Thanks, Microsoft. Both for not providing a native binary and for the server binary that does not even log in a verbose mode (at least not obviously - I'll gladly be corrected!) ...

Last update

7th August 2024