1
2

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で接続すると接続元IPアドレスがコンテナネットワーク内のIPv4アドレスになる

Posted at

結論としてはタイトルに書いた通りですが、調べた点とかをメモしておきます。

現象

ネットワーク構成はざっくりとこんな感じです。https-portalではリバースプロキシしてwebコンテナのコンテンツを返しています。

画像1.png

このとき、webコンテナでは接続元としてグローバルIPアドレスが取得されることを想定していましたが、実際にはDockerのネットワーク(172.16.0.0/16)内のローカルアドレスが取得されていました。

原因

最初は以下の点を調べてみましたが、どれも原因ではなさそうでした。

  • --userns-remapが原因?
    • 別の環境を用意して--userns-remapを有効にして試してみたが、正常にIPアドレスが取得できた
  • --userland-proxy=trueが原因?
    • docker-proxyを使用していると接続元IPアドレスが取得できないとの情報があったため、--userland-proxy=falseにして試すも再現せず
  • steveltn/https-portalでリバースプロキシさせてるのが原因?
    • そもそもhttps-portalの時点で接続元がローカルアドレスになっているので関係なさそう

最終的にはGitHubのこのコメントを見て、IPv6でサーバに接続していることが問題だと気づきました。

自分の環境で調べてみたところ、IPv6でコンテナへの接続が行われた場合、以下の図のように2001:db8::1(グローバルアドレス)から172.16.0.1(Dockerネットワーク上のアドレス)への変換が行われ、Docker内ではその変換されたIPv4アドレスを使用して通信をしていました。

画像2.png

そのため、IPv6で接続した際に取得できる接続元IPアドレスが次のような状態になり、接続元のIPアドレスが取得できなかったようです。

  • https-portalコンテナ
    • 接続元は172.16.0.1 (変換後のIPアドレス)
  • webコンテナ
    • 接続元は172.16.0.2 (https-portalのIPアドレス)
    • X-Forwarded-Forは172.16.0.1 (変換後のIPアドレス)

対策案

Dockerのデーモンを--ipv6を付けて起動するようにする

「docker」「ipv6」の2つで検索すると一番最初に見つかったのがこのオプションでした。

試していないのですが、調べた限りDockerのIPv6周りは「IPv6ならコンテナそれぞれに固有のIPアドレスを割り振って直接接続すればいいじゃん」という思想のようで、IPv4のようにNATされることはないみたいです1。そのため、--ipv6オプションを指定しても、コンテナにIPv6アドレスの割当が行われるようになるだけで、IPv4のようにホストのIPv6アドレスに接続したらコンテナともIPv6で通信できるわけではないようです。

また、仮にこの方法でIPv6対応するとしても、最低でも/80(MACアドレス64bit分)のサブネットワークが必要みたいでした。自分が今使っているさくらのVPSだと、契約ごとにグローバルIPv6アドレスは1つしか付与されません2。そのため、この方法は実現が難しそうでした。

自分でNATする

自分でIPv6をNATすればIPv6アドレスが1つだけでも対応できそうですが、めんどくさいのと、管理が煩雑になりそうなためこれはやめておきました。3

Docker上ではなく、ホストにリバースプロキシを設置する

ホスト上にリバースプロキシを設置すれば、Dockerの制約は受けないので、IPv6で接続してもIPアドレスを取得できるようになると思います。恐らく、X-Forwarded-ForでIPv6アドレスを渡すようにすれば、コンテナ側でも接続元IPアドレスを取得できるようになると思います。

ただ、せっかくいろいろコンテナ化してるのに、サーバ上にコンテナ化してないサービスを置くのはなんだかなぁという気がするので、今回は見送りました。

IPv6での接続をあきらめる

今のところはIPv6でしか通信できないなんて環境はないだろうから、早急に対処する必要もないかなあということで、今回はこの方法を取りました。

気が向いたら何らかの方法でIPv6でも見れるようにしようと思います。

  1. 数年前にIPv6もNATして欲しいと要望が出されてはいるみたいですが、数年前に出されて未だに実装されていないことを考えると、だいぶ優先度は低そうです。

  2. 蛇足ですが、追加料金を支払うとIPアドレスが追加で付与される、みたいなサービスもこのVPSには無いようです。

  3. このあたりを参考にrobbertkl/docker-ipv6natを使えば自分ですべて構築するよりは楽に済みそうです

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?