3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

dockerネットワークのipv6対応方法と通信経路の整理

Last updated at Posted at 2020-02-24

概要

squidでActiveDirectory連携とSSLインターセプトするProxyをdockerで手軽につくる で、squid4.4の構築時に
squidがIPv6で自分自身にアクセスするため、dockerもIPv6を有効化する必要がありました。
手順と通信経路について整理します。

dockerエンジン・デーモンのIPv6化

以下のファイルを作成し、デーモンを再起動します。
IPv6の表記はドキュメント用なので、適宜修正ください。

/etc/docker/daemon.json
{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}

すでに daemon.json がある場合には、上記を追記してください。

systemctl restart docker

止めたくないから reload してみたけど、反映されなかったので、 restart しました。

参考:https://docs.oracle.com/cd/E77565_01/E87205/html/docker_install_upgrade_ipv6.html

Dockerネットワークとコンテナ

IPv6を有効化したネットワークを作成し、そこに生成したコンテナを参加させる。

# docker network create --ipv6  --driver=bridge  --subnet=fd5a:ceb9:ed8d:1::/64 br_ipv6_nw \
   -o com.docker.network.bridge.name="br_ipv6_nw"
# docker run --network br_ipv6_nw --name cnt01 -it -d centos:centos8 /bin/bash

Dockerネットワークの状態

# docker network inspect br_ipv6_nw
[
    {
        "Name": "br_ipv6_nw",
        "Id": "ae1e90ac38bbdd208394922263053e8cfac4d31d6d6bbfecf50c345f18606e30",
        "Created": "2020-02-24T18:36:33.239261559+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": true,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.26.0.0/16",
                    "Gateway": "172.26.0.1"
                },
                {
                    "Subnet": "fd5a:ceb9:ed8d:1::/64"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "286e2d07ab7a0d04f061ffbe4451f2a5d0a6553ad4cf6063ab21f7cdb4f40441": {
                "Name": "cnt01",
                "EndpointID": "d057150483d194c0e95eca386189482b431cff3b351411b01cb0394b92dd1852",
                "MacAddress": "02:42:ac:1a:00:02",
                "IPv4Address": "172.26.0.2/16",
                "IPv6Address": "fd5a:ceb9:ed8d:1::2/64"
            }
        },
        "Options": {
            "com.docker.network.bridge.name": "br_ipv6_nw"
        },
        "Labels": {}
    }
]

DockerホストとDockerコンテナのインターフェース

Dockerホスト

インターフェース
ホストのインターフェースIDはsubnetの最若番になる。
と、リンクローカルも最若番のfe80::1になる。

# ip add
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:62:2e:fa brd ff:ff:ff:ff:ff:ff
    inet 10.254.10.252/24 brd 10.254.10.255 scope global noprefixroute ens192
       valid_lft forever preferred_lft forever
    inet6 fd5a:ceb9:ed8d:fe0a:ed57:61d8:20eb:aba5/64 scope global dynamic noprefixroute
       valid_lft 2591966sec preferred_lft 604766sec
    inet6 fe80::f7f9:b2ce:3e89:7281/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
75: br_ipv6_nw: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:c1:de:82:5c brd ff:ff:ff:ff:ff:ff
    inet 172.26.0.1/16 brd 172.26.255.255 scope global br_ipv6_nw
       valid_lft forever preferred_lft forever
    inet6 fd5a:ceb9:ed8d:1::1/64 scope global tentative
       valid_lft forever preferred_lft forever
    inet6 fe80::1/64 scope link tentative
       valid_lft forever preferred_lft forever

ルーティング(関係ないdocker0は除外しています)
デフォルトはens192の対向先

# ip -6 route | grep -v docker0
::1 dev lo proto kernel metric 256 pref medium
fd5a:ceb9:ed8d:1::/64 dev br_ipv6_nw proto kernel metric 256 pref medium
fd5a:ceb9:ed8d:fe0a::/64 dev ens192 proto ra metric 100 pref medium
fe80::/64 dev ens192 proto kernel metric 100 pref medium
fe80::/64 dev br_ipv6_nw proto kernel metric 256 pref medium
fe80::/64 dev veth671b926 proto kernel metric 256 pref medium
default via fe80::1 dev ens192 proto ra metric 100 pref medium

Dockerコンテナ

インターフェース
ホストのインターフェースIDはDockerホストから昇順での割り当ての模様。
と、リンクローカルはMACアドレスからの自動採番かな。

# docker exec -it cnt01 bash
[root@45b84c2182a5 /]# ip add
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
82: eth0@if83: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:1a:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.26.0.2/16 brd 172.26.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fd5a:ceb9:ed8d:1::2/64 scope global nodad
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe1a:2/64 scope link
       valid_lft forever preferred_lft forever

ルーティング
デフォルトはULAのDockerホストになるみたい。

