IPv6 で IPv6 Ready なサーバの Nginx にアクセスしようとしたら 404 になったのと IPv6 のこれからの話し

IPv6 で自分のブログ(:80)にアクセスしたら 404 になってた件について

私のブログのリファラを辿ってどこからリンクされているのかなと興味があって見てみたのが発端。
なんかはてなブログから参照されているなーと思って私のブログへのリンクが貼られているのに加えてちょっと上に iframe の埋め込みと思われる Nginx の 404 画面が表示されていた。

はてなブログにほほえまーって思ってたらほほえましいのは私の方だった。
そして自分のブログへのリンクを踏んだら 404 になった。
リダイレクトされるはずだと思ってたが Nginx 404 になってる。
もしかして iframe で表示されてた 404 は私のサーバの Nginx が吐き出していたのである。

ここでの原因は Nginx 自身は IPv4 でしかリッスンしない設定になっていたことによるものである。

80 番ポートなんてリダイレクト専用のバーチャルホスト設定する以外に使わない。
こうでもしないと気付かなかったでしょう。

半年前ぐらいに、はてなブログから自分で持ってるこの WordPress ブログに移行してリダイレクトも設定したのだが
リダイレクトの設定したのははてなと WordPress の記事 URL の体系が異なっていたため。
旧来の記事参照アクセスはしばらくこのはてなブログの URL 体系でアクセスしてくるとかんがえられるため 301 リダイレクトをかましている。

IPv6 は最近のキャリア(ISP)はデフォルトでデュアルスタックでインターネット接続可能な IPv6 アドレスを払い出しているので、限界集落一歩手前の実家もご多分に漏れず IPv6 アドレスが払い出されていた。

さくらの VPS 上にサーバーを構築しているので IPv6 GUA(Global Unicast Address) はデフォルトで付与されていたので Route 53 に DNS レコードとして AAAA レコードも一緒に登録しておいたのでした。
IPv6 で遊んでみたいというのもあった。

Nginx のログを抜粋。ちなみに IPv6 のプレフィックスはドキュメント用のものに置換してあります。
IPv4 用の TEST-NET があったり、ドメイン名を example.com にするのと同様に IPv6 にも TEST-NET 相当のものがあります。

2001:db8::50:d7f8:c233:1 - - [01/Jan/2018:10:12:59 +0900] "GET /entry/2014/11/09/232916 HTTP/1.1" 404 564 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Geck
o) Chrome/63.0.3239.84 Safari/537.36" "-"


2001:db8::50:d7f8:c233:1 - - [01/Jan/2018:10:24:34 +0900] "GET /entry/2014/11/09/232916 HTTP/1.1" 404 564 "http://example.com/entry/2015/08/02/022855" "Mozilla/5.0 (Macintosh; Intel Mac
 OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36" "-"


2001:db8::50:d7f8:c233:1 - - [01/Jan/2018:10:29:54 +0900] "GET /entry/2014/11/09/20141109232916/ HTTP/1.1" 404 63388 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML
, like Gecko) Chrome/63.0.3239.84 Safari/537.36" "-"

2001:db8::50:d7f8:c233:1 - - [01/Jan/2018:10:30:55 +0900] "GET /embed/2014/11/09/232916 HTTP/1.1" 404 63358 "http://example.com/entry/2015/08/02/022855" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36" "-"

IPv6 からのアクセスとなっている。
盛大に自分のブログが見れなくなってれば実家についてさて記事書くぞと思ったら気付くはずだったんですが、
SSL 版は default の設定が入っていたので影響を受けなかったのでした。

/embed/ アクセス oEmbed があったのでそのリダイレクトルールも追記しておいた。
こうゆう標準的な埋め込みプロトコルアクセスもあるのね。

Before

server {
    listen 80;

    # from hatenablog access (normal)
    rewrite ^/entry/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/(.+)$ https://blog.pg1x.com/$1/$2/$3/$1$2$3$4/ permanent;
    rewrite ^(.*)$ https://blog.pg1x.com$1 permanent;

}

