Minecraft + HAProxy で RTX830 の IP マスカレード機能のテストをしてみる

# はじめに
Minecraft サーバーを自宅の RTX830 配下において運用するためのテストをしました。
その記録です。

Minecraft は Java 版です。

# やること
0. 既存ルーターの下に RTX830 を配置して二重ルーター状態にする
0. RTX830 の外側に Minecraft クライアントとリバースプロキシを置く
0. RTX830 の内側に Minecraft サーバーを置く
0. RTX830 の IP マスカレード設定をする
0. Minecraft クライアントからサーバーへの接続テストを行う

# 環境
- リバースプロキシサーバー
    - Ubuntu 24.04
    - HAProxy (2.8.5-1ubuntu3.2 2024/12/02)
- Yamaha RTX830 (Rev15.02.03)

RTX830 の外側を `192.168.0.0/24`、内側を `192.168.100.0/24` として説明します。
また、使用するマシンの IP アドレスは以下に示す通りとします。
- HAProxy: 192.168.0.2
- Minecraft Client: 192.168.0.3
- RTX830:
    - 外側: 192.168.0.100
    - 内側: 192.168.100.1
- Minecraft Server: 192.168.100.100

# 準備(リバースプロキシサーバー)
HAProxy のインストールをします
テストにしか使わないので `apt install haproxy` で取得できるパッケージを使います。

---

HAProxy をインストールしたら `/etc/haproxy/haproxy.cfg` を編集します。
今回はリバースプロキシサーバーの 25565 ポート向けに入ってきた通信を 192.168.0.100 の 25565 ポートへ流す設定にします。
```/etc/haproxy/haproxy.cfg
global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

frontend minecraft
  mode tcp
  bind 0.0.0.0:25565
  default_backend minecraft_server

backend minecraft_server
  mode tcp
  balance roundrobin
  server first 192.168.100.100:25565 send-proxy-v2
```

デフォルトのコンフィグファイルに `frontend minecraft` と `backend minecraft_server` をくっつけただけです。

Minecraft サーバーへ接続元の実際のアドレスを提供したいので、backend セクションの server 行に `send-proxy-v2` を追記しています。
[HAProxy Enable the Proxy Protocol](https://www.haproxy.com/documentation/haproxy-configuration-tutorials/client-ip-preservation/enable-proxy-protocol/)

---

`haproxy -c -f /etc/haproxy/haproxy.cfg` を実行して HAProxy の設定ファイルにミスが無いかチェックします。
http についての注意が出るかもしれませんが fatal error 的なことが表示されなければ大丈夫です。

# 準備(Minecraft サーバー)
0. PaperMC をダウンロード = `wget https://api.papermc.io/v2/projects/paper/versions/(VERSION)/builds/(BUILD_NUM)/downloads/paper-(VERSION)-(BUILD_NUM).jar`
0. eula の同意
0. `config/paper-global.yml` の `proxies.proxy-protocol` を true に変更

# 準備(RTX830)
NAT ディスクリプター関連は Web GUI とシリアルの両方から設定可能ですが、今回は分かりやすい前者で設定します。

設定を開いて、静的 IP マスカレード設定に以下の内容を追加します。
- NAT ディスクリプターにおけるエントリ番号 = 1
- 宛先の IP アドレス = 192.168.100.100
- 使用するプロトコル = tcp
- 宛先のポート番号 = 25565

フィルタの設定を変更を許可して適用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/265c09bd-0b69-9fa3-96ba-ce64c0f58928.png)


# テスト
クライアントからリバースプロキシの 25565 ポートへ接続したときに、RTX830 を介してサーバーに接続できるかを試します。

今回は HAProxy が 192.168.0.2 にあるので、マルチプレイのサーバー参加欄から 192.168.0.2 を指定します。
接続できれば成功です。
接続できない場合にはルーター、プロキシの設定とログを確認してみましょう。

# おわりに
すごい！