# ip -6 route
fd5a:ceb9:ed8d:1::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default via fd5a:ceb9:ed8d:1::1 dev eth0 metric 1024 pref medium

疎通確認

ホスト → コンテナ の通信確認

# ping6 -c 1 fd5a:ceb9:ed8d:1::2 | grep icmp_seq
64 bytes from fd5a:ceb9:ed8d:1::2: icmp_seq=1 ttl=64 time=0.297 ms
# ping6 -c 1 fe80::1%br_ipv6_nw | grep icmp_seq
64 bytes from fe80::1%br_ipv6_nw: icmp_seq=1 ttl=64 time=0.195 ms

コンテナ → ホスト の通信確認

# ping6 -c 1 fd5a:ceb9:ed8d:1::1 | grep icmp_seq
64 bytes from fd5a:ceb9:ed8d:1::1: icmp_seq=1 ttl=64 time=0.114 ms
# ping6 -c 1 fe80::1 | grep icmp_seq
64 bytes from fe80::1%eth0: icmp_seq=1 ttl=64 time=0.129 ms

コンテナ → ホスト → 外部 の通信確認

# ping6 -c 1 dns.google | grep icmp_seq
64 bytes from dns.google (2001:4860:4860::8844): icmp_seq=1 ttl=52 time=6.74 ms

通信経路

概略

dns.google に ping6 したとき、以下のように通信を行います。

HOSTではIPマスカレードして、srcアドレスをHOSTのアドレスに置き換えます。
GATEWAYでは、fd5a:ceb9:ed8d:fe0a::/64 を ROUTINGPREFIX:ff66/64 にNPTv6 しています。

Screenshot from Gyazo

HOSTの設定と動作

DockerホストのIPマスカレードは firewall-cmd --masquerade --zone=public --permanent により以下のルールが追加されています。

# nft list chain ip6 firewalld nat_POST_public_allow
table ip6 firewalld {
        chain nat_POST_public_allow {
                oifname != "lo" masquerade
        }
}

これによりコンテナからのパケットはホストでSNATされます。
conntrackで確認すると、以下のようになっています。

# conntrack -E -p icmpv6
    [NEW] icmpv6   58 30 src=fd5a:ceb9:ed8d:1::2 dst=2001:4860:4860::8888 type=128 code=0 id=38 [UNREPLIED] src=2001:4860:4860::8888 dst=fd5a:ceb9:ed8d:fe0a:ed57:61d8:20eb:aba5 type=129 code=0 id=38
 [UPDATE] icmpv6   58 30 src=fd5a:ceb9:ed8d:1::2 dst=2001:4860:4860::8888 type=128 code=0 id=38 src=2001:4860:4860::8888 dst=fd5a:ceb9:ed8d:fe0a:ed57:61d8:20eb:aba5 type=129 code=0 id=38

ROUTERの設定と動作

ROUTERのルーティングは以下のように設定されています。
(なんでfe80::1にしなかったんだっけ。。。)

Rdc01#sh run | in ::/0
ipv6 route ::/0 Vlan252 FD5A:CEB9:ED8D:FEFC::1

GATEWAYの設定と動作

GATEWAYのインターフェースは以下のように設定されています。
(いまだにCLI使いこなせない。。。)

admin@FWdc01> show interface all
(~省略~)
ethernet1/1.999     271   1    zUntrust         vr:default               999    192.168.1.250/24
                                                                                fe80::b60c:25ff:fe0f:df10/64
                                                                                ROUTINGPREFIX:ffff:192:168:1:250/64
                                                                                fe80::192:168:1:250/128
(~省略~)
ethernet1/2.252     260   1    zTrust           vr:default               252    10.254.252.1/24
                                                                                fe80::b60c:25ff:fe0f:df11/64
                                                                                fd5a:ceb9:ed8d:fefc::1/64
                                                                                fe80::1/128
(~省略~)

GATEWAYのNPTv6は以下のように設定されています。
本当は Prefix64bit ごとに NPTv6のトランスレータを準備しないといけないのですが、手抜きで2セグをまとめています。

"nat66_NPTv6_to_internet; index: 1" {
        nat-type nptv6;
        from zTrust;
        source [ fd5a:ceb9:ed8d:fe0a:0:0:0:0/64  fd5a:ceb9:ed8d:fefc:0:0:0:0/64  ];
        to zUntrust;
        to-interface ethernet1/1.999 ;
        destination any;
        service 0:any/any/any;
        translate-to "src: ROUTINGPREFIX:ff66:0:0:0:0/64 (static-ip) (pool idx: 0)";
        terminal no;
}

これによりパケットはGATEWAYでSNATされます。
NAT後のトラフィックログは、以下のようになっています。
(CLIの確認方法がわからなかった。。。)

Screenshot from Gyazo

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?