LoginSignup
7
6

More than 3 years have passed since last update.

NAT64/DNS64の環境をUbuntu Server 18.04で構築する

Last updated at Posted at 2019-03-05

概略

IPv6の勉強のため、NAT64/DNS64でインターネット接続性のあるIPv6 onlyなネットワークを作ろうとしたところ、バージョンによる違いが発生してつまづきまくった(特にJoolとisc-dhcp-server)。

とりあえず、現時点で最新のUbuntu 18.04 ServerとJool 4.0.0を使ったNAT64/DNS64環境の構築方法をまとめた。

ネットワーク構成

    +-----+
    | GW  | 192.168.10.253
    +--+--+
       |
       |eth0: 192.168.10.217/24
+------+------+
|   Host A    |
+------+------+
       |eth1: fc01:0:0:1::1/64
       |
       |eth0: DHCPv6で付与されたアドレス
+------+------+
|   Host B    |
+-------------+
  • Host A
    • 本記事の主役
    • NAT64, DNS64, DHCPv6サーバ
    • OS: Ubuntu Server 18.04.2
    • eth0がIPv4ネットワークに、eth1がIPv6ネットワークに接続
  • Host B
    • IPv6ネットワークのテスト端末
    • OS: Ubuntu Server 18.04.2

Host Aはnetplanで下記設定になればOK。

/etc/netplan/99_config.yaml
network:
    ethernets:
        eth0:
            addresses:
            - 192.168.10.217/24
            gateway4: 192.168.10.253
            nameservers:
                addresses:
                - 8.8.8.8
        eth1:
            addresses:
            - fc01:0:0:1::1/64
            nameservers: {}
    version: 2

構築手順

DNS64の設定

DNS64サーバにはunboundを使用する。

sudo apt install unbound

設定ファイルを/etc/unbound/unbound.conf.d/dns64.confに作成。

/etc/unbound/unbound.conf.d/dns64.conf
server:
  verbosity: 2
  pidfile: "/var/run/unbound.pid"
  use-syslog: yes
  module-config: "dns64 iterator"
  dns64-prefix: 64:ff9b::/96
  dns64-synthall: yes
  interface: ::0
  port: 53
  access-control: ::0/0 allow

forward-zone:
  name: "."
  forward-addr: 8.8.8.8

サービスを再起動。

sudo systemctl restart unbound

正常に起動できたことを確認(sudo systemctl status unboundなど)したら、DNS64の動作を確認。

$ dig AAAA www.yahoo.co.jp

(中略)

;; ANSWER SECTION:
www.yahoo.co.jp.        19      IN      CNAME   edge12.g.yimg.jp.
$ dig AAAA www.yahoo.co.jp @localhost

(中略)

;; ANSWER SECTION:
www.yahoo.co.jp.        367     IN      CNAME   edge12.g.yimg.jp.
edge12.g.yimg.jp.       20      IN      AAAA    64:ff9b::b74f:d97c

unboundが起動しているlocalhostに問い合わせると、AAAAレコードを持っていない場合でも、
設定で指定されたprefixがついたIPv6アドレスが返ってくることを確認。

RAの設定

IPv6のRoute Advertisementをするradvdをインストールする。
その前に、/etc/sysctl.confにIPv4とIPv6パケットの転送を有効にするように設定。

/etc/sysctl.conf(追記)
net.ipv4.conf.all.forwarding = 1
net.ipv6.conf.all.forwarding = 1

設定を有効化。

sudo sysctl -p

radvdをインストール。

sudo apt install radvd

上記のコマンドでインストールすると、インストール後そのままradvdを起動しようとするのだが、/etc/radvd.confが無いから起動できないよ、と言われるので、設定ファイルの/etc/radvd.confを下記のように作成、設定する。

/etc/radvd.conf
interface eth1 {
  AdvSendAdvert on;
  MinRtrAdvInterval 3;
  MaxRtrAdvInterval 10;
  AdvOtherConfigFlag on;

  prefix fc01:0:0:1::/64 {
    AdvOnLink on;
    AdvAutonomous on;
    AdvRouterAddr on;
  };
};

radvdを再起動し、エラーが出なければOK。

sudo systemctl enable radvd
sudo systemctl restart radvd

DHCPv6の設定

