環境はconohaのVPS(CentOS6.5)をレンタルしています。
PHPは5.6です。

conohaでは標準os(CentOS6.5)を選択した場合、17個IPv6がついてきます。
IPv4を追加するのは有料なので、できるだけIPv6を活用したいと思っています。

file_get_contentsにてコンテキストの使用が可能ということでPHPマニュアルにある以下のコードを試してみました。

   

<?php
$opts = array(
    'socket' => array(
        'bindto' => '[自環境のIPv6]:任意のポート',
    ),
);

$context = stream_context_create($opts);
echo file_get_contents('http://www.example.com', false, $context);

?>

上記のようにコンテキストを指定しても

  • file_get_contents(): Invalid IP Address : [自環境のIPv6]

というエラーが出てしまいます。

以下状況です。

  • 当該のIPv6は17個すべてDNS逆引きが可能な状態で設定は正しいものと思います。
  • IPv6、17個すべて試しましたがエラーが出ます(省略表記・フル表記どちらも)。
  • 別途追加したIPv4ではコンテキスト指定(IP切り替え)に成功しています。
  • 接続先のサイトはIPv6に対応しています。

どのようにしたらPHPからIPv6にて外部に出ることができますでしょうか?
IP(IPv6にて)を切り替えてデータが取得できるのであれば方法はfile_get_contentsにこだわりはありません。

よろしくおねがいします。

追記 コメントにて確認頂いた件について情報を追加

  • 1.ping6は成功しています。( ipv6.google.com等のサイトで成功)
  • 2.ip6tablesの設定は以下です。

    :INPUT ACCEPT [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    -A INPUT -p ipv6-icmp -j ACCEPT -A INPUT -i lo -j ACCEPT
    -A INPUT -m state --state NEW -m udp -p udp --dport 546 -d [ 自環境のIPv6の帯域] -j ACCEPT
    -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
    -A INPUT -j REJECT --reject-with icmp6-adm-prohibited
    -A FORWARD -j REJECT --reject-with icmp6-adm-prohibited
    COMMIT

  • 3.ip6tablesを無効にしても出現するエラーに変化はありませんでした。
     

  • 4.php -i | grep -i ipv6の試行結果については以下のようになりました。

    $ php -i | grep -i ipv6
    IPv6 Support => enabled
    IPv6 => Yes

  • 5.PHPプログラムのbindtoの部分を'bindto' => '[0]:0' (osに任せる)にしてみる。

エラーは出なくなりますが、別途所有するサーバに以下のようなスクリプトを用意し接続してみると、取得できるのはインターフェスeth0に紐付いたVPSレンタル時に授与されるデフォルトのIPv4でした。

    <?php
    echo $_SERVER["REMOTE_ADDR"];
  • 6.'bindto' => '[::1]:0'の試行結果は以下のようになりました。

以下のようなエラーとなりました。

file_get_contents(): Invalid IP Address: ::1

上記5.で使用した別サーバのスクリプトにて取得できたIPはデフォルトのIPv4でした。

  • 7.IPアドレスとして適切な形式になってるかの確認(全角文字の有無、省略表記の誤謬)

再度確認しましたが、全角文字等の不適当な文字は入っていませんでした。
::が:になっていないかについては、所有するIPv6にて0000で連続する領域が無いため記述はありません。
また、所有するIPv6にて「0090」のような「0」を省略できる箇所は複数ありますので、再度省略に間違いがないかを確認しました。また0を省略しないフル表記でも再度試行してみましたが、エラーは依然として出ています。

  • 一応の解決?

結論から申しますと、コメントにて示唆いただいた「IPv6の直指定によるfile_get_contents」にて、IPv6コンテキスト切り替えが可能であることがわかりました。

IPv6の直指定であれば、エラーは出ず、なおかつ接続元のIPはIPv6になります。ドメイン指定でなぜエラーが出てしまうのかの疑問はありますが、現状では示唆していただいた方法で目的に叶うので一旦解決とさせていただきたいと思います。

たくさんの助言をいただきありがとう御座います。