LoginSignup
2
1

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-09-02

はじめに

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

以前「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でこれを解決しています。 

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1