Minecraftで、大本のIPを隠すためにVPSを使ってリバースプロキシしていきます。
複数のVPSを用意してGSLBなどで分散することにより、DDoS対策としても使えます。
構成としては、
[BungeeCord - MCServer] <--> [VPS(Proxy)] <--> [クライアント]
のようになります。
接続してきたユーザーのIPアドレスも欲しいので、proxy_protocolを使って実現していきます。
知識が浅いため、様々な記事やドキュメントを調べながら行っています。
最低限動作する事を目標にしているので、動作が不安定かもしれません。
今回使うVPS
WebARENA Indigoの8GB 6vCPUプランのVPSを使用します。
OSはUbuntu 20.04です。
オーバースペックな気もしますが...まぁいいでしょう。
友人からもらったVPSを使っているので...
準備 - BungeeCord / Geyser
BungeeCordのconfig.yml内の
proxy_protocol
をtrue
に変更。
Geyserのconfig.ymlにある
enable-proxy-protocol
proxy-protocol-whitelisted-ips
を以下のように変更
enable-proxy-protocol: true #有効化
proxy-protocol-whitelisted-ips: "VPSのIP" #ホワリス
複数のVPSからのアクセスを許可したい場合は
proxy-protocol-whitelisted-ips: [ "VPSのIP", "VPSのIP(2)" ]
のようにします。
準備 - VPS側
HaProxyをインストール
$sudo apt install haproxy
Nginxをビルド
aptで入手可能なNginxにはngx_stream_*
モジュールが含まれていません。
そのため、自分でビルドしなければなりません。
Nginxの最新版をダウンロードします。
(2024/01/19時点では1.25.3が最新でした。)
この記事では1.24.0を使用します。
$wget http://nginx.org/download/nginx-1.24.0.tar.gz
$tar zxvf nginx-1.24.0.tar.gz
$cd nginx-1.24.0
ビルドに必要なライブラリをダウンロードします。
$apt install build-essential libpcre3-dev zlib1g-dev
ユーザーを作成します。
$ sudo groupadd nginx
$ sudo useradd -g nginx nginx
$ sudo usermod -s /bin/false nginx
ビルドします。
$sudo ./configure \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--user=nginx \
--group=nginx \
--with-stream
$sudo make
$sudo make install
起動し、無事に動作していることを確認
$ sudo systemctl start nginx.service
$ sudo systemctl status nginx.service
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset:>
Active: active (running) since Mon 2023-09-25 20:01:45 JST; 16h ago
Docs: man:nginx(8)
Process: 660193 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_pro>
Process: 660200 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; >
Main PID: 660205 (nginx)
Tasks: 3 (limit: 9513)
Memory: 2.3M
CGroup: /system.slice/nginx.service
tq660205 nginx: master process /usr/sbin/nginx -g daemon on; maste>
tq660207 nginx: worker process
mq660208 nginx: worker process
TCP(Java版)
Java版(TCP)のリバースプロキシを作っていきます。
エディタを使って、/etc/haproxy/haproxy.cfg
のconfigを
#Global
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
# Gateway Settings
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
# MC Gateway
listen minecraft01
bind 0.0.0.0:25565
mode tcp
option tcplog
balance roundrobin
server mc01 <BungeeCord-IP>:<Port> send-proxy-v2
のようにしてください。
<BungeeCord-IP>
と<Port>
はBungeeCordが動いているサーバーのIP(ドメイン):ポートにしてください。
例: 123.456.78.90:25565
、mc.example.com:25566
設定したら、念のために
haproxy -f /etc/haproxy/haproxy.cfg -c
を行い、Configuration file is valid
となっていることを確認したら
systemctl restart haproxy
で再起動しましょう。
再起動後、VPSのIPアドレス:ポート番号
から正常に接続できれば成功です。
UDP(BE版)
BE版(UDP)のリバースプロキシを作っていきます。
エディタを使って、/etc/nginx/nginx.conf
のconfigを
worker_processes 2;
events {
worker_connections 1024;
}
stream {
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
upstream minecraft_udp_upstreams {
server <BungeeCord-IP>:<Port>;
}
server {
error_log /var/log/nginx/error.log debug;
access_log /var/log/nginx/access.log proxy buffer=32k;
listen 19132 udp;
proxy_pass minecraft_udp_upstreams;
proxy_timeout 120s;
proxy_protocol on;
}
}
のようにしてください。
Java版と同様<BungeeCord-IP>
と<Port>
はBungeeCordが動いているサーバーのIP(ドメイン):ポートにしてください。
例: 123.456.78.90:19132
upstreamの部分でドメインを使用する場合、ngx_upstream_jdomain
のようなドメインを解決できるものが必要となるらしいです。
念のために構文チェック。
$nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
となっているのを確認したら
$systemctl restart nginx
で再起動しましょう。
再起動後、VPSのIPアドレス:ポート番号
から正常に接続できれば成功です。
おわりに
試してみた感じでは特に問題もなく安定しており、期待通りの動作となりました。
皆さんも、是非試してみてはいかがでしょうか。
NginxのUDPでproxy_protocolを使う方法に関する記事がかなり少なく、数時間ぐらい格闘しました。
解決策を見つけられた時の達成感はやっぱり最高
参考記事