Outils pour utilisateurs

Outils du site


server:minecraft

Installation et configuration d'un serveur Minecraft sous Linux

Avant-propos

Mettre en place un serveur Minecraft (Vanilla) n'a rien de compliqué en soi : télécharger le JAR, l'exécuter et jouer. Cependant, la plupart des tutoriels que l'on trouve à ce sujet sont parcellaires et négligent bien souvent des points pourtant cruciaux (du moins pour moi), comme la sécurité.

Ainsi, l'objectif de cette page est de mettre en place un serveur Minecraft privé sur une machine Linux sans interface graphique en respectant les contraintes suivantes :

  • Sécurité
    • Utilisateur dédié et non-root (pour limiter les accès et les dégâts possibles en cas de compromission du serveur)
    • Configurations adaptées
    • Utilisation d'une liste blanche pour définir les joueurs autorisés
    • Ouverture du port dans le pare-feu/iptables
  • Fiabilité
    • Sauvegardes régulières (quotidiennes)
    • Arrêt propre du serveur (pas de kill -9 sauvages…)
    • Utilisation des mécanismes natifs de l'OS (systemd, cron…)
  • Autonomie (“fire and forget”)
    • Lancement automatique au démarrage (service)
    • Fonctionnement en arrière-plan (screen)
    • Accès distant par SSH pour maintenance
  • Performances
    • La meilleure fluidité possible pour accueillir environ 2-5 utilisateurs simultanés (mais aura de la marge pour en accueillir plus ;-))

En résumé, je souhaite que le serveur Minecraft soit capable d'accueillir entre 2 et 5 personnes dans les meilleures conditions possibles, tout en épargnant les ressources de la machine (partagées avec d'autres services) et sans en négliger les aspects liés à la sécurité.

Pour ce faire, je me suis inspiré de plusieurs sources, principalement le projet https://github.com/TheRemote/RaspberryPiMinecraft/ (documenté dans cet article).

Situation initiale

Voici les caractéristiques de la machine :

CPU Intel Core i3-4160 CPU @ 3.60GHz
Architecture x86-64
RAM 8 Go
OS Debian 9 (stretch), 64-bit
Disque HDD Western Digital Black, 640 Go
Réseau Gigabit Ethernet, IP statique

À noter que cette machine héberge d'autres services, donc l'objectif n'est pas d'assigner toute la RAM au seul serveur Minecraft ;-)

En outre :

  • iptables est configuré pour n'autoriser que les seuls ports nécessaires en entrée.
  • SSH est activé et l'utilisateur root est interdit de connexion.
  • ddclient est le client DNS dynamique utilisé afin qu'un (sous-)domaine pointe sur mon IP publique.

En savoir plus sur l'environnement configuré : https://wiki.vuilleumier.tv/doku.php?id=server:installation

Installation des dépendances

Pour commencer, nous installons les dépendances requises pour faire tourner Minecraft en arrière-plan :

sudo apt update
sudo apt install screen wget -y
sudo apt install net-tools -y

Installation de Java

Sans surprise, Minecraft Java Edition ne pourrait pas tourner sans la présence de Java ;-)

Nous choisissons ici la variante open-source OpenJDK prévue pour les systèmes d'exploitation sans interface graphique (headless). Il est recommandé d'utiliser la version 11 (LTS) au minimum, car elle offre de meilleures performances notamment grâce à son ramasse-miettes G1GC.

Malheureusement, cette version n'est pas disponible nativement dans les dépôts de Debian 9, alors il nous faut ajouter le dépôt officiel stretch-backports.

Pour ce faire, éditer le fichier sources.list :

sudo nano /etc/apt/sources.list

Et y ajouter la ligne :

deb http://deb.debian.org/debian stretch-backports main

Maintenant, nous pouvons installer Java 11 :

sudo apt install openjdk-11-jdk-headless

Si une autre version de Java était déjà installée, vous pourriez avoir besoin de changer la version utilisée par défaut :

sudo update-alternatives --config java

Cette commande permet de vérifier la version de Java actuellement utilisée :

java --version

ou (en Java 8)

java -version

Création du compte utilisateur

