Jool(NAT64)の導入とUnboundのDNS64設定メモ

自室IPv6化計画の一環です

前回

https://qiita.com/jp_ibis/items/23c07b687203b2a1364d

# 動機
うちはNTTも光回線を引けないと逃げ出す田舎での(´・ω:;.:... 

100MBpsの回線が6千円近くとかのCATVのサービスしか選択肢がないのですが、当然IPv6に対応しているわけもなく。

つまり自室をIPv6にしたら外につながらなくなるので途中でIPv4に変換しなければなりません。そこで必要なのがNAT64という技術。

さらにIPv6でDNSを引くとIPv6アドレスが帰ってきますが、このアドレスにはIPv4に変換したパケットが到達しません。つまりIPパケットだけでなくIPアドレスもIPv4に変換しなければなりません。そこで必要なのがDNS64という技術。

つまり今回はNAT64とDNS64の2つの設定が必要になります。

## アクセスの流れ
```mermaid
sequenceDiagram
    メインPC->>中継サーバ: 名前問い合わせ<br>IPv6: example.com
    中継サーバ->>外部DNSサーバ: ①NAT64<br>IPv4: example.com
    外部DNSサーバ->>中継サーバ: Aレコードで応答<br>IPv4: a.b.c.d
    中継サーバ->>メインPC: ②NAT64/DNS64<br> IPv6: 64:ff9b::xxxx:yyyy
    メインPC->>中継サーバ: 接続<br>IPv6: 64:ff9b::xxxx:yyyy
    中継サーバ->>外部サーバ: ③NAT64<br>IPv4: a.b.c.d
    外部サーバ->>中継サーバ: 応答<br> IPv4
    中継サーバ->>メインPC: NAT64<br> IPv6
```

①： メインPCの2001:db8::1のような送信元IPv6アドレスを中継器のIPv4アドレスに変換してホームルーターに流して外へアクセスできるようにする

②： a.b.c.dのようなIPv4アドレスのa,b,c.dの部分を16進数に変換し頭に64:ff9b::を付けて仮のIPv6アドレスとして扱えるようにするDNS64変換と、中継器に戻ってきたIPv4パケットをIPv6パケットに変換して2001::db8::1のメインPCに流すNAT64変換

③： ①同様メインPCのIPv6をIPv4に変換してホームルーターから外に行けるようにする。併せて64:ff9b::xxxx:yyyyという仮のIPv6アドレスの宛先をa.b.c.dという元の正しいIPv4アドレスの宛先に変換する。

このうちNAT64の変換をJoolが担当し、DNS64の変換をUnboundが担当します。

# Joolのインストール
最初taygaを使ってみましたがIF作ってRoute設定して……メンドクサイ。しまいには作ったIFがUPしなくなったりして……

そこでJoolですよ。

公式パッケージにはない😢ので非公式パッケージよりインストールします
```bash
$ dnf copr enable dasskelett/jool
$ dnf install jool
```

設定ファイルはサンプルをコピーして用意します。

```bash
$ mkdir /etc/jool
$ cp /usr/share/doc/jool/examples/jool.conf  /etc/jool/
```

## 設定ファイルの修正
instance名をinitからdefaultにしておくと便利です。便利、程度なので別に変更しなくても大丈夫です。

joolのコマンドを使うときに-i instance名という引数が必要になりますが、defaultの場合これを省略できます。とはいえ、そもそもコマンドを使うことがあまりない……

```jool.conf
"instance": "init"
↓
"instance": "default"
```

prefixはJoolを動かすサーバのIPv4アドレスを入れます。NATといいつつ出力ポートで振り分けるNAPTなので出力先は自分のIPv4アドレス固定でいけます。

pingが通らないと疎通チェックが面倒なのでICMPも入れておきました。

```jool.conf
{
        "protocol": "TCP",
        "prefix": "192.0.2.1",
        "port range": "61001-65535"
}, {
        "protocol": "UDP",
        "prefix": "192.0.2.1",
        "port range": "61001-65535"
}
↓
{
        "protocol": "TCP",
        "prefix": "中継器のIPv4アドレス",
        "port range": "61001-65535"
}, {
        "protocol": "UDP",
        "prefix": "中継器のIPv4アドレス",
        "port range": "61001-65535"
}, {
        "protocol": "ICMP",
        "prefix": "中継器のIPv4アドレス"
}
```

素のjsonパーサーを使っているようなので余計な`,`が付いていたらエラーになります。JSON構文のチェックはしっかりとしてください。

自信が無いときはjqを使うと便利です。

```bash
$ dnf install jq
$ cat /etc/jool/jool.conf | jq .
```

## 起動

```bash
$ systemctl enable jool
$ systemctl start jool
```

これだけでNAT64変換してくれるようになります。とても簡単☺️

## お試し

ICMPを有効にしたのでpingが通ります。サーバ(jool.confのprefixに指定したアドレス)に向かって64::ff9b::の後ろに10進数でIPv4を追加したアドレスにpingを実行すれば、16進数に変換されたアドレスでNAT64してIPv4で外にpingを通してくれます。

特別な設定をしていなければサーバ内でpingをしたら普通にIPv6インターフェイスを使って外に行こうとするので、サーバに向かってIPv6を流せる端末で実行してください。

```cmd:メインPC(Windows)より
$ ping www.google.com
www.google.com [a.b.c.d]に ping を送信しています 32 バイトのデータ:
...

$ ping 64:ff9b::a.b.c.d
64:ff9b::xxxx:yyyy に ping を送信しています 32 バイトのデータ:
...
```

応答があればIPv6通信の宛先アドレスを変換しながらIPv4で代理アクセスしたことになります。

# Unboundの設定(DNS64対応)

ものすごく簡単に設定できた……ハズなのですがとんだ罠が😇

この罠をみんなに見てもらいたくてこの記事を書いている、まである。

設定自体は簡単なんですよ。以前の記事でUnboundの導入までは終わっているので以下の設定を追加します。

```conf:/etc/unbound/unbound.conf
        module-config: "dns64 validator iterator"

        dns64-prefix: 64:ff9b::0/96
        dns64-synthall: yes  # AAAAレコードを無視してAレコードのDNS64を強制
```

場所はserver:の下である必要があります。基本的にはコメントアウトされている同様の設定があるので、コメントアウトを外して書き換える(dns64-synthallは追記)と良いでしょう。

設定は終わりなのでこれでUnboundを再起動(reloadでもいけそうだけど上手くいかなかったので再起動してた)してdigってみます。

```bash
$ systemctl restart unbound
$ dig +short www.google.com aaaa
2004:xxxx:...:yyyy
```

普通にIPv6アドレスが返ってくるー？／(^o^)＼

数時間これで悩んだのですが、原因はだいぶ下の方にありました。

```conf:こやつめ、ハハハ
# Default Fedora settings
include: "/usr/share/unbound/fedora-defaults.conf"
```

なんでデフォルト設定がこんな下にあるんだー？／(^o^)＼

この中でmodule-configを上書きしちゃうので、`"dns64 validator iterator"`の設定が無かったことになっていました。

デフォルト設定は最初にやってほしいのでここのincludeをコメントアウトして、unbound.confの先頭にコピーしておきます。まぁぶっちゃけると無くても動く。

```conf:/etc/unbound/unbound.conf
# 先頭にお引っ越し
include: "/usr/share/unbound/fedora-defaults.conf"

# Example configuration file.
#
# See unbound.conf(5) man page, version 1.22.0.
#
# this is a comment.
```

設定を読み直してdigってみるとDNS64が動きました。

```bash
$ systemctl restart unbound
$ dig +short www.google.com aaaa
64:ff9b::xxxx:yyyy
```

後になって考えてみると、すぐ下にconf.d下を読む設定があるのでそもそもunbound.confで設定をするんじゃなくて、conf.d下に上書き設定を書いた.confファイルを置くっていうのがお作法だったのかも。

```conf
# Default Fedora settings
include: "/usr/share/unbound/fedora-defaults.conf"
        
# Stub and Forward zones
include: "/etc/unbound/conf.d/*.conf"
```

# 顛末
NAT64とDNS64が動いたのでIPv4を無くすことができるようになりました。

早速メインPC(Windows)でIPv4を無効にして試してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/c243680b-6289-4ea1-b98a-c9141094d125.png)

|アプリ|通信の成否|
|-|-|
|ブラウザ| 〇|
|Steam| 〇|
|Kindle|〇|
|千年戦争アイギス|〇|
|AdobeCC| ✕|
|Houdini| ✕|
|レスレリアーナのアトリエ| ✕|

普段使ってるアプリ全滅したー／(^o^)＼

ブラウザはなんだかんだ言って通信の最先端、IPv6対応はキッチリしてますね。ブラウザゲーの千年戦争アイギスもその恩恵にあずかっています。

KindleもさすがというかなんだかんだでAmazonはIT大手って感じですね。
UIは💩だけど😇

Steamはブラウザとほぼ同じ画面なのでたぶんWebビュー系がメインコンポーネントでブラウザのIPv6対応技術がそのまま使えてると予想。

Adobe/Houdini/レスレリ等の一般アプリはDNS使わずに内部でサーバと通信して接続先アドレスを確定させたりするだろうから、そこがIPv4アドレスだとIPv6のみにしたWindows側で扱えない。かといってIPv6で受け取ってもホームルーターから先がIPv4網なので通らない。

……詰んでる／(^o^)＼


[デュアルスタック] λ... .. ... .