Ubuntu18.04 LTS でマインクラフトマルチプレイサーバーを立てる


# はじめに
このドキュメントは Ubuntu18.04 にマインクラフトのマルチプレイができるサーバー(以下 マイクラサーバー)をインストールする手順をまとめたものです。

# おことわり
* 個人的なメモです。
* Linux技術者認定試験[LinuC](https://linuc.org/) の [Level1](https://linuc.org/linuc1/)程度のコマンド知識があればできると思います。

# 環境

```shell-session
~#
~# uname -a
Linux hty-mc01 4.15.0-1013-azure #13-Ubuntu SMP Thu May 24 14:42:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
~#
~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04 LTS
Release:        18.04
Codename:       bionic
~#
```

# インストール手順  

## Ubuntu18.04をインストールする  

## お好みで[初期セットアップ](https://qiita.com/hatayan1126/items/6264782ef7ea91ffc250)をしておく  

## 必要なパッケージをインストール

```shell-session
~#
~# apt install openjdk-8-jdk
~#
~#  java -version
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-0ubuntu0.18.04.1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)
~#
```

**注意1**
apt install default-jdk とすると java10 がインストールされるが、これだとマイクラサーバーは起動するものの、認証エラーで接続できない状態になります。
  
```shell-session:errorlog
[14:49:14] [User Authenticator #1/INFO]: Disconnecting com.mojang.authlib.GameProfile@3dd788ea[id=<null>,name=********,properties={},legacy=false] (/27.95.135.64:61787): Authentication servers are down. Please try again later, sorry!
[14:49:14] [User Authenticator #1/ERROR]: Couldn't verify username because servers are unavailable
[14:49:14] [Server thread/INFO]: com.mojang.authlib.GameProfile@3dd788ea[id=<null>,name=********,properties={},legacy=false] (/27.95.135.64:61787) lost connection: Authentication servers are down. Please try again later, sorry!
```
## マイクラサーバー専用ユーザーを作る  
マイクラサーバー専用ユーザーがsudoできるようにパスワードの設定とsudoグループへの追加をする。

```shell-session
~#
~# useradd -m -r minecraft
~#
~# passwd minecraft
新しい UNIX パスワードを入力してください:
新しい UNIX パスワードを再入力してください:
passwd: password updated successfully
~#
~# id minecraft
uid=999(minecraft) gid=999(minecraft) groups=999(minecraft)
~#
~# gpasswd -a minecraft sudo
~# id minecraft
uid=999(minecraft) gid=999(minecraft) groups=999(minecraft),27(sudo)
~#
~# su - minecraft
~$
~$ pwd
/home/minecraft
~$
~$
```

## マイクラサーバー用のディレクトリを作成する

```shell-session
~$ 
~$ mkdir minecraft_server
~$ cd minecraft_server/
~/minecraft_server$
~/minecraft_server$ pwd
/home/minecraft/minecraft_server
~/minecraft_server$
```

## ダウンロードする
[Minecraftのサイト](https://minecraft.net/ja-jp/download/server)からマイクラサーバーの本体をダウンロードする。(本記事の執筆時点でバージョンは1.13です)
ダウンロードしたら、のちのち混乱しないように名前を変更しておく。
古いバージョンがほしいときは[ここから](https://mcversions.net/)ダウンロードできる。

```shell-session
~/minecraft_server$
~/minecraft_server$ curl -LO https://launcher.mojang.com/mc/game/1.13/server/d0caafb8438ebd206f99930cfaecfa6c9a13dca0/server.jar
~/minecraft_server$
~/minecraft_server$ ls -l
合計 31888
-rw-rw-r-- 1 minecraft minecraft 32649675  7月 23 11:33 server.jar
~/minecraft_server$
~/minecraft_server$ mv server.jar minecraft_server.1.13.jar
~/minecraft_server$ ls -l
合計 31888
-rw-rw-r-- 1 minecraft minecraft 32649675  7月 23 11:33 minecraft_server.1.13.jar
~/minecraft_server$
```

## 一旦マイクラサーバーを起動する
初回だけは環境設定が不十分のためエラーで停止してしまうが、これでよい。

```shell-session
~$
~$ java -Xmx1024M -Xms1024M -jar minecraft_server.1.13.jar nogui
[02:40:52] [main/WARN]: Ambiguity between arguments [teleport, destination] and [teleport, targets] with inputs: [Player, 0123, @e, dd12be42-52a9-4a91-a8a1-11c01849e498]
[02:40:52] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[02:40:52] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, targets] with inputs: [0.1 -0.5 .9, 0 0 0]
[02:40:52] [main/WARN]: Ambiguity between arguments [teleport, targets] and [teleport, destination] with inputs: [Player, 0123, dd12be42-52a9-4a91-a8a1-11c01849e498]
[02:40:52] [main/WARN]: Ambiguity between arguments [teleport, targets, location] and [teleport, targets, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[02:40:52] [main/INFO]: Loaded 0 recipes
[02:40:52] [main/INFO]: Loaded 0 advancements
[02:40:52] [Server thread/INFO]: Starting minecraft server version 1.13
[02:40:52] [Server thread/INFO]: Loading properties
[02:40:52] [Server thread/WARN]: server.properties does not exist
[02:40:52] [Server thread/INFO]: Generating new properties file
[02:40:52] [Server thread/WARN]: Failed to load eula.txt
[02:40:52] [Server thread/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.
[02:40:52] [Server thread/INFO]: Stopping server
[02:40:52] [Server Shutdown Thread/INFO]: Stopping server
~/minecraft_server$
```

「eula.txt」「logs」「server.properties」が生成される

```shell-session
~/minecraft_server$
~/minecraft_server$ ls -l
合計 31900
-rw-rw-r-- 1 minecraft minecraft      181  7月 23 11:40 eula.txt
drwxrwxr-x 2 minecraft minecraft     4096  7月 23 11:40 logs
-rw-rw-r-- 1 minecraft minecraft 32649675  7月 23 11:33 minecraft_server.1.13.jar
-rw-rw-r-- 1 minecraft minecraft       59  7月 23 11:40 server.properties
~/minecraft_server$
~/minecraft_server$
```

## eula.txtの「eula=false」を「eula=true」にする

```shell-session
~/minecraft_server$
~/minecraft_server$ cat eula.txt
#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
#Mon Jul 23 02:40:52 UTC 2018
eula=false
~/minecraft_server$
~/minecraft_server$ sed -i 's/eula=false/eula=true/' eula.txt
~/minecraft_server$
~/minecraft_server$ cat eula.txt
#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
#Mon Jul 23 02:40:52 UTC 2018
eula=true
~/minecraft_server$
```

## もう一度起動させる
「Done (45.262s)! For help, type "help"」と表示されたら成功。
このままだとコマンドを実行したコンソールを閉じてしまうとマイクラサーバーも停止してしまうので、このあとの工程でバックグラウンドで動くようにしていく。

```shell-session
~/minecraft_server$
~/minecraft_server$  java -Xmx1024M -Xms1024M -jar minecraft_server.1.13.jar nogui
[02:45:16] [main/WARN]: Ambiguity between arguments [teleport, destination] and [teleport, targets] with inputs: [Player, 0123, @e, dd12be42-52a9-4a91-a8a1-11c01849e498]
[02:45:16] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[02:45:16] [main/WARN]: Ambiguity between arguments [teleport, location] and [teleport, targets] with inputs: [0.1 -0.5 .9, 0 0 0]
[02:45:16] [main/WARN]: Ambiguity between arguments [teleport, targets] and [teleport, destination] with inputs: [Player, 0123, dd12be42-52a9-4a91-a8a1-11c01849e498]
[02:45:16] [main/WARN]: Ambiguity between arguments [teleport, targets, location] and [teleport, targets, destination] with inputs: [0.1 -0.5 .9, 0 0 0]
[02:45:16] [main/INFO]: Loaded 0 recipes
[02:45:16] [main/INFO]: Loaded 0 advancements
[02:45:16] [Server thread/INFO]: Starting minecraft server version 1.13
[02:45:16] [Server thread/INFO]: Loading properties
[02:45:16] [Server thread/INFO]: Default game type: SURVIVAL
[02:45:16] [Server thread/INFO]: Generating keypair
[02:45:16] [Server thread/INFO]: Starting Minecraft server on *:25565
[02:45:17] [Server thread/INFO]: Using epoll channel type
[02:45:17] [Server thread/INFO]: Preparing level "world"
[02:45:17] [Server thread/INFO]: Found new data pack vanilla, loading it automatically
[02:45:17] [Server thread/INFO]: Reloading ResourceManager: Default
[02:45:18] [Server thread/INFO]: Loaded 524 recipes
[02:45:19] [Server thread/INFO]: Loaded 571 advancements
[02:45:34] [Server thread/INFO]: Preparing start region for level 0
[02:45:35] [Server thread/INFO]: Preparing spawn area: 0%
[02:45:36] [Server thread/INFO]: Preparing spawn area: 0%
　：
　：
[02:46:01] [Server thread/INFO]: Preparing spawn area: 96%
[02:46:02] [Server thread/INFO]: Preparing spawn area: 100%
[02:46:02] [Server thread/INFO]: Time elapsed: 28561 ms
[02:46:02] [Server thread/INFO]: Done (45.262s)! For help, type "help"
[02:46:05] [Server thread/WARN]: Can't keep up! Is the server overloaded? Running 2350ms or 47 ticks behind
help
[02:46:42] [Server thread/INFO]: /advancement (grant|revoke)
[02:46:42] [Server thread/INFO]: /ban <targets> [<reason>]
[02:46:42] [Server thread/INFO]: /ban-ip <target> [<reason>]
[02:46:42] [Server thread/INFO]: /banlist [ips|players]
[02:46:42] [Server thread/INFO]: /bossbar (add|get|list|remove|set)
[02:46:42] [Server thread/INFO]: /clear [<targets>]
[02:46:42] [Server thread/INFO]: /clone <begin> <end> <destination> [filtered|masked|replace]
[02:46:42] [Server thread/INFO]: /data (get|merge|remove)
[02:46:42] [Server thread/INFO]: /datapack (disable|enable|list)
[02:46:42] [Server thread/INFO]: /debug (start|stop)
[02:46:42] [Server thread/INFO]: /defaultgamemode (adventure|creative|spectator|survival)
[02:46:42] [Server thread/INFO]: /deop <targets>
[02:46:42] [Server thread/INFO]: /difficulty [easy|hard|normal|peaceful]
[02:46:42] [Server thread/INFO]: /effect (clear|give)
[02:46:42] [Server thread/INFO]: /enchant <targets> <enchantment> [<level>]
[02:46:42] [Server thread/INFO]: /execute (align|anchored|as|at|facing|if|in|positioned|rotated|run|store|unless)
[02:46:42] [Server thread/INFO]: /experience (add|query|set)
[02:46:42] [Server thread/INFO]: /fill <from> <to> <block> [destroy|hollow|keep|outline|replace]
[02:46:42] [Server thread/INFO]: /function <name>
[02:46:42] [Server thread/INFO]: /gamemode (adventure|creative|spectator|survival)
[02:46:42] [Server thread/INFO]: /gamerule (announceAdvancements|commandBlockOutput|disableElytraMovementCheck|doDaylightCycle|doEntityDrops|doFireTick|doLimitedCrafting|doMobLoot|doMobSpawning|doTileDrops|doWeatherCycle|keepInventory|logAdminCommands|maxCommandChainLength|maxEntityCramming|mobGriefing|naturalRegeneration|randomTickSpeed|reducedDebugInfo|sendCommandFeedback|showDeathMessages|spawnRadius|spectatorsGenerateChunks)
[02:46:42] [Server thread/INFO]: /give <targets> <item> [<count>]
[02:46:42] [Server thread/INFO]: /help [<command>]
[02:46:42] [Server thread/INFO]: /kick <targets> [<reason>]
[02:46:42] [Server thread/INFO]: /kill <targets>
[02:46:42] [Server thread/INFO]: /list [uuids]
[02:46:42] [Server thread/INFO]: /locate (Buried_Treasure|Desert_Pyramid|EndCity|Fortress|Igloo|Jungle_Pyramid|Mansion|Mineshaft|Monument|Ocean_Ruin|Shipwreck|Stronghold|Swamp_Hut|Village)
[02:46:42] [Server thread/INFO]: /me <action>
[02:46:42] [Server thread/INFO]: /msg <targets> <message>
[02:46:42] [Server thread/INFO]: /op <targets>
[02:46:42] [Server thread/INFO]: /pardon <targets>
[02:46:42] [Server thread/INFO]: /pardon-ip <target>
[02:46:42] [Server thread/INFO]: /particle <name> [<pos>]
[02:46:42] [Server thread/INFO]: /playsound <sound> (ambient|block|hostile|master|music|neutral|player|record|voice|weather)
[02:46:42] [Server thread/INFO]: /recipe (give|take)
[02:46:42] [Server thread/INFO]: /reload
[02:46:42] [Server thread/INFO]: /replaceitem (block|entity)
[02:46:42] [Server thread/INFO]: /save-all [flush]
[02:46:42] [Server thread/INFO]: /save-off
[02:46:42] [Server thread/INFO]: /save-on
[02:46:42] [Server thread/INFO]: /say <message>
[02:46:42] [Server thread/INFO]: /scoreboard (objectives|players)
[02:46:42] [Server thread/INFO]: /seed
[02:46:42] [Server thread/INFO]: /setblock <pos> <block> [destroy|keep|replace]
[02:46:42] [Server thread/INFO]: /setidletimeout <minutes>
[02:46:42] [Server thread/INFO]: /setworldspawn [<pos>]
[02:46:42] [Server thread/INFO]: /spawnpoint [<targets>]
[02:46:42] [Server thread/INFO]: /spreadplayers <center> <spreadDistance> <maxRange> <respectTeams> <targets>
[02:46:42] [Server thread/INFO]: /stop
[02:46:42] [Server thread/INFO]: /stopsound <targets> [*|ambient|block|hostile|master|music|neutral|player|record|voice|weather]
[02:46:42] [Server thread/INFO]: /summon <entity> [<pos>]
[02:46:42] [Server thread/INFO]: /tag <targets> (add|list|remove)
[02:46:42] [Server thread/INFO]: /team (add|empty|join|leave|list|modify|remove)
[02:46:42] [Server thread/INFO]: /teleport (<destination>|<location>|<targets>)
[02:46:42] [Server thread/INFO]: /tell -> msg
[02:46:42] [Server thread/INFO]: /tellraw <targets> <message>
[02:46:42] [Server thread/INFO]: /time (add|query|set)
[02:46:42] [Server thread/INFO]: /title <targets> (actionbar|clear|reset|subtitle|times|title)
[02:46:42] [Server thread/INFO]: /tp -> teleport
[02:46:42] [Server thread/INFO]: /trigger <objective> [add|set]
[02:46:42] [Server thread/INFO]: /w -> msg
[02:46:42] [Server thread/INFO]: /weather (clear|rain|thunder)
[02:46:42] [Server thread/INFO]: /whitelist (add|list|off|on|reload|remove)
[02:46:42] [Server thread/INFO]: /worldborder (add|center|damage|get|set|warning)
[02:46:42] [Server thread/INFO]: /xp -> experience
```

# バックグラウンドで実行できるように systemd に登録する
[@nownabeさんのQiita](https://qiita.com/nownabe/items/ca45bb4829d75460b31e)を参考にさせていただきました。

## スクリプトを作る

```shell-session
~/minecraft_server$
~/minecraft_server$ vi startup.sh
#!/bin/bash
/usr/bin/java -Xmx1024M -Xms1024M -jar /home/minecraft/minecraft_server/minecraft_server.1.13.jar nogui
~/minecraft_server$
~/minecraft_server$ chmod +x startup.sh
~/minecraft_server$
```

## ユニットファイルを作成する
 
```shell-session
~/minecraft_server$
~/minecraft_server$ sudo vi /etc/systemd/system/minecraft_server.service
[Unit]
Description=Minecraft Server
After=network-online.target
 
[Service]
ExecStart=/bin/bash /home/minecraft/minecraft_server/startup.sh
WorkingDirectory=/home/minecraft/minecraft_server
Restart=always
User=minecraft
Group=minecraft
 
[Install]
WantedBy=multi-user.target
~/minecraft_server$
```

## systemdに登録する

```shell-session
~/minecraft_server$
~/minecraft_server$ sudo systemctl daemon-reload
~/minecraft_server$
~/minecraft_server$ sudo systemctl enable minecraft_server
Created symlink /etc/systemd/system/multi-user.target.wants/minecraft_server.service → /etc/systemd/system/minecraft_server.service.
~/minecraft_server$
```

## マイクラサーバーをsystemd経由で起動する

```shell-session
~/minecraft_server$
~/minecraft_server$ sudo systemctl status minecraft_server
● minecraft_server.service - Minecraft Server
   Loaded: loaded (/etc/systemd/system/minecraft_server.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2018-07-23 12:28:25 JST; 4s ago
 Main PID: 49874 (bash)
    Tasks: 20 (limit: 9519)
   CGroup: /system.slice/minecraft_server.service
           tq49874 /bin/bash /home/minecraft/minecraft_server/startup.sh
           mq49875 /usr/bin/java -Xmx1024M -Xms1024M -jar /home/minecraft/minecraft_server/minecraft
 
 7月 23 12:28:25 hty-mc01 systemd[1]: Started Minecraft Server.
~/minecraft_server$
```

## マイクラサーバーのTCPポート(25565)が開いていれば起動完了

```shell-session
~/minecraft_server$
~/minecraft_server$ ss -ant | grep 25565
LISTEN   0         128                 0.0.0.0:25565            0.0.0.0:*
minecraft@hty-mc01:~$
minecraft@hty-mc01:~$ lsof -i:25565
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    49875 minecraft   20u  IPv4 133725      0t0  TCP *:25565 (LISTEN)
~/minecraft_server$
```

# マイクラサーバーの設定
* マイクラサーバーの設定ファイルは「server.properties」です。
    * 参考 https://minecraft.server-memo.net/server-properties/
    * 参考 https://blog.yukimomo.net/minecraft-server-properties/
* 荒らし対策に有効なホワイトリストは「whitelist.json」に書きます。
    * 参考 https://blog.yukimomo.net/minecraft-server-properties/
* 禁止リストは「banned-ips.json」とか「banned-players.json」に書きます。
* デフォルトのワールドは「world」というディレクトリに格納されています。

# おわりに
比較的簡単にマイクラサーバーを立てることができました。
MODを入れたりForgeを入れたりすればより楽しめると思います。

マイクラサーバーを楽しむための様々な設定やいわゆる「荒らし」への対策やLinuxサーバーへのセキュリティ対策も忘れてはいけません。

そのあたりの話題はまた別に機会にご紹介できればと思います。