2023/09/03

Linuxサーバに、Minecraft用にポート転送を設定

息子殿のMinecraftサーバをインターネットからアクセスできるようにするため、自サーバ(Gentoo Linux)にポート転送を設定した。

ルータ(KDDIからの貸与なので機種変更できない 涙)の設定のみで行う予定だったが、機能不足でインターネットから来た通信の転送先が1 IPアドレスにしか転送できないことが分かったため、既存サーバにポート転送を設定し、息子殿のMinecraftサーバに通信を流すことにした。


行った設定

iptables -t nat -A PREROUTING  -p tcp                --dport 45565 -j DNAT        --to-destination 192.168.1.3:25565
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.3 --dport 25565 -j MASQUERADE
iptables        -A FORWARD     -p tcp -d 192.168.1.3 --dport 25565 -j ACCEPT
iptables        -A FORWARD     -p tcp ! --syn -m state --state ESTABLISHED -s 192.168.1.3 --sport 25565 -j ACCEPT
iptables -t nat -A OUTPUT      -p tcp                --dport 45565 -j DNAT        --to-destination 192.168.1.3:25565

 

自サーバではすでにiptablesが有効になっており、IPのルーティングが許可されていたので不要であったが、許可されていない場合は、ip_forwardを有効してやる必要がある。


# echo 1 > /proc/sys/net/ipv4/ip_forward


iptablesを触るのは10年以上ぶりなので、ほとんど忘れていた。テーブルとか、チェーンとかは以下のページの図がわかりやすいと思った。

https://christina04.hatenablog.com/entry/iptables-outline



あとは、-jオプションで指定するターゲットのMASQUERADEってなんだっけか、昔使っていたな、と思ったらソースIPが動的な場合の送信元IPのNATだった。自宅サーバをルータとして使っていた時代に、NAPT(Network Address and Port Translation)用に利用していたんだった。


各ルールの説明メモ

iptables -t nat -A PREROUTING -p tcp --dport 45565 -j DNAT --to-destination 192.168.1.3:25565

クライアントから入ってくる通信の、宛先IPとポート番号を息子殿のMinecraftサーバに向ける。パケットの宛先 IPアドレスを書き換えるため、ターゲット(-j)はDNAT。

--dportはクライアントから受け取ったパケットの宛先ポート番号、--to-destinationは転送先のIPアドレスとポート番号。

インターネットには45565番ポートで公開しており、ルータから自サーバの45565番ポートにクライアントからの通信が送られてくる。送られてきた通信を、息子殿のMinecraftサーバ192.168.1.3の25565番ポートに転送している。


iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.3 --dport 25565 -j MASQUERADE

自サーバから、息子殿のMinecraftサーバに向かって出ていく通信の設定を行う。送信元IPアドレスが動的(不特定多数のクライアントから通信があるため)な状態で、パケットの送信元IPアドレスを自サーバのアドレスに変更するため、ターゲット(-j)はMASQUERADE。

POSTROUTINGチェーンなので、送信先IPアドレス(-d)、送信先ポート(-dport)として指定されているのは転送先である息子殿Minecraftサーバのそれら。

自サーバから息子殿Minecraftサーバ(192.168.1.3:25565)に向かって出ていく通信について、NAPTをかけている。


iptables -A FORWARD -p tcp -d 192.168.1.3 --dport 25565 -j ACCEPT

自サーバが受け取ったパケットを、外に出すための処理の1つめ。宛先が息子殿Minecraftサーバ(192.168.1.3:25565)の場合、通信を許可。


iptables -A FORWARD -p tcp ! --syn -m state --state ESTABLISHED -s 192.168.1.3 --sport 25565 -j ACCEPT

自サーバが受け取ったパケットを、外に出すための処理の2つめ。1つめの通信の戻りの通信も許可してやる必要がある。

! --syn」はSYNフラグだけが立ったパケットではないことを示す。「--syn」は「--tcp-flags SYN,RST,ACK SYN」の省略形であり、「SYN、RST、ACKフラグが立っているかチェックし、SYNだけが立っているパケット」を示している。「!」はNOTの意味。

-m state --state ESTABLISHED」は通信の状況(State)がすでに確立した通信(ESTABLISHED、3-wayハンドシェイクでSYNに対する戻り以降の通信)であることを指定している。Stateマッチを使うには「-m state」の指定が必須なので、少し冗長に見える。

-s 192.168.1.3 --sport 25565」は、送信元のIPアドレス・ポート番号が息子殿Minecraftサーバ(192.168.1.3:25565)であることを示している。

ということで、自サーバに向かって息子殿Minecraftサーバから発信された、確立済み通信の通過を許可する。


iptables -t nat -A OUTPUT -p tcp --dport 45565 -j DNAT --to-destination 192.168.1.3:25565

自サーバではMinecraftは行わないので、これはなくても支障はないが、今後の移設の際にハマってしまわないように記録として設定。

自サーバでMinecraftを行うと、Local Processからパケットが発生することになるため、このページの1番目の設定で行ったPREROUTINGチェインによる宛先変更が適用されない。そのため、自サーバでMinecraftを行う場合、45565番ポートに通信をして転送されることを期待しても息子殿Minecraftサーバには転送してくれない。

そこで、Local Processから出たパケットに対する処理を行うOUTPUTチェインで、PREROUTINGチェインと同じ設定を行う。


設定は以上。


余談

ルータだけで複数のIPアドレスへの転送ができなかった理由。インターネット側から通信を転送する際、ルータが上記のMASQUERADEをやってくれないため。

その結果、転送を受ける側では、ルータが持っているグローバルIPをNICに設定しておく必要がある。ルータはグローバルIPを1個しか持てない仕様のため、転送を受ける2台のサーバが同じグローバルIPを持つことになり競合が起き、先に当該グローバルIPを取得したほうにしか転送できない。



参考にしたページ

https://qiita.com/showchan33/items/407bde52c44d1d8e1a6d

https://christina04.hatenablog.com/entry/iptables-outline

 

0 件のコメント:

コメントを投稿