Pour des raisons évidentes de sécurité, nous n'allons pas faire tourner le processus serveur avec le compte root ni un compte possédant les pouvoirs su, mais un utilisateur créé spécialement pour cette occasion. Ainsi, si le serveur est compromis et qu'un attaquant arrive à exécuter des commandes, ses actions seront limitées aux seuls droits et fichiers de ce compte.

Pour commencer, nous créons l'utilisateur minecraft (vous êtes libre de l'appeler mcs, mcadmin ou ce que vous voulez) :

sudo adduser minecraft

Comme ce compte sera accessible par SSH, un mot de passe (fort !) doit absolument être défini (on peut laisser les autres informations vides).

Le répertoire utilisateur /home/minecraft et le groupe minecraft sont automatiquement créés.

Configuration de SSH

Le système d'exploitation hébergeant le serveur étant dépourvu d'interface graphique, il est indispensable d'autoriser l'utilisateur minecraft à se connecter en SSH. De plus, cela permet une gestion distante, ce qui est souhaité.

Pour cela, nous devons éditer le fichier /etc/ssh/sshd_config et y ajouter minecraft à la ligne AllowUsers. Par exemple :

AllowUsers admin minecraft

Pour terminer, redémarrer le service SSH pour prendre en compte la modification :

sudo service ssh restart

Téléchargement du serveur Minecraft

Il nous faut à présent télécharger le JAR (fichier exécutable Java) du serveur Minecraft et le placer dans le répertoire désiré. Pour ma part, j'ai choisi que ce serait le répertoire home de minecraft, alors on commence par se placer dans celui-ci :

cd /home/minecraft

Notez que j'ai décidé de continuer de travailler avec le compte admin pour le moment en agissant en tant que minecraft (avec sudo -u minecraft).

Premièrement, il est nécessaire de connaître l'URL de téléchargement de la dernière version du serveur Minecraft (1.16.3, à l'heure où j'écris) en vous rendant à ce lien : https://www.minecraft.net/fr-fr/download/server/

En l'occurrence, nous constatons que l'URL est https://launcher.mojang.com/v1/objects/f02f4473dbf152c23d7d484952121db0b36698cb/server.jar alors nous le téléchargeons :

sudo -u minecraft wget -O server.jar https://launcher.mojang.com/v1/objects/f02f4473dbf152c23d7d484952121db0b36698cb/server.jar

Lançons le serveur Minecraft une première fois afin qu'il crée sa structure et ses fichiers de base :

sudo -u minecraft java -jar -Xms400M -Xmx2G server.jar

Le serveur se termine de lui-même, prévenant que nous devons accepter les conditions d'utilisation (EULA), ce que nous faisons :

sudo -u minecraft nano eula.txt
eula=true

Configuration du serveur (server.properties)

La configuration du serveur Minecraft se fait par le fichier server.properties, créé automatiquement au lancement. La documentation est trouvable à cette adresse.

Les valeurs par défaut sont majoritairement adaptées, moyennant les personnalisations usuelles (motd, difficulté, mode de jeu…), laissées à la libre appréciation de chacun.

Toutefois, certains paramètres “avancés” doivent être changés pour correspondre aux exigences précédemment décrites :

op-permission-level=3

Par défaut, la valeur est à 4, ce qui signifie que les opérateurs (ops) peuvent utiliser toutes les commandes du serveur, y compris /stop, /save-all, /save-on et /save-off. Ce n'est pas désirable dans notre cas de figure, car seul l'administrateur doit être capable d'arrêter le serveur (avec les mécanismes mis en place dans cette procédure).

white-list=true

Nous souhaitons restreindre l'accès du serveur aux seuls joueurs autorisés, alors une liste blanche est utilisée (les utilisateurs seront ajoutés à une étape ultérieure).

snooper-enabled=false

Facultatif. Désactive le “snooping”, l'envoi de données de télémétrie du serveur à Mojang/Microsoft.

Mise en place des scripts

Nous allons à présent créer les scripts de démarrage et d'arrêt du serveur Minecraft ainsi que son service (systemd) associé, afin qu'il se lance automatiquement au démarrage de la machine.

Avant tout, connectons-nous avec l'utilisateur minecraft :

su - minecraft

Script de démarrage

Ce script sauvegarde les fichiers du serveur (dans le sous-répertoire backups), puis le démarre avec les bons flags (inspirés de cet article de référence). Un test s'assure au préalable que le serveur n'est pas déjà en cours de fonctionnement.

