Setting up a Modded Minecraft Java Server on Debian 12

Specifications of the Server

The exact machine I used was an ASUS ZenBook Flip 15 Q528. It originally had Windows 10 installed but I've wiped it in favor of Debian 12 for this personal project. The performance of the server was extraordinary since the laptop was more than enough to handle server requirements stated by Mojang. This documentation assumes that the installation of Debian 12 has already been set up and was successful. The particular preseed I used was in the following: preseed

In addition, the modloader the server will be created on is the curse forge modloader. This is the most popular and what mods that I'll include in this server need to run on. There are other modloaders like Fabric and Quilt that support different mods which may require further research to properly install.

Note that the installation will be done as if the server is headless, so strictly through the command-line. I'm sure it can be done with a GUI, but I want to avoid that for the many benefits the command-line provides. Therefore, this will require some proficiency with the Linux command-line. As always, make sure your installation has been updated and upgraded.

Installing the Server

The jar file used to install the modded server is different. This one is sourced from the official cursed forge team. The minecraft version is 1.19.2 and cursed forge modloader version is 43.3.0. The link to get this jar file is within the following:

https://maven.minecraftforge.net/net/minecraftforge/forge/1.19.2-43.3.0/forge-1.19.2-43.3.0-installer.jar

Similar to using wget on the vanilla link, we use wget tool to download the server.jar file from cursed forge. Assuming that you have a terminal open and its current directory is the home directory, simpy use the wget command to download the server.jar file directly from the url:

$ wget https://maven.minecraftforge.net/net/minecraftforge/forge/1.19.2-43.3.0/forge-1.19.2-43.3.0-installer.jar

This will download and place the forge-version-installer.jar file in our current directory.

The next step is to install Java onto our machine using the following command:

$ sudo apt install default-jre

After installing Java, we need to make a directory to store the server files, the name doesn't really matter but I'll name it minecraft_server:

$ mkdir minecraft_server

We can then use the mv command to place the server.jar file into the minecraft_server directory. Once this has been done enter the minecraft_server directory and execute the following command:

$ java -jar forge-1.19.2-43.3.0-installer.jar -installServer

This is different from the Vanilla server command because the installer.jar file actually creates a shell script that runs the modded server for us. This command only begins the installation process by building the modded server within the minecraft_server directory. Before we can officially start the server, we must agree to the End-user license agreement or EULA and set up a firewall to monitor our ports for our linux machine.

To agree to the EULA, we must edit the eula.txt file that is now present within the minecraft_server directory. Simply, use a command line text editor and change the eula value to eula=true.

The reason to set up a firewall is to allow the minecraft server process to communicate with the network by configuring a firewall, I used the firewalld package to configure this. This is to accept connections from outside the Local Area Network, or LAN, or your home network. If you do not plan to have outside connections, you can skip to the next section of starting the server and connecting through LAN. However, if you want online friends to join the server, then proceed.

First install firewalld if it's not installed, then set up the firewall with the following:

$ sudo apt install firewalld $ sudo firewall-cmd --zone=public --add-port=25565/tcp --permanent $ sudo firewall-cmd --zone=public --add-port=25565/udp --permanent $ sudo firewall-cmd --reload $ sudo firewall-cmd --list-ports

The first two opens the 25565 port for both internet protocols, since changes require the firewalld to restart we use the reload option on the command, and the last command lists the ports verifying that the reload worked.

Testing the Modded Server

Now that our server is primed to start we must test that the server runs without any mods. After that step, we'll be able to install any desired mods. First, ensure that the version of minecraft and modloader of cursed forge are the same as that of the server. In my case, I'll make sure my cursed forge client has minecraft version 1.19.2 and modloader 43.3.0. Another condition to consider is whether we have the same mods installed as the server, however, at this point there should be none, so we may continue.

We switch to the minecraft_server directory and run this command on the command line:

$ ./run.sh nogui

When we installed the minecraft cursed forge server jar file, it created a run.sh file, which will start the server for us and handles the mods. The nogui option is added to make sure our server runs without a gui. Before joining, the server we must locate the ip of the server.

You can get the ip of your device using the following:

$ ip a

Assuming you only have one network interface, you should look at the ipv4 address of the interface that is not the lo: or Loopback.

If you have multiple (more than 2), look into determining the main network interface by seeing which one is associated with the gateway ip. The exact commands are beyond the scope of this documentation, but that is a good question to research or google.

Now that we have our LAN ip, it should look relatively something like 192.168.1.x This is the IP of your server within the LAN. When adding a server in Minecraft through the multiplayer option, the name can be anything, but the ip must match what we found.

Note that this will only allow people within your home network to join the server. Which is perfect in my case since I want to join the server from a separate desktop system within my own house.

To extend the server to people outside your home network, continue to the next section.

Port Fowarding

While using the LAN network might be enough for most people, I want to play with friends that aren't always in my house and have their own computers at home. To achieve this, you have to set up something called port forwarding

Port forwarding allows connections from other computers on a specific port to be sent to the appropiate device that handles that connection. In this case, my laptop is the device that handles all connections for port 25565, the port for minecraft multiplayer connections. Normally, under LAN, the device is known to every other device on the network and thus no port fowarding is needed. However, since my friends' computers are outside my LAN network, I need to tell my router where to send their port 25565 connection requests, which is to my Laptop, the server.