DHCPサーバには、もう古いとは言われているものの情報が多いのでisc-dhcp-serverを使う。
バージョンによって設定ファイルの書き方が変わっているので要注意。

sudo apt install isc-dhcp-server

設定ファイル(/etc/default/isc-dhcp-server/etc/dhcp/dhcpd6.conf)を次のようにコメントアウト/設定。

/etc/default/isc-dhcp-server
DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf
DHCPDv6_PID=/var/run/dhcpd6.pid
INTERFACESv6="eth1"
/etc/dhcp/dhcpd6.conf(追記)
subnet6 fc01:0:0:1::/64
{
  option dhcp6.name-servers fc01:0:0:1::1;
}

そして、今回最大のハマリポイントだったのだが、DHCPv6サーバのサービス名が、
isc-dhcp-serverからisc-dhcp-server6に変わっていた。

下記のように、DHCPv4は無効化し、DHCPv6を有効化、起動する。

sudo systemctl disable isc-dhcp-server
sudo systemctl enable isc-dhcp-server6
sudo systemctl start isc-dhcp-server6

別のマシン(Host B)から確認

ここまで設定した状態で、一度IPv6オンリーのネットワークに繋いだホストBで下記を確認する。

  • ip aで割り当てられたIPv6アドレスを確認
  • systemd-resolve --statusでDHCPv6でDNSサーバの情報が降ってきていることを確認
  • digでDNS64の名前解決ができることを確認
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether fa:75:52:f4:58:e2 brd ff:ff:ff:ff:ff:ff
    inet6 fc01::1:f875:52ff:fef4:58e2/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 86394sec preferred_lft 14394sec
    inet6 fe80::f875:52ff:fef4:58e2/64 scope link 
       valid_lft forever preferred_lft forever
$ systemd-resolve --status
(中略)
    DNS Servers: fc:0:0:1::1
$ dig AAAA www.yahoo.co.jp

(中略)

;; ANSWER SECTION:
www.yahoo.co.jp.        415     IN      CNAME   edge12.g.yimg.jp.
edge12.g.yimg.jp.       39      IN      AAAA    64:ff9b::b74f:d97c

NAT64(Jool)のビルドと設定

構築手順は公式ページに準ずるが、
Jool 4.0から設定方法やコマンドが大幅に変わっているので注意されたし。

まずはビルドに必要なパッケージをインストール。

sudo apt install gcc make linux-headers-$(uname -r) libxtables-dev \
  dkms git autoconf tar pkg-config libnl-3-dev libnl-genl-3-dev

次にソースをダウンロードする。
Gitで最新版を落とすと./configureが文法エラーで止まったのでtarballで4.0.0をダウンロード。

wget https://github.com/NICMx/Jool/releases/download/v4.0.0/jool_4.0.0.tar.gz
tar -xzf jool_4.0.0.tar.gz

DKMSでインストール。

sudo dkms install jool-4.0.0/

次にuserspace clientsをビルド。

cd jool-4.0.0/
./configure
cd src/usr/
make
sudo make install

ビルドができたら、次のように設定、起動する。
以前のバージョンと全く異なるので要注意。

sudo modprobe jool

sudo jool instance add "example" --iptables  --pool6 64:ff9b::/96

sudo ip6tables -t mangle -A PREROUTING -d 64:ff9b::/96 -j JOOL --instance "example"
sudo iptables  -t mangle -A PREROUTING -d 192.168.10.217 -p tcp --dport 61001:65535 -j JOOL --instance "example"
sudo iptables  -t mangle -A PREROUTING -d 192.168.10.217 -p udp --dport 61001:65535 -j JOOL --instance "example"
sudo iptables  -t mangle -A PREROUTING -d 192.168.10.217 -p icmp -j JOOL --instance "example"

NAT64の確認(Host Bから)

まずはIPv4ネットワーク側にPingが通ることを確認。

ping6 64:ff9b::192.168.10.253

あとはcurlで適当なウェブサイトを見てみて、ダウンロードできればOK。

curl www.yahoo.co.jp

Host Bに入れたのがサーバOSなのであまりアプリケーションがないのだが、
IPv6 onlyなネットワークに接続したホストから、IPv4ネットワークに接続する種々のアプリケーションが動作するはず。

自動起動の設定

再起動後に自動でJoolが起動するように設定する。