Le serveur est démarré en arrière-plan avec screen dans un écran nommé mcs.

Nous allons donc créer le fichier start.sh à la racine du dossier du serveur :

start.sh
#!/bin/bash
# Minecraft Server startup script using screen
 
# Check if server is already running
if screen -list | grep -q "mcs"; then
    echo "Server is already running!  Type screen -r mcs to open the console"
    exit 1
fi
 
# Switch to server directory
cd /home/minecraft/
 
# Back up server
if [ -d "world" ]; then 
    echo "Backing up server (to minecraft/backups folder)"
    tar --exclude='backups' --exclude='logs' --exclude='server.jar' -pzcf backups/$(date +%Y.%m.%d.%H.%M.%S).tar.gz *
fi
 
echo "Starting Minecraft server.  To view window type screen -r mcs."
echo "To minimize the window and let the server run in the background, press Ctrl+A then Ctrl+D"
screen -dmS mcs java -Xms1G -Xmx3G -XX:+ParallelRefProcEnabled -XX:+DisableExplicitGC -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=30 -XX:G1HeapRegionSize=8M -XX:+PerfDisableSharedMem -jar /home/minecraft/server.jar nogui

Adaptez Xms et Xmx en fonction de la quantité de mémoire vive que vous souhaitez assigner au serveur Minecraft et selon les caractéristiques matérielles de votre machine !

On doit attribuer au script les droits d'exécution :

chmod +x start.sh

Script d'arrêt

Adapté de ce script, il permet d'arrêter le serveur proprement (en y envoyant la commande stop). Cet arrêt est annoncé 30 secondes avant aux joueurs par le canal de discussions.

Nous allons créer le fichier stop.sh dans le dossier du serveur :

stop.sh
#!/bin/bash
# James Chambers - March 2nd 2019
# Minecraft Server stop script - primarily called by minecraft service but can be ran manually
 
# Check if server is running
if ! screen -list | grep -q "mcs"; then
  echo "Server is not currently running!"
  exit 1
fi
 
# Stop the server
#if [ "$1" == "announce" ]; then
  echo "Sending stop notifications to server..."
  screen -Rd mcs -X stuff "say Server is stopping in 30 seconds! $(printf '\r')"
  sleep 23s
  screen -Rd mcs -X stuff "say Server is stopping in 7 seconds! $(printf '\r')"
  sleep 1s
  screen -Rd mcs -X stuff "say Server is stopping in 6 seconds! $(printf '\r')"
  sleep 1s
  screen -Rd mcs -X stuff "say Server is stopping in 5 seconds! $(printf '\r')"
  sleep 1s
  screen -Rd mcs -X stuff "say Server is stopping in 4 seconds! $(printf '\r')"
  sleep 1s
  screen -Rd mcs -X stuff "say Server is stopping in 3 seconds! $(printf '\r')"
  sleep 1s
  screen -Rd mcs -X stuff "say Server is stopping in 2 seconds! $(printf '\r')"
  sleep 1s
  screen -Rd mcs -X stuff "say Server is stopping in 1 second! $(printf '\r')"
  sleep 1s
#fi
 
echo "Stopping Minecraft server ..."
screen -Rd mcs -X stuff "say Closing server (stop.sh called)...$(printf '\r')"
screen -Rd mcs -X stuff "stop$(printf '\r')"
 
# Wait up to 30 seconds for server to close
StopChecks=0
while [ $StopChecks -lt 30 ]; do
  if ! screen -list | grep -q "mcs"; then
    break
  fi
  sleep 1;
  StopChecks=$((StopChecks+1))
done
 
# Force quit if server is still open
if screen -list | grep -q "mcs"; then
  echo "Minecraft server still hasn't closed after 30 seconds, closing screen manually"
  screen -S mcs -X quit
fi
 
echo "Minecraft server stopped."
 
# Sync all filesystem changes out of temporary RAM
sync

Ne pas oublier une fois encore de lui attribuer les droits d'exécution :

chmod +x stop.sh

Se déconnecter de l'utilisateur minecraft avec

logout

Création du service

