Help us understand the problem. What is going on with this article?

firewalldとiproute2でポートフォワーディング

More than 1 year has passed since last update.

はじめに

特定のポートの通信を、特定のゲートウェイを通して行わせようと思います。

以前「nginxをminecraftのプロキシとして使う」という記事を書きました。
表に置くサーバーと、アプリケーションを動かすサーバーを分けるという話ですが、TCPレイヤーのプロキシを使用しているため、アプリケーション側から見ると接続元のIPアドレスがプロキシのものになってしまいます1
今回は、IPパケットをフォワーディングさせることで、この問題を回避してみます。

ネットワーク構成

port_forwarding.png

minecraft: VM(VirtualBox), Minecraft(25565番ポート)を動かす想定のサーバー
gateway: VM(VirtualBox), clientからのパケットを直接受け取るサーバー
client: ホストマシン, Minecraftのクライアントを動かす

gatewayのネットワークアダプタはブリッジアダプタを使用して、ホストマシンと同じネットワークに置きます(DHCPなので、ルータの設定でgatewayのIPを192.168.0.101に固定しておきます)。
minecraft-gateway間は内部ネットワークで接続します。

設定内容

内部ネットワークの設定

gateway

nmcli c add type ethernet ifname enp0s8 con-name enp0s8
nmcli c m enp0s8 ipv4.method manual ipv4.addresses 10.0.0.101/24 connection.autoconnect true

minecraft

nmcli c add type ethernet ifname enp0s8 con-name enp0s8
nmcli c m enp0s8 ipv4.method manual ipv4.addresses 10.0.0.102/24 connection.autoconnect true

ポートフォワーディングの設定

gateway

# ip_forwardを有効化
echo 1 > /proc/sys/net/ipv4/ip_forward

firewall-cmd --direct --add-rule ipv4 nat PREROUTING 0 -p tcp --dport 25565 -j DNAT --to 10.0.0.102
firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -p tcp --sport 25565 -j SNAT --to 192.168.0.101
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -p tcp --dport 25565 -j ACCEPT

デフォルトではカーネルの設定でip_forwardが無効になっているので、有効にします。

(firewalld) PREROUTINGチェインで25565番ポート宛てのパケットの送り先を10.0.0.102に書き換えます。
(firewalld) FORWARDチェインで25565番ポート宛てのパケットが別のホストへ通過する許可設定を入れます。
(firewalld) POSTROUTINGチェインで送り元が25565番ポートのパケットの送り元を10.0.0.102に書き換えます。

minecraft

# 経路フィルタの設定
echo 2 > /proc/sys/net/ipv4/conf/enp0s8/rp_filter

firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 0 -p tcp --sport 25565 -j MARK --set-mark 1

ip rule add fwmark 1 table 1
ip route add default via 10.0.0.101 dev enp0s8 table 1

経路フィルタに引っかかるようになるので、緩いフィルタ"2"に変更します。

(firewalld) OUTPUTチェインで、送り元が25565番ポートのパケットにマーク"1"を付けます。
(iproute2) マーク"1"を付けたパケットに適用するルートテーブルをテーブル"1"に変更し、テーブル"1"にgateway(10.0.0.101)を通過するルールを加えます。

以上の設定を入れることで、minecraftサーバーから見たclientのIPアドレスがgatewayのものではなく、本来のものとして通信することができるようになりました。

まとめ

  • ip_forwardとrp_filterの設定に気が付くのが遅れ結構な時間を無駄にした
  • Linuxでルーターを作れるようになった
  • デバッグでtcpdumpとかnetcatつかえるようになった
  • BungeeCordを使おう

こんなことをやろうとする人が他にいるかわかりませんが、とりあえずまとめました。
Minecraftに限った話だとBungeeCordを使うのが最善かと思います。


  1. Minecraftの場合はBungeeCord(Minecraftのプロキシアプリケーション)が独自のIP Forwardingでこれを解決しています。 

ttk1
IT技術者。 面白いことだけを考えて生きていきたい。
https://ttk1.net
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした