2
2

More than 3 years have passed since last update.

OpenWrtでNAT64/DNS64環境を構築する

Last updated at Posted at 2021-03-04

2021/05/26追記: OpenWrtの現在のstable release (19.07)のJoolパッケージはバージョン3.5.7ですが、次のOpenWrt 21.02では4.1.5に更新されているようです。
Jool 4.x向けに記事の内容を変更しましたが、3.5を使用する場合はこちらを参照してください。


OpenWrtのLAN側のネットワークはデフォルトではIPv4/IPv6デュアルスタックで動作するように設定されていますが、これをIPv6シングルスタックに変更するためJoolとUnboundを使ってNAT64/DNS64環境を構築しました。

環境

root@OpenWrt:~# cat /etc/openwrt_release
DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='21.02.0-rc1'
DISTRIB_REVISION='r16046-59980f7aaf'
DISTRIB_TARGET='ath79/generic'
DISTRIB_ARCH='mips_24kc'
DISTRIB_DESCRIPTION='OpenWrt 21.02.0-rc1 r16046-59980f7aaf'
DISTRIB_TAINTS=''
root@OpenWrt:~# jool --version
4.1.5.0
root@OpenWrt:~# unbound -V
Version 1.13.1

デフォルトでは以下のようなネットワーク構成になっています。

# ifstatus wan
...
        "proto": "dhcp",
        "device": "eth0.2",
        "ipv4-address": [
                {
                        "address": "10.10.10.113",
                        "mask": 24
                }
        ],
        "dns-server": [
                "10.10.10.1"
        ],
...

# ifstatus wan6
...
        "proto": "dhcpv6",
        "device": "eth0.2",
        "ipv6-prefix": [
                {
                        "address": "2001:db8:fc7e:200::",
                        "mask": 56,
                        "class": "wan6",
                        "assigned": {
                                "lan": {
                                        "address": "2001:db8:fc7e:200::",
                                        "mask": 60
                                }
                        }
                }

        ],
        "dns-server": [
                "2001:db8:fc7e::1"
        ],
...

# ifstatus lan
...
        "proto": "static",
        "device": "br-lan",
        "ipv4-address": [
                {
                        "address": "192.168.1.1",
                        "mask": 24
                }
        ],
        "ipv6-prefix-assignment": [
                {
                        "address": "2001:db8:fc7e:200::",
                        "mask": 60,
                        "local-address": {
                                "address": "2001:db8:fc7e:200::1",
                                "mask": 60
                        }
                },
                {
                        "address": "fd92:2bfc:16ee::",
                        "mask": 60,
                        "local-address": {
                                "address": "fd92:2bfc:16ee::1",
                                "mask": 60
                        }
                }
        ],
...

+------+  |
| Host +--+ LAN +---------+ WAN/ +------+
+------+  |     |         | WAN6 |      |
          +-----+ OpenWrt +------+  GW  |
+------+  |     |         |      |      |
| Host +--+     +---------+      +------+
+------+  |

<---------------- v4/v6 ---------------->

これを以下のように変更します。

+------+  |
| Host +--+ LAN +---------+ WAN/ +------+
+------+  |     |         | WAN6 |      |
          +-----+ OpenWrt +------+  GW  |
+------+  |     |         |      |      |
| Host +--+     +---------+      +------+
+------+  |

<---- v6 ----> NAT64/DNS64 <--- v4/v6 --->

NAT64/DNS64を利用してIPv4への接続性を確保しつつ、LAN側のIPv4を無効にします。

必要なパッケージのインストール

# opkg update
# opkg install unbound-daemon kmod-jool jool-tools

DNS64 (Unbound)の設定

# uci set unbound.@unbound[0].dns64='1'
# uci commit unbound

全ての名前解決を別のDNSキャッシュサーバにforwardしたい場合は以下のようにforward-zoneを設定する。

/etc/unbound/unbound_ext.conf
forward-zone:
        name: "."
        forward-addr: 10.10.10.1
        forward-addr: 2001:db8:fc7e::1

DnsmasqのDNSサーバを無効にする。

# uci set dhcp.@dnsmasq[0].port='0'
# uci commit dhcp
# service dnsmasq restart
# service unbound restart

名前解決できているか確認する。

# nslookup ipv4.google.com localhost
Server:         localhost
Address:        ::1#53

Name:      ipv4.google.com
ipv4.google.com canonical name = ipv4.l.google.com
Name:      ipv4.l.google.com
Address 1: 172.217.25.110
ipv4.google.com canonical name = ipv4.l.google.com
Address 2: 64:ff9b::acd9:196e

