ゲームのpingが悪すぎて自分だけのDS-Lite環境を構築しました。

始まる前に
=========
- OpenVPN環境を構築した方が簡単だし、動作もはっきりです。
- 次の記事を参考しました。
https://qiita.com/sho7650/items/6dd4c8145411686d012d
https://www2.tmyinsight.net/?p=923
https://qiita.com/kakinaguru_zo/items/2764dd8e83e54a6605f2

- 特にサーバの設定部分がガバガバです

発端
=========
普段、Starcraft 2というゲームをやっていますが、引越ししてネット環境がMAP-Eになってから韓国サーバ向けのpingが遅くなってきました。
140msくらいならなんとかプレイできますが、最近240msになりました。流石にキツイです。
回線や設定の問題だと思いましたが、台湾サーバ向けのpingは30msくらいなので、ISPルーティングテーブルの問題ですね。

![FY-JcuYaMAMyASS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735623/e1ec1c67-334b-39e8-a6ec-a865264c3ff8.jpeg)

~~なんとかしてください~~

とにかく、Oracle Cloudの無料枠上にOpenVPNサーバを設定してその問題は解決しましたが、なんか面白くないんですね。
結果、自前でAFTRを構築してDS-Liteぽい環境を作ることにしました。

環境
=========
- 回線
フレッツ光ネクストマンションタイプLAN方式+オープンサーキットv6Neo
ひかり電話なし
- CPE
Mikrotik CCR1009
MAP-E設定済み
- AFTRになる予定の仮想サーバー
Oracle Cloud VM.Standard.E2.1.Micro(Chuncheon Region) + Oracle Linux 8.0(IPv6アドレス割当済み)
ens3がネットワークインタフェースです。

IPv6の割当方法は　https://docs.oracle.com/ja-jp/iaas/Content/Network/Concepts/ipv6.htm
を参考にしてください

Security Listの設定
=========
Ingress RuleとEgress Ruleで、::/0をすべてacceptすれば大丈夫です。
セキュリティ的には大丈夫じゃないかも


AFTRの構築
=========
まず、サーバがDHCPv6からIPv6アドレスを貰う必要がありますので、その辺の設定をします。

```
# firewall-cmd --permanent --zone=public --add-service=dhcpv6-client
# firewall-cmd --reload
# dhclient -6 ens3
```

これで、ifconfig上にIPv6アドレスが表示されます。
IPv6アドレスもゲットしたので、トンネルを設定します。


```
# modprobe ip6_tunnel
# ip -6 tunnel add ip6tnl mode ipip6 remote <ルーターのv6アドレス> local <AFTRサーバのv6アドレス> encaplimit none
# ip link set dev ip6tnl mtu 1460
# ip link set dev ip6tnl up
# ip addr add 192.0.0.1/30 dev ip6tnl
# firewall-cmd --permanent --zone=public --add-rich-rule='rule protocol value="4" accept'
# firewall-cmd --permanent --zone=public --add-rich-rule='rule protocol value="41" accept'
# firewall-cmd --permanent --zone=public --add-rich-rule="rule family='ipv6' source address=<ルーター側のv6ネットワーク> accept"
# firewall-cmd --reload
```

トンネル設定は終わったので、転送設定もします。


```
#sysctl -w net.ipv4.ip_forward=1
#sysctl -w net.ipv4.conf.all.forwarding=1
#sysctl -w net.ipv4.conf.ens3.rp_filter=0
#sysctl -w net.ipv4.conf.ip6tnl.rp_filter=0
#sysctl -w net.nf_conntrack_max=65535
```

残りは待望のNAT設定です。

```
# firewall-cmd --permanent --zone=trusted --change-interface=ip6tnl
# firewall-cmd --permanent --zone=public --add-masquerade
# firewall-cmd --permanent --zone=trusted --add-masquerade
# firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -o ens3 -j MASQUERADE
# firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i ip6tnl -o ens3 -j ACCEPT
# firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i ens3 -o ip6tnl -m state --state RELATED,ESTABLISHED -j ACCEPT
# firewall-cmd --reload
# route add -net <ルーター内部ネットワーク> dev ip6tnl
```

これでサーバ側の設定は完了です。

ルーターの設定(トンネル)
=========
結構簡単です。

```
/interface ipipv6
add !keepalive local-address=<ルーターのv6アドレス＞ mtu=1460 name=DSLite-Korea remote-address=<AFTRサーバのv6アドレス＞
/ip address
add address=192.0.0.2 interface=DSLite-Korea network=192.0.0.2
```

これで、192.0.0.1(サーバのトンネルIP)や8.8.8.8にpingすると、応答が帰ってくるはずです。


ルーターの設定(ルーティングその辺)
=========

これでトンネルも構築できましたし、通信もできます。残りは、特定ゲームのパケットだけ新しくできたトンネルへ送る設定です。
方法としては、
- ゲームサーバIPを調べ、そのIP宛のパケットは新しいトンネルへ向かうようにする
- ゲームが使用するポート番号を調べ、そのポート番号のパケットは新しいトンネルへ向かうようにする

ポート番号ベースの方が、スマートなきがします。Blizzardゲームは使用しているポートも公開していますし。
mangleのrouting markでできるらしいですね。

まずルーティングテーブルを作ります。

```
/routing table
add disabled=no fib name=sc2w
/ip firewall mangle
add action=mark-routing chain=prerouting new-routing-mark=sc2w port=3724 protocol=tcp src-address=<ルーター内部ネットワーク>
add action=mark-routing chain=prerouting new-routing-mark=sc2w port=3724 protocol=udp src-address=<ルーター内部ネットワーク>
add action=mark-routing chain=prerouting new-routing-mark=sc2w port=1119-1120 protocol=tcp src-address=<ルーター内部ネットワーク>
add action=mark-routing chain=prerouting new-routing-mark=sc2w port=1119-1120 protocol=udp src-address=<ルーター内部ネットワーク>
/ip route
add disabled=no dst-address=0.0.0.0/0 gateway=DSLite-Korea routing-table=sc2w suppress-hw-offload=no
```


これで完成です。
実際ゲームをプレイすると、240msから40msまで減りました！

課題
=========
 - まずfirewalldの設定を見直したい
 - 最初のmangle設定では、src-addressの設定がありませんでしたが、その場合何故かサーバとの通信ができなかったのでやむを得ずsrc-addressを設定しました。NATその辺をいじればsrc-addressを設定せずにできるのでは
 - MAP-EとDS-Liteが共存しているので、二重NATみたいなものが起きているのではないかが心配