server {
    listen 443 default ssl;

After

server {
    listen 80;
    listen [::]:80;

    # from hatenablog access (normal)
    rewrite ^/entry/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/(.+)$ https://blog.pg1x.com/$1/$2/$3/$1$2$3$4/ permanent;
    # from hatenablog access (oEmbed)
    rewrite ^/embed/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/(.+)$ https://blog.pg1x.com/$1/$2/$3/$1$2$3$4/embed permanent;
    rewrite ^(.*)$ https://blog.pg1x.com$1 permanent;

}

server {
    listen 443 default ssl;
    listen [::]:443 ssl;

重要なのは listen [::]:80, [::]:443 の記述です。

また、 1.3.4 以上の Nginx であれば ipv6only=on は不要です。

Option ipv6only=on might not be needed anymore and on the contrary potentially create issues.

http://nginx.org/en/CHANGES

Changes with nginx 1.3.4 31 Jul 2012

*) Change: the “ipv6only” parameter is now turned on by default for
listening IPv6 sockets.

[wnoguchi@mx1 ~]$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
http://blog.pg1x.com/entry/2014/11/09/232916
http://blog.pg1x.com/entry/2014/08/12/175950-mac-mavericks-vagrant-omnibus-nokogiri-install-failure

リダイレクトも、 oEmbed もうまく表示されるのを確認したらこれで完了。

これからの IPv6 の話をしよう

これからは IPv6 だと 10 年以上前に言われてぜんぜん IPv4 グローバル IP アドレスがなくなる気配を見せず、当時は IPv6 は私の生きている間にメジャーとなるのだろうかと思っておりました。
どっかで 「 IPv4 は石油みたいなもんだからな 」というブコメを見てなるほどなと思いました。

こうして今に至るわけですが、最近になってじわりじわりと確実にグローバル IPv6 アドレスが浸透しているのを感じます。
Google は普通に IPv6 に対応してるし、 AWS EC2, VPC も IPv6 に対応し始めている。
NURO も INTERLINK も au光 も、UQ WiMAX 等のモバイルルータもデフォルトで IPv6 を払い出しています。
たぶんインターネット接続を電気水道ガスと同じ感覚で使っている人たちは IPv6 が広まってきていることには気付かないと思います。
まあ、気づかないうちに IPv6 が広まっていくのが理想だと思います。
こうしてインターネットはありふれたインフラとなっているわけですね。
IPv4 がレガシーな Layer 3 プロトコルになるのも近いなと思った次第です。

しかし先日のMITのクラスA IPアドレスを一部 Amazon に売却したのには驚いた。
クラスA グローバルIPアドレスなんて滅多なことではお目にかかれない。
具体的には 18.145.0.0/16 のネットワークを売ったのかな?
ゆうに 65536 個(ネットワークアドレスとブロードキャストアドレスを除けば 65534 個)の連続したアドレス空間。

  1. MIT No Longer Owns 18.0.0.0/8 – Slashdot
  2. Whois-RWS
  3. MIT no longer owns 18.0.0.0/8

IPv6

  1. 対応ページ: pp.440-473
  2. 対応試験: CCNPv2.0 Routing and Switching 300-101J ROUTE
  3. カテゴリ: IPv6
  4. サブカテゴリ: なし
  5. IOS: c3725-adventerprisek9-mz.124-15.T14.bin
  6. Cisco ISR 1841, IOS: c1841-adventerprisek9-mz.151-4.M10.bin

グローバルユニキャストアドレス 2000::/3
ユニークローカルユニキャストアドレス FC00::/7 Effectively FD00::/8
リンクローカルユニキャストアドレス FE80::/10

インターフェイスID

EUI-64
64bit Extended Unique Identifier

MACアドレス(EUI-48)

U/L(Universal/Local) ビット

匿名アドレス(一時アドレス) RFC3041
RFC 3041 – Privacy Extensions for Stateless Address Autoconfiguration in IPv6

マルチキャストアドレス

FF00::/8

エニーキャストアドレス

最も近いノードとの通信。

IPv6 ルート集約

IPv6 アドレスの割り当て

手動設定

ステートレスアドレス自動設定(オートコンフィギュレーション)

RFC2462

ネットワークに接続するとルータからプレフィックスが通知される。

近隣探索プロトコル(NDP; Neighbor Discovery Protocol) を使用する。
RS/RA

Router Solicitation

Router Advertisement

主要なプロトコル

ICMPv6

RFC2463
RFC2470
RFC2461

近隣探索プロトコル(NDP)

Neighbor Discovery Protocol

RFC4861

Router Solicitation(RS)
Router Advertisement(RA)

Neighbor Solicitation(NS)
Neighbor Advertisement(NA)

要請ノードマルチキャストアドレスへの参加義務

R1(config)#do sh run | i ipv6
ipv6 unicast-routing
ipv6 cef
R1(config)#ipv6 unicast-routing
R3#sh run | i ipv6
no ipv6 cef
R2(config)#ipv6 unicast-routing
en
conf t
int f0/0
no shut
int f0/1
no shut
end


en
conf t
int f0/0
no shut
end

en
conf t
int f0/0
no shut
end

en
conf t
int f0
no shut
end

en
conf t
int f0
no shut
end

IPv6 の有効化

R1#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R1(config)#ipv
R1(config)#ipv6 unica
R1(config)#ipv6 unicast-routing
R1(config)#int f0/0
R1(config-if)#ipv
R1(config-if)#ipv6 ena
R1(config-if)#ipv6 enable
R1(config-if)#do sh ipv
% Ambiguous command:  "do sh ipv"
R1(config-if)#do sh ipv6 int
FastEthernet0/0 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::21B:2AFF:FE77:66D2
  No Virtual link-local address(es):
  No global unicast address is configured
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::1:FF77:66D2
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are enabled
  ICMP unreachables are sent
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 200 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.

グローバルユニキャストアドレスの設定

R1(config-if)#ipv6 address 2001:1:1:1::/64 eui-64
R1(config-if)#do sh ipv6 int
FastEthernet0/0 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::21B:2AFF:FE77:66D2
  No Virtual link-local address(es):
  Global unicast address(es):
    2001:1:1:1:21B:2AFF:FE77:66D2, subnet is 2001:1:1:1::/64 [EUI]
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::1:FF77:66D2
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are enabled
  ICMP unreachables are sent
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 200 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.

リンクローカルアドレスをわかりやすいアドレスに変更する。

f0/0 において FE80::1 としよう。

R1(config-if)#ipv6 address FE80::1 link-local
R1(config-if)#do sh ipv6 int f0/0
FastEthernet0/0 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::1
  No Virtual link-local address(es):
  Global unicast address(es):
    2001:1:1:1::1, subnet is 2001:1:1:1::/64 [EUI]
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::1:FF00:1
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are enabled
  ICMP unreachables are sent
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 200 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.

上記トポロジのように設定してみる。
インターフェイス名はちょっと違うのでご注意。

conf t
int f0/0
ipv6 enable
ipv6 address 2001:1:1:1::/64 eui-64
ipv6 address FE80::1 link-local
int f0/1
ipv6 enable
ipv6 address FE80::1:1 link-local
end

conf t
int f0/0
ipv6 enable
ipv6 address 2001:1:1:1::/64 eui-64
ipv6 address FE80::2 link-local
end

conf t
int f0/0
ipv6 enable
ipv6 address FE80::3 link-local
end

conf t
int f0
ipv6 enable
ipv6 address FE80::1:4 link-local
end

conf t
int f0
ipv6 enable
ipv6 address FE80::1:5 link-local
end

設定が終わったこのとき、 IPv6 ネイバーテーブルを確認すると空っぽ。

R2#sh ipv6 neighbors

ping を打ってみる。

リンクローカルアドレスは出力インターフェイスも指定する必要がある。

出力インターフェイス名は省略形ではなくスペース無しで完全なインターフェイス名を書く必要があるようだ。

R2#ping FE80::1
Output Interface:
% Interface required
R2#ping FE80::1 ?
data specify data pattern
repeat specify repeat count
size specify datagram size
source specify source address or name
timeout specify timeout interval
verbose verbose output

R2#ping FE80::1
Output Interface: f0/0
% Invalid interface. Use full interface name without spaces (e.g. Serial0/1)
Output Interface: FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::1, timeout is 2 seconds:
Packet sent with a source address of FE80::2%FastEthernet0/0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 0/1/8 ms

出力の例を見ると % 記述でつなげて出力インターフェイス名を指定できるみたいだ。
YAMAHA でもそんな感じでできた気がする。

R2#ping FE80::1%f0/0
% Unrecognized host or address, or protocol not running.

R2#ping FE80::1%FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::1, timeout is 2 seconds:
Packet sent with a source address of FE80::2%FastEthernet0/0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 0/0/4 ms

R2#sh ipv6 neighbors
IPv6 Address Age Link-layer Addr State Interface
FE80::1 0 001b.2a77.66d2 REACH Fa0/0

対向の R1 でもネイバーテーブルにキャッシュされる。

R1#sh ipv6 neighbors
IPv6 Address Age Link-layer Addr State Interface
FE80::2 3 0024.c431.126e STALE Fa0/0

グローバルユニキャストアドレス、ならびにユニークローカルユニキャストアドレスは出力インターフェイスを指定する必要はない。

R1#sh ipv6 int f0/0
FastEthernet0/0 is up, line protocol is up
IPv6 is enabled, link-local address is FE80::1
No Virtual link-local address(es):
Global unicast address(es):
2001:1:1:1::1, subnet is 2001:1:1:1::/64 [EUI]
Joined group address(es):
FF02::1
FF02::2
FF02::1:FF00:1
MTU is 1500 bytes
ICMP error messages limited to one every 100 milliseconds
ICMP redirects are enabled
ICMP unreachables are sent
ND DAD is enabled, number of DAD attempts: 1
ND reachable time is 30000 milliseconds (using 30000)
ND advertised reachable time is 0 (unspecified)
ND advertised retransmit interval is 0 (unspecified)
ND router advertisements are sent every 200 seconds
ND router advertisements live for 1800 seconds
ND advertised default router preference is Medium
Hosts use stateless autoconfig for addresses.

R2#sh ipv6 int
FastEthernet0/0 is up, line protocol is up
IPv6 is enabled, link-local address is FE80::2
No Virtual link-local address(es):
Global unicast address(es):
2001:1:1:1::2, subnet is 2001:1:1:1::/64 [EUI]
Joined group address(es):
FF02::1
FF02::2
FF02::1:FF00:2
MTU is 1500 bytes
ICMP error messages limited to one every 100 milliseconds
ICMP redirects are enabled
ICMP unreachables are sent
ND DAD is enabled, number of DAD attempts: 1
ND reachable time is 30000 milliseconds (using 30000)
ND advertised reachable time is 0 (unspecified)
ND advertised retransmit interval is 0 (unspecified)
ND router advertisements are sent every 200 seconds
ND router advertisements live for 1800 seconds
ND advertised default router preference is Medium
Hosts use stateless autoconfig for addresses.

R1#ping 2001:1:1:1::2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:1:1:1::2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 0/1/8 ms

こうするとグローバルユニキャストアドレスも IPv6 ネイバーテーブルにのるようになる。

R2#sh ipv6 neighbors
IPv6 Address                              Age Link-layer Addr State Interface
2001:1:1:1::1                               0 001b.2a77.66d2  REACH Fa0/0
FE80::1                                     9 001b.2a77.66d2  DELAY Fa0/0