PHPでIPv6から適切なwhoisサーバーへ接続し情報を取得するサンプルIT系おじさんのチラシの裏2018年10月~プロフィールAUTHOR:とっちら書きたくなったときに書きたいことを書く雑記ブログ。IT系のネタが多いかも知れません。11:57とっちら1年前の記事に助けられました。14:28とっちらこの記事のお陰で60分録画できるようになりました。16:01とっちらライセンスを明示して貰えると使いやすいのですが。14:37ご回答いただきどうもありがとうございます。21:56とっちら超初心者です。)IPv6への対応、完了していますか?IPが枯渇する、する、というわりに日本では実はけっこう余っているとか、ついこの前、アメリカでも突如1億7500万個ものIPアドレスが放出されたとか聞くし、そもそもIPv6になったからといってWebアプリ側で特に気を付けることなんてないのではないか、そんなふうに思っていました。...CloudFlareを導入するまでは。このブログはWordPressを使って構築していますが、これが、とても、重い。一度でもWordPressを使ったことがある方ならある程度共感してくれると思うのですが、窓から投げ捨てたくなるほどに重いので、なんとか高速化しようと、キャッシュ用のプラグインを入れたり、JavaScriptやCSSをダイエットするプラグインを入れたり、画像をコンパクトにするプラグインを入れたり、とにかくプラグイン...プラグイン...プラグイン...とプラグインだらけになります。WordPressはプラグインが豊富だからすごい、みたいなこと書かれていることもあるけれど、導入しているプラグインのほとんどが高速化関連ではないのか?最初から軽量なシステムならほとんどのプラグインが不要ではないのか?と問い詰めたい。それはともかく、こういった経緯からCloudFlareの導入に踏み切るケースも多いと思うのです。Serverで動いているレンタルサーバーへ移転してからだいぶ快適になりましたが、セキュリティ面でCloudFlareのファイアウォール機能を使いたくなり、CDNの導入に踏み切りました。CloudFlareを導入したおかげで、表示スピードも高速化され、ファイアウォールによってかなりの数の攻撃的なbotを拒否することができ、その効果にはとても満足しているのですが、いかんせん強制的にIPv6へ変更される、という点が悩ましい。IPv6にするとホスト情報を取れないことが多いぼくと同じ、インターネット老人会の人ならよくご存知であろう「確認くん」。うちの環境からアクセスするとホスト情報は「ほにゃらら.v4.enabler.ne.jp」のように表示されます。等の名称が入り、おおよそのプロバイダー情報がわかります。プロバイダーのFQDNではありませんが、V6プラスのサービスを使っていることはわかります。gethostbyaddr関数で簡単に取得できるため、たとえば掲示板システムを作ったとしたら、投稿者の名前と一緒にホスト名もデータベースに保存しておく、みたいな作り方をするんですね。悪質ないたずら行為などがあった場合、ホスト名の一部で判断して、BBExciteからのアクセスだけは一時的に遮断する!みたいな使い方もできるし、通報先の判断にも使えます。ところが、IPv6を導入するとこのホスト名が取れないことがとても増えるのです。ほとんど取れないと言って良いくらい。いうのも、IPアドレスからホスト名の逆引きをするためには逆引き用のレコードの登録が必要であり、IPv4ではプロバイダーが接続時に自動でレコード登録していましたが、IPv6だと膨大な数になるため、逆引きレコードを登録しないのだそうです。IT系のニュースサイトで読んだだけなので本当かどうかは知りません。実体験としてIPv6の逆引きに成功したことがありません。ホスト情報がわからないならwhoisに聞けば良いじゃないwhoisとはIPアドレス/ドメイン名の登録者情報を持つ、インターネット上のデータベースです。いえ、世界中のIPアドレスとドメインの情報を1か所に集約していては回線がパンクしてしまうため、地域ごとに5つに分かれています。詳しく知りたい場合はJPNIC等で解説されているのでそちらをご覧ください。https://www.nic.ad.jp/ja/basics/terms/rir.html5つの地域をまとめるとこんな感じ。問い合わせる(=telnet接続する)と下記のような回答が返ってきます。APNIC全文ではなく一部ですが、これでもJPNICの割り当て範囲、つまり日本からのアクセスだということはわかりますよね。問い合わせると回線事業者の詳細までわかりますが、おおよそで良いならnetnameの項目だけでもプロバイダの判別ができます。みたいな名前が付いているのでプロバイダの判別には十分です。今回は自分が日本からのアクセスだとわかりきっていたので、whois.apnic.netへ接続しましたが、Webサイトのアクセスログから回線情報を調べるためにはどのwhoisサーバーへ問い合わせるべきなのか知る必要があります。IPアドレスから問い合わせ先のwhoisサーバーを知るためにはどうするか。地域ごとに割り当てられているIPv6アドレスの範囲は決まっているIANAのこちらのページ。https://www.iana.org/assignments/ipv6-unicast-address-assignments/ipv6-unicast-address-assignments.xhtmlここでIPv6の範囲ごとにどの地域に割り振られているのか一覧が公開されていました。うーん、5つの地域+それ以外の特別な範囲=IANAということで、6個で済むのかと思いきや、アドレス範囲が飛び地になっていてちょっとだけ複雑ですね...。このリストを連想配列にでもしてプログラム内に持って判断すれば良いでしょう。以前作ったドメインの登録情報を取得するサンプルではwhoisサーバーを200以上リストアップしていたので、それよりはだいぶマシです。参考記事:https://blog.ver001.com/php-whois/PHPでIPv6から適切なwhoisサーバーへ接続し情報を取得するサンプルというわけで、ようやく、本題のPHPサンプルです。流れとしては下記のとおり単純なものです。連想配列についてはianaで公開されている表をそのままコピペしただけ。(例:2400:0000::/12)に含まれているかどうか、これを判断する部分が唯一複雑なところですが、これも実はPHPのページにサンプルがあるんです。形式に変換する」という関数があります。いうような0~255までの数字を4つ組み合わせたのがIPアドレスでしたよね?0~255、つまり8ビット。8ビットが4つで32ビット。32ビットはlong値で表せるのでip2longなどで簡単に数値化できましたが、IPv6は128ビットあるので数値型の変数では表現できません。128ビット整数値型とかあると良いんだけどなー。いうわけで、128ビットの文字列をバイナリデータに変換してくれるのがinet_ptonという関数。/12などの数字はネットマスクと呼ばれ、IPアドレスの先頭から12ビット分が共通範囲だよ、という意味。この範囲内に指定されたIPアドレスが収まっているかどうかチェックしているのが、上のサンプルのip_in_range関数で、その中で呼んでいるmask_ip関数ではPHPマニュアルのサンプルをそのままコピペしてIPアドレスをバイナリ化してマスク処理しています。まとめ本題より前振りのほうが長くなってしまった気もしますが、ともあれ、これでIPv6から適切なwhoisサーバーへ接続し、whois情報を取得することが出来るようになりました。こんな仕組みをアクセスログの解析などで使ったらすっげー迷惑だと思うんですよ...。うちの個人サイトですら月数十万件、一意のIPアドレスに絞っても数万件あるのに、それを全部whoisサーバーに問い合わせるとか、どんなスパムだよっていう。興味本位でプログラムは作りましたが、これを自動化処理などに載せるつもりはありません。管理ページで、気になるIPアドレスをポチっと押したらwhois情報を表示する、とかそんな使い方をするかなぁ。ログに記録されたIPv6のアドレスからISP(プロバイダ)情報を取得する手段については、db-ipが公開しているCSVと突き合わせるのが良いかなぁと思って現在検討中です。https://db-ip.com/db/download/ip-to-asn-lite関連記事PHPでCookieを保持しつつWebスクレイピングする例PHPを使ったWebスクレイピングといえば5年ほど前に投稿した「PHPでHTMLを簡単に解析できるDOMDocument」でほとんどコト足りていましたし、これでは取得できないページでも「VBScrip02023-10-02INSERT文を一括処理して5万件のデータ追加を12倍高速化するもう半年以上前になりますが、「PHPでSQLiteからMySQLへテーブル構造を変換しデータも移行する例」と題して、SQLiteからMySQLへデータベースを移行するPHPスクリプトを公開/解説しまし02022-10-25PHPのjson_encodeで空白が返ってきてしまう場合のエラー確認方法PHPでJSON形式のデータを作る際によく使うjson_encode関数ではエラー(=変換できない事象)が起こっても空文字が返ってくるだけなので、JSON_THROW_ON_ERRORオプションを付け02022-10-14Web版Gmailは絵文字を画像として扱うためCSSの書き方には注意しようPHPでHTMLメールを送信するプログラムを書いていて、なぜか絵文字だけが予期しない形や位置に移動してしまうトラブルにハマったので備忘録として残しておきます。先日投稿した「SQLiteとMySQLにおける一括更新と逐次更新でパフォーマンス比較をしてみる」に関連して、一部のサイトで実験的に並列更新部分をMySQLへ移行しています。コメント投稿直後ならコメントの編集/削除が可能です。※24時間経過するか、新しく投稿した場合は古い投稿の編集や削除は出来ません。※ブラウザでCookieが受け入れられない場合はこの機能は使えません。非公開にチェックを入れたコメントは管理人のみ閲覧できます。コメント投稿のガイドライン誰もが閲覧できるコメント欄ですので個人が特定できる情報等は書き込まないようにしましょう。他人のHPやブログの文章を掲載する場合は著作権法第32条「引用」の条件を満たすかご確認ください。誹謗中傷にあたる表現などは場合によっては法的な責任を問われる可能性があるためご注意ください。とっちらか~るTOP。