Unfortunately, this cannot be done through the terminal and must be done through your service provider's router. However, here's the general process use the following command to obtain the gateway, or the router ip.

$ sudo route -n

We then enter this ip into a web browser, this will either give you a dashboard for configuring the router or more information on how to configure the router. In my case, it gave a QR code allowing me to download an app to configure my router from my phone. Once you find out how to set up port forwarding the general information you need is a name for the process, external port, internal port, and protocol. In some cases, you may need the local ip of the server itself, simply use the ip a command to get it.

For name, enter minecraft, anything works

For both external and internal ports, use 25565

For protocol, its best to use both TCP and UDP protocols.

Please refer to your service provider's method of configuring the router.

To check if the port forwarding has worked use the following site or similar sites: https://mcsrvstat.us/. If port forwarding has worked, the site should report that port 25565 is open on your public ip address. Simply searching What is my ip? on any web browser should immediately give you your public ip.

Once verified, to have friends join your server once port forwarding has been setup you simply need to provide them your public ip. When having them join, the address should look something like this ww.xx.yy.zz:25565 Obviously, the ww.xx.yy.zz should be replaced with your public ip.

Installing Mods

To install mods, we simply have to get the .jar files for each mod into our mods directory within the minecraft_server directory. Launching the server with run.sh will automatically load mods for us, so no further configuration is required.

You have two options of obtaining the .jar files through a headless server. First option is to download using the wget command or by having the files transerred to your server. What I'm going to do is use the second option by using the scp command to transfer files from my Windows Desktop to my Linux server.
You can use a USB Thumb Drive to achieve the same results or even find the download link to the mod jar file and use wget.

Remeber to have the mod jar files located within the mods directory. If you named the server directory minecraft_server then the full path of the mods directory should be the following:

/home/**user**/minecraft_server/mods/

Launch the server like before and test if the mods have been applied. Additionally, this process creates a config directory allowing us to configure each mod to our liking.

This process can be easy if we only have 1 or 2 mods to add, or if we're adding on mods, but it'll be tedious if our list of mods requires more than 10. However, the cursed forge client allows you to create groups of mods and export them, while the mod loader doesn't export the mods themselves, they definitely export files that are easily parsed and can be used to create an importing tool. While the one I made is primitive, it'll defintely be useful when importing a massive list of mods, like in my case where there's over 90 mods. Please check out the Automation section to get a greater understanding of the script.

import.sh

Porting Worlds

Before I started building this server, my friend and I already had a world that we created. So I expiremented with porting worlds since in Java Edition, all data related to a world is stored within a directory. The process that I'm about to describe works for both vanilla and modded servers.

The data of worlds are stored within a single directory. Therefore, to port a world we need to obtain the world directory. Find the location of your world folder and transfer it to the Linux server. This is accomplished either through the USB Thumb Drive method or the scp command I used ealier to transfer files to my Linux machine.

We want to make sure that this world directory is then renamed to a more generic name, this will not be seen by players so I'm going to name it new_world. We then place it within the minecraft_server directory and then edit the server.properties file.

We change the level-name property from its default name to the new directory we have transferred to the minecraft_server directory:

level-name: world ---> level-name: new_world

Starting the server will allow our server to use the new_world instead of the previously generated one.

Security

Important Security notes

  • Configure the firewall to improve security and disable any unwanted ports
  • Create a separate user for the server to run under, this is so the server is isolated, NEVER use sudo to start the server when difficulties are met
  • Be cautious when sharing public ip, only give this to those you trust, especially if your server is located at your household
  • Always backup your server
  • Within the minecraft_server directory, a whitelist file has been created, use it to block unwanted visitors and only accept trusted friends
  • Always double check that mods are safe to install, check if there are any known vulnerabilities within mods

Automation

The best part about doing this strictly through the terminal is being able to automate everystep. The only step we can't automate is the port forwarding part as that involves a separate interface entirely.

This script automatically installs java, adds the minecraft user, makes the server directory within the home directory of the minecraft user, gets the modded server.jar file, and makes a start.txt file that once given executable permissions can start building the modded server and be used to run the server afterwards.

In addition, this script installs the firewalld package, sets up the firewall ports, reloads the firewall, and lists the ports and status of firewalld. After starting the server with the start.txt, change the eula.txt file like before and start the server.

The password for the minecraft account is "vm", please change the password something more secure with the passwd command.

This script is my own primitive import tool that works with the Cursed Forge export tool. Cursed Forge has an option to export a list of mods which will make a zipped directory with a html and json file that can be parsed and used to quickly download the desired mods into our server.

First, the script searches the home directory for server-side.zip and unzips it to the mods directory. So when extracting we must make sure the file name is called server-side.zip.

Secondly, the html file is parsed to get the list of mods so we can name each jar file later.

Thirdly, it parses the json file to get the project and file IDs of every mod to build the download links for wget. Fortunately, the names of the mods and project IDs are ordered for us so all we have to do is apply a for loop to download the mod.

The for loop takes the index offset into account, then it builds the download link for the mod using the project and file IDs from the list created from the third step. Then it uses wget to place the downloaded mod into the mods directory. Afterwards it renames the file to the appropiate name using the parsed list of names from the second step.

Once the script is finished, it then cleans up by removing left over files such as the html and json files.

--