IPv6が有効なホストからSOCKS経由でGoogleに繋ごうとすると失敗する
さくらVPSを2台契約しておりまして、
hostB$ ssh -D 1080 username@hostA
という感じで片方のホストをSOCKSサーバーにして、もう片方のホストからSOCKS経由で外に行く、なんて事をやっていました。
しかし、特定のホストだけ接続できない。
例えば以下のようになります。
hostB$ curl --socks5 localhost:1080 "http://www.google.com/" curl: (6) Failed to resolve "www.google.com" for SOCKS5 connect.
勿論SOCKSを経由しなければ
hostA$ curl "http://www.google.com/" <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>302 Moved</TITLE></HEAD><BODY> <H1>302 Moved</H1> The document has moved <A HREF="http://www.google.co.jp/?gfe_rd=cr&ei=XggRVIyJMcGF4AK10YGgBw">here</A>. </BODY></HTML>
hostB$ curl "http://www.google.com/" <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>302 Moved</TITLE></HEAD><BODY> <H1>302 Moved</H1> The document has moved <A HREF="http://www.google.co.jp/?gfe_rd=cr&ei=XggRVIyJMcGF4AK10YGgBw">here</A>. </BODY></HTML>
これ、相当ハマったのですが、以下のようにしたら動きました。
hostB$ curl --socks5 localhost:1080 --ipv4 "http://www.google.com/" <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>302 Moved</TITLE></HEAD><BODY> <H1>302 Moved</H1> The document has moved <A HREF="http://www.google.co.jp/?gfe_rd=cr&ei=XggRVIyJMcGF4AK10YGgBw">here</A>. </BODY></HTML>
そうです、IPv6が問題だったのです。
curlのオプションで、IPv4の使用を強制したら繋がりました。
つながらないホストは、IPv6に対応しているホストでした。
しかし謎なのは、現行のさくらVPSは標準でIPv6に対応しており、2台とも問題なくIPv6通信ができます。
あまり深追いはしていないのですが、OpenSSHのDynamicForwardがIPv6に対応していない?
さて、実際はPHPのcurlからIPv6対応ホストにSOCKS経由で接続できなくて困っていたので、
場当たり的にPHPのcurlもIPv4固定で動作させる事により回避したいと思います。
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
ちなみにこれ、最初は別のホストで動いていたものを新しいVPSに移行したら動かなくなり調べていたのですが、
移行元ホストは古いさくらVPSのインスタンスで、IPv6が無効の状態となっていました。
そのため強制的にIPv4が使われていたため動いていたようです。
時間のあるときにOpenSSHのDynamicForwardとIPv6の関係を調べよう。。
参考
http://www.businesscorner.co.uk/disable-ipv6-in-curl-and-php/