NAT64 (Jool)の設定

# modprobe jool
# jool instance add "example" --iptables --pool6 64:ff9b::/96
# ip6tables -t mangle -A PREROUTING -j JOOL --instance "example"
# iptables -t mangle -A PREROUTING -j JOOL --instance "example"

起動時にJoolが有効になるように、initスクリプトと設定ファイルを作成する。

# mkdir /etc/jool
# cat << "EOF" > /etc/jool/jool.conf
{
    "comment": "Configuration for the NAT64 Jool service.",

    "instance": "example",
    "framework": "iptables",

    "global": {
        "pool6": "64:ff9b::/96"
    }
}
EOF
# cat << "EOF" >> /etc/firewall.user
ip6tables -t mangle -A PREROUTING -j JOOL --instance "example"
iptables -t mangle -A PREROUTING -j JOOL --instance "example"
EOF
# cat << "EOF" >> /etc/sysupgrade.conf
/etc/init.d/jool
/etc/jool/
EOF
# wget -O /etc/init.d/jool https://gist.githubusercontent.com/konosukef/d0a3b8fa73458defd4f61c95649dd029/raw/jool
# chmod +x /etc/init.d/jool
# service jool enable
# service jool restart
# service firewall restart

LANのIPv4の設定を削除する。

# uci delete network.lan.ipaddr
# uci delete network.lan.netmask
# uci commit network
# service network restart

接続テスト

root@OpenWrt:~# jool instance display
+--------------------+-----------------+-----------+
|          Namespace |            Name | Framework |
+--------------------+-----------------+-----------+
|           8064df98 |         example |  iptables |
+--------------------+-----------------+-----------+

root@OpenWrt:~# jool --instance "example" global display
  manually-enabled: true
  pool6: 64:ff9b::/96
  lowest-ipv6-mtu: 1280
  logging-debug: false
  zeroize-traffic-class: false
  override-tos: false
  tos: 0
  mtu-plateaus: 65535,32000,17914,8166,4352,2002,1492,1006,508,296,68
  address-dependent-filtering: false
  drop-externally-initiated-tcp: false
  drop-icmpv6-info: false
  source-icmpv6-errors-better: true
  f-args: 11 (0b1011): SrcAddr:1 SrcPort:0 DstAddr:1 DstPort:1
  handle-rst-during-fin-rcv: false
  tcp-est-timeout: 2:00:00 (HH:MM:SS)
  tcp-trans-timeout: 0:04:00 (HH:MM:SS)
  udp-timeout: 0:05:00 (HH:MM:SS)
  icmp-timeout: 0:01:00 (HH:MM:SS)
  logging-bib: false
  logging-session: false
  maximum-simultaneous-opens: 10
  ss-enabled: false
  ss-flush-asap: true
  ss-flush-deadline: 2000
  ss-capacity: 512
  ss-max-payload: 1452

root@OpenWrt:~# ip6tables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
JOOL       all      anywhere             anywhere             instance:example
...

root@OpenWrt:~# iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
JOOL       all  --  anywhere             anywhere             instance:example
...

LAN側のホストからipv4.google.comにpingしてみます。

user@host:~$ ping6 ipv4.google.com
PING ipv4.google.com(nrt13s51-in-f14.1e100.net (64:ff9b::acd9:196e)) 56 data bytes
64 bytes from nrt13s51-in-f110.1e100.net (64:ff9b::acd9:196e): icmp_seq=1 ttl=116 time=5.18 ms
64 bytes from nrt13s51-in-f110.1e100.net (64:ff9b::acd9:196e): icmp_seq=2 ttl=116 time=5.00 ms
64 bytes from nrt13s51-in-f110.1e100.net (64:ff9b::acd9:196e): icmp_seq=3 ttl=116 time=5.20 ms
64 bytes from nrt13s51-in-f110.1e100.net (64:ff9b::acd9:196e): icmp_seq=4 ttl=116 time=5.36 ms
...

ICMPセッションテーブルを確認します。

root@OpenWrt:~# jool --instance "example" session display --icmp
---------------------------------
Expires in 0:00:49.412
Remote: nrt13s51-in-f110.1e100.net#63022 2001:db8:fc7e:200:8e3:5b48:3ed8:e40#1
Local: 10.10.10.113#63022       64:ff9b::acd9:196e#1
---------------------------------

以下のようにAndroidではclatdが動いて192.0.0.4が自動設定されているので464XLATも問題ないようです。

参考

2
2
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
2