À ce stade, il est déjà possible de démarrer et d'arrêter le serveur avec les scripts que nous venons de créer. Seulement, nous souhaitons que celui-ci se lance automatiquement au démarrage de la machine, raison pour laquelle un service systemd est mis en place.

Il est nécessaire d'être connecté avec un compte possédant les droits administrateur (su) à cette étape.

Nous allons tout d'abord créer le fichier /etc/systemd/system/minecraft.service :

minecraft.service
[Unit]
Description=minecraft server service
After=network-online.target
 
[Service]
User=minecraft
WorkingDirectory=/home/minecraft
ProtectSystem=full
Type=forking
ExecStart=/bin/bash /home/minecraft/start.sh
ExecStop=/bin/bash /home/minecraft/stop.sh
GuessMainPID=no
TimeoutStartSec=600
 
[Install]
WantedBy=multi-user.target

Ne pas oublier de changer User et les chemins WorkingDirectory, ExecStart et ExecStop en conséquence si vous un autre utilisateur ou un autre répertoire racine ont été choisis.

Comme les scripts, ce fichier doit avoir les droits d'exécution :

sudo chmod +x minecraft.service

Nous activons à présent le service afin qu'il puisse démarrer automatiquement :

sudo systemctl enable minecraft.service

Nous démarrons le service (ce qui lancera le serveur) :

sudo systemctl start minecraft.service

Finalement, nous planifions le redémarrage du serveur tous les jours à 4 heures du matin (sauvegarde quotidienne) :

sudo crontab -e
0 4 * * * /bin/systemctl restart minecraft.service

Ouverture du port

Le serveur est démarré, le service opérationnel, il ne reste plus qu'à ouvrir le bon port (25565) dans le “pare-feu” (ici, iptables). C'est bien entendu facultatif si vous n'en possédez pas.

Nous allons par conséquent éditer le fichier /etc/iptables/rules.v4 afin d'y ajouter la ligne suivante :

# Accept Minecraft Server
-A INPUT -p tcp -m tcp --dport 25565 -j ACCEPT

Configuration de la liste blanche et des opérateurs

À ce stade, le serveur est prêt et fonctionnel. Il ne reste plus qu'à ajouter les joueurs autorisés à la liste blanche et définir qui est opérateur (op).

On se connecte tout d'abord à la console du serveur depuis le compte minecraft :

screen -r mcs

Ensuite, on autorise les joueurs player1 et player2 (les pseudos renseignés doivent exister) :

whitelist add player1 player2

Et on ajoute toto aux opérateurs (ils sont automatiquement en liste blanche) :

op toto

Pour finir, on utilise la combinaison de touches Ctrl+A et Ctrl+D pour réduire la console (ne surtout pas la fermer, sinon le serveur sera arrêté !).


Erreurs et solutions

Voici quelques erreurs que j'ai rencontrées et leurs solutions.

Échec de connexion au serveur (authentification impossible)

À la connexion au serveur, certains utilisateurs rencontraient l'erreur “Minecraft server authentication servers are down. please try again later sorry”.

La solution consiste à mettre à jour la liste des certificats Java du serveur à l'aide de ces deux commandes :

sudo dpkg --purge --force-depends ca-certificates-java
sudo apt install ca-certificates-java

Source : https://www.reddit.com/r/Minecraft/comments/8fpy67/failure_to_connect_to_authentication_servers_on/


Améliorations possibles

  • Utilisation du serveur PaperMC (plus fluide, compatible avec les mods Spigot et Bukkit)
  • Activation de rcon pour la gestion du serveur à distance

Commandes utiles

Se connecter à la console du serveur

Depuis le compte minecraft :

minecraft$ screen -r mcs

Puis Ctrl+A et Ctrl+D pour réduire la fenêtre (ne surtout pas la fermer, sinon le serveur sera arrêté !).

Démarrer le serveur

admin$ sudo systemctl start minecraft.service

Arrêter le serveur

admin$ sudo systemctl stop minecraft.service

Rappel : il faut compter au minimum 30 secondes pour son arrêt complet.

Mettre à jour le serveur (server.jar)

Se connecter à l'utilisateur minecraft depuis un autre compte

admin$ su - minecraft

Lister les écrans screen

minecraft$ screen -list
server/minecraft.txt · Dernière modification : 2021/12/12 18:06 de kevin