一旦、Joolを停止。

sudo ip6tables -t mangle -F
sudo iptables  -t mangle -F
sudo jool instance remove "example"
sudo modprobe -r jool

SystemdのUnitとその設定ファイルを作成する。

/etc/systemd/system/jool.service
[Unit]
Description=Jool - NAT64
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/etc/jool.conf
ExecStart=/bin/sh -ec '\
    /sbin/modprobe jool; \
    /usr/local/bin/jool instance add "${JOOL_INSTANCE_NAME}" --iptables  --pool6 ${JOOL_IPV6_POOL}; \
    /sbin/ip6tables -t mangle -A PREROUTING -d ${JOOL_IPV6_POOL} -j JOOL --instance "${JOOL_INSTANCE_NAME}"; \
    /sbin/iptables  -t mangle -A PREROUTING -d ${JOOL_IPV4_ADDRESS} -p tcp --dport ${JOOL_NAPT_START}:${JOOL_NAPT_END} -j JOOL --instance "${JOOL_INSTANCE_NAME}"; \
    /sbin/iptables  -t mangle -A PREROUTING -d ${JOOL_IPV4_ADDRESS} -p udp --dport ${JOOL_NAPT_START}:${JOOL_NAPT_END} -j JOOL --instance "${JOOL_INSTANCE_NAME}"; \
    /sbin/iptables  -t mangle -A PREROUTING -d ${JOOL_IPV4_ADDRESS} -p icmp -j JOOL --instance "${JOOL_INSTANCE_NAME}" '


ExecStop=/sbin/ip6tables -t mangle -F
ExecStop=/sbin/iptables  -t mangle -F
ExecStop=/usr/local/bin/jool instance remove "${JOOL_INSTANCE_NAME}"
ExecStop=/sbin/modprobe -r jool

[Install]
WantedBy=multi-user.target
/etc/jool.conf
JOOL_IPV4_ADDRESS="192.168.10.217"
JOOL_IPV6_POOL="64:ff9b::/96"
JOOL_INSTANCE_NAME="example"
JOOL_NAPT_START="61001"
JOOL_NAPT_END="65535"

Unitファイルの変更を反映させ、サービスとして起動してみる。

sudo systemctl daemon-reload
sudo systemctl enable jool
sudo systemctl start jool

上手くいったら、再起動してJoolが起動できていればOK

sudo reboot

その他(Joolの状態確認)

インスタンス一覧

$ sudo jool instance display
+--------------------+-----------------+-----------+
|          Namespace |            Name | Framework |
+--------------------+-----------------+-----------+
| 0xffffffffacde4640 |         example |  iptables |
+--------------------+-----------------+-----------+

インスタンスの設定

$ sudo jool -i example global display
  manually-enabled: true
  pool6: 64:ff9b::/96
  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-icmpv6-info: false
  drop-externally-initiated-tcp: false
  udp-timeout: 00:05:00 (HH:MM:SS)
  icmp-timeout: 00:01:00 (HH:MM:SS)
  tcp-est-timeout: 02:00:00 (HH:MM:SS)
  tcp-trans-timeout: 00:04:00 (HH:MM:SS)
  maximum-simultaneous-opens: 10
  source-icmpv6-errors-better: true
  f-args: 11 (0b1011): SrcAddr:1 SrcPort:0 DstAddr:1 DstPort:1
  handle-rst-during-fin-rcv: false
  logging-bib: false
  logging-session: false
  ss-enabled: false
  ss-flush-asap: true
  ss-flush-deadline: 2000
  ss-capacity: 512
  ss-max-payload: 1452

セッション一覧

$ sudo jool -i example session display
---------------------------------
(V4_FIN_V6_FIN_RCV) Expires in 00:03:20.268
Remote: steelix.canonical.com#http      fc01::1:f875:52ff:fef4:58e2#50844
Local: 192.168.10.217#61190     64:ff9b::5bbd:5898#80
---------------------------------
(V6_INIT) Expires in 00:03:07.784
Remote: keeton.canonical.com#http       fc01::1:f875:52ff:fef4:58e2#34530
Local: 192.168.10.217#61940     64:ff9b::5bbd:58a1#80
---------------------------------

参考サイト

※ いずれもJool 4.0以前の情報なので要注意

7
6
3

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