www.smiyasaka.com は、 2019 年2月から SSL 化し 通信を暗号化した方式で発信をしています。
● 自分のグローバルIPアドレスの取得方法の解説 ● アクセス数 昨日 84 今日 3
  累計 74,716   

このページは、私が、グローバルIPアドレスを自動表示したいために、勉強した結果を忘備録として まとめたものです。

ルータのグローバル IP アドレスを取得するプログラムは、Linux のコマンドを使用するため、シェルスクリプトと perl で作っています。

以下が、グロバル IP アドレスを取得し、ホームページに表示する為の私が先人の知恵等を参考にして作成したプログラムです。

※※ ドメイン( URL )でホームページが公開できる条件 ※※

外部から、
ドメインでアクセスした時に、自分のサーバ機に到達する条件は、ネームサーバー ( DynamicDNS ) 管理しているグローバル IP アドレスルータの wan 側 の IP アドレス(プロバイダが 割り振った IP アドレス)と一致する必要があります。

一致しない時には、手作業でネームサーバー( DynamicDNS )に登録し直すか、DiCE 等のプログラムを使 用して、自動でネームサーバー( DynamicDNS )に新しいグローバル IP アドレスを登録し直します。

ちなみに、DiCE 等のプログラムの動作は、設定された時間毎(10分毎とか)にアクセス元のグローバル IP アドレスを返してくれるサイトにアクセスし、グローバル IP アドレスの変化を監視し、変化が あった時には、ネームサーバー( DynamicDNS )に新しいグローバル IP アドレスの登録し直しを自動でします。

( 実際、私の場合、IP アドレス更新時間短縮の為、手動でネームサーバの情報を書き換えています。
 DiCE での更新は、毎週ネームサーバへの IP アドレス更新の為にだけ使用しています。 )

※ 注 意 事 項 ※
コマンド・プログラム等を コピペ する時には、全角のスペース が、入っていることがありますので
半角に変換 してから、使用してください。

スマホ対策の為、長いコマンド・プログラム等を継続記号( linux は、"\" 、EXCELマクロは、"_" )で
故意に数行に分割している箇所が有ります。

目    次
[○○○○]のクリックで、その内容が目次の下に表示、再度クリックで非表示になります。


私のサーバ機では、ダイナミックグローバル IPアドレス つまり、私が契約している プロバイダ [ STNet ピカラ ] が割り付けた IPアドレスをネームサーバ [ 私の場合、VALUE-DOMAIN ] に登録し運用しています。
※※ 下記は、今取得したあなたと私のサーバのグローバル IP アドレスです。 ※※

取得した場所 (コマンド等) グローバル IP アドレス
あなたの IP アドレス
( ホームページの    
アクセス情報から取得 )
3.235.107.209
ネームサーバ ( VALUE DOMAIN )
( dig コマンドで取得 )
133.123.138.248
モデム ( ルータ )
(プロバイダの STNet が割付)
133.123.138.248

1. ルータが、管理しているグローバルIPアドレスの取得
( NEC Aterm WH822N・Aterm WH832A )

ルータ( NEC Aterm WH822N )が、管理しているグローバルIPアドレス( wan 側の IP アドレス)は、 ルータに、アクセス(http://192.168.0.1/)して、ID とパスワードを入力し、[情報][現在の状態] [拡張表示]で見ることが、できるので、この情報から、グローバルIPアドレスの部分だけを抜き出 します。
ルータのグローバルIPアドレスは、プロバイダー(私の場合、STNet)が割付けたアドレスで、
ルータ の電源のON/OFFで再割付けされ変更してしまいます
当然ですが、プロバイダーの都合( 機器のメンテナンス等 )で勝手に変更されてしまいます。

● プログラム( シェルスクリプト )の作成
以下が、したプログラム(ipcheck.sh)です。

※参考情報 このプログラムは、シェルスクリプトで作成した方が簡単になるようです。
(○○○は、ID ×××は、パスワードを意味します。)

※1 リスト内のコメントは、グローバルIPアドレスが、
133.123.130.65 の時のものです。
コメントが沢山入っていますが、プログラムがあまりにも簡単なので、処理の流れを忘れないた めに、入れています。 必要な行は、10行しかありません。

※2 wgetでダウンロードしたデータは、URLのファイル名でシェルを実行したフォルダに保存されます。
( cron で実行した時は、root・コマンドで実行した時には、プログラムが実行したパス上に保存 されます。)

※3 ルータの機種が違う時には、下記のプログラム通りでは、グローバルIPアドレスの取得は、でき ませんのでルータにアクセスして管理画面を表示し、そのHTMLのソースリストを解析して 探す 文字列・消去する文字列を変更してください。

※4 プログラムは、分かりやすくする為、sed を分割して実行させています。

※5 漢字が含んだ行の抽出の場合には、必要に応じてアプリ nkf 等でコード変換( 内部コードは、 UTF8 です。)が必要になります。

確認方法として、Tera Term( ユーザ権限 )から実行した時に上手く行き、cron で実行させた時 に上 手く行かない時には、漢字コードの変換が必要です。参考まで。
( 日本語文字コードをインストール後の初期設定で UTF8 ---> eucJP にしている場合は、漢字 コードの変換が必要になると思います。必要に応じて確認をしてください。)

※※ 注意 1 ※※ ( H24.04.27 追記 )

ルータへのアクセスで、必ず一回目の承認が、エラーになるため、ホームページから、下 記プログラム(ipcheck.sh)を実行すると、その都度 apache のエラーログに記録されます。
 そのため、現在は、crontabで、4時間ごとに実行させ、取得データをファイルに記録し、 ホームページ側から、ファイルの内容を表示する様に改造しています。
これにより、apacheのエラーログの記録が、無くなりました。また、ルータへの負担も軽減され ました。
 グローバルIPアドレスは、滅多に変わることがないので、一日に、一回でも良いのですが、特に 根拠はありませんが、4時間毎にしています。

※※ 注意 2 ※※ ( H24.07.28 追記 )

wget で 、書込みフォルダの 属性を 666 か、777 することを忘れないようにしてください。
-P オプションを付けると任意のフォルダへの書込みか出来ます。
これを忘れて、HTMLから、wget を実行した後、apache のログファイルを見ると、Cannot write to `書き込み先のフォルダ名・ファイル名` (Permission denied).
( このエラーは、書込み権限が無いので、書き込みできませんという意味です。 )となり、書込 みが実行されて無いことがわかります。


#!/bin/sh
# ファイル名 : ipcheck.sh
#
NEC Aterm WH822N の  情報-->現在の情報-->拡張表示のHTMLソースデータを取得する。
#
192.168.0.1/index.cgi/info_mainのHTMLのソースファイルを取得する。
#
取得結果は、ファイル名  info_main  で格納される。
#
wget --http-user ○○○ --http-passwd ××× \
http://192.168.0.1/index.cgi/info_main
#
ゲットしたソースリストから、 "<td class='small_item_td2' colspan='2'> "
#
に一致する行のみを抽出する。
IP1=$(grep "<td class='small_item_td2' colspan='2'> " info_main )
#echo " 1 $1"
#echo " IP1 $IP1"
#
上記の実行結果の例
#IP1 : <td class='small_item_td2' colspan='2'> 192.168.0.1/24</td>
# <td class='small_item_td2' colspan='2'>
133.123.130.65</td>
IP3=$(echo $IP1 | sed -e "s/[']//g")
<---- 'の削除
#echo " IP3 $IP3"
# IP3 : <td class=small_item_td2 colspan=2> 192.168.0.1/24</td>
# <td class=small_item_td2 colspan=2>;
133.123.130.65</td>
#
IP4=$(echo $IP3 | sed -e 's/td2//g' -e 's/=2//g')
<---- td2,=2 の削除
#echo " IP4 $IP4"
#
上記の実行結果の例
# IP4 : <td class=small_item_ colspan> 192.168.0.1/24</td>
# <td class=small_item_ colspan>
133.123.130.65</td>
#
IP4=$(echo $IP4 | sed -e "s/[^0-9\.]//g")
<---- 数字と "." 以外削除
#echo " IP4 $IP4"
#
上記の実行結果の例 133.123.130.65 がグローバルIPアドレスです。
#IP4 : 192.168.0.124
133.123.130.65
# 192.168.0.124 は、192.168.0.1/24 の "/" が無くなって変わった数値列です。
# 不要なので、下記で削除します。その結果、133.123.130.65 だけが残ります。
IP=$(echo $IP4 | sed -e "s/192.168.0.124//g")
<---- 192.168.0.124の配列を削除
echo "$IP"
<---- ここでグローバルIPアドレスだけが、出力できます。
#
#
info_mainのデータ、不要なのでファイルを削除する。
#
これをしないと、info_main のファイルが沢山作られます。
rm info_main
#

上記プログラムは、コメントを沢山入れているのでごちゃごちゃしていますが、本文は、下記のように少ししかありません。

#!/usr/bin/sh
#
wget --http-user ○○○ --http-passwd ××× \
http://192.168.0.1/index.cgi/info_main
#
IP1=$(grep "<td class='small_item_td2' colspan='2'>    " info_main )
#
IP3=$(echo $IP1 | sed -e "s/[']//g")
#
IP4=$(echo $IP3 | sed -e 's/td2//g' -e 's/=2//g')
#
IP4=$(echo $IP4 | sed -e "s/[^0-9\.]//g")
#
IP=$(echo $IP4 | sed -e "s/192.168.0.124//g")
echo "$IP"
#
rm info_main

 (※) --http-user ○○○ --http-passwd ××× の○○○・×××は、
 NEC Aterm WH822Nにアクセスするための、ID・パスワードです。
 5GB wifi 対応 NEC Aterm WH832A も同じプログラムで取得できました。
● 以下は、ルータ(NEC Aterm WH822N)から取得した管理画面のHTMLのソースリストです。
(一行が長い部分は、数行にしています。
  このリストの時のグローバルIPアドレスは、
133.123.130.65 です。)

(前 省略)
 <tr class='advView'>
 <td colspan='2'><h2>LAN側状態<input type='image' class='help' alt='help'
  value='ヘルプ' src='/common/help_btn.gif' onclick="HelpShow(event,
  '本商品のLAN側の状態を表示します。');return false;" /></h2></td>
 </tr>
 <tr class='advView'>
 <td class='small_item_td'>IPアドレス/ネットマスク<input type='image' class='help'
  alt='help' value='ヘルプ' src='/common/help_btn.gif' onclick="HelpShow(event,
  '本商品で使用するLAN側のIPアドレス/ネットマスクを表示します。');
return false;" /></td>
 
<td class='small_item_td2' colspan='2'> 192.168.0.1/24</td>
 </tr>
 <tr class='advView'>
 <td colspan='2'><h2>接続先1 [接続先1] 状態<input type='image'
class='help' alt='help'
  value='ヘルプ' src='/common/help_btn.gif' onclick="HelpShow(event,
  '本商品の接続先1の状態を表示します。');return false;" /></h2></td>
 </tr>
 <tr class='advView'>
<td class='small_item_td'>WAN側IPアドレス<input type='image' class='help' alt='help'
  value='ヘルプ' src='/common/help_btn.gif' onclick="HelpShow(event, '接続先1
で使用するWAN側のIPアドレスを表示します。');return false;" /></td>
<td class='small_item_td2' colspan='2'> 133.123.130.65 </td>
 </tr>
 <tr class='advView'>
 <td class='small_item_td'>WAN側プライマリDNS<input type='image' class='help'
  alt='help' value='ヘルプ' src='/common/help_btn.gif' onclick="HelpShow(event,
  '接続先1で使用するWAN側のプライマリ(優先)DNSサーバを表示します。')
;return false;" /></td>
 <td class='small_item_td2' colspan='2'>218.231.54.19</td>
 </tr>
 <tr class='advView'>
 <td class='small_item_td'>WAN側セカンダリDNS<input type='image' class='help'
   alt='help' value='ヘルプ' src='/common/help_btn.gif' onclick="HelpShow(event,
   '接続先1で使用するWAN側のセカンダリ(予備)DNSサーバを表示します。')
;return false;" /></td>
 <td class='small_item_td2' colspan='2'>218.231.54.3</td>
 </tr>
    (後 省略)


○ perlのプログラム上で ipcheck.sh を実行させる方法です。

以下が、perlで、作成したプログラムです。


#
# Aterm WH822Nが持っているグローバルIPアドレスを
# シェルスクリプト(ipcheck.sh)を実行して取得する。
# パスの設定は、フルパスで。
#
$atermip = `/var/www/html/○○○○/ipcheck.sh`;
#


2. digコマンドでネームサーバが、管理しているグローバルIPアドレスを取得

nslookup www.smiyasaka.com でも、自分のグローバルIPアドレスを取得できますが、digコマンドの 情報量が多いので、こちらで実現してみました。

以下が、シェルスクリプトで、作成したプログラム(ipnamesrv.sh)です。
※ リスト内のコメントは、グローバルIPアドレスが、
133.123.130.65 の時のものです。
ドメインを換えるだけで、他のドメインからのグローバルIPアドレスの取得ができます。

#!/bin/sh
# ファイル名 : ipnamesrv.sh
# H23.12.06 作成 by S.Miyasaka
# ネームサーバーからグルパルIPアドレスを取得する。
# 取得結果は、ファイル get_data に格納される。
#
dig smiyasaka.com > get_data
#
#以下のようになることがあるので対策する必要がある。
#
smiyasaka.com. 1200 IN A 133.123.130.65
#
smiyasaka.com. 1200 IN NS ns1.value-domain.com.
#
smiyasaka.com. 1200 IN NS ns2.value-domain.com.
#
#
ゲットしたソースリストから、 "smiyasaka.com." と "A" がある行のみを抽出する。
#
IP1=$(grep "smiyasaka.com." get_data | grep "A")
#
#echo "IP1 : $IP1"
#
IP3=$(echo $IP1 | sed -e "s/ //g")
<---- space delete
#echo "IP3 : $IP3"
#
#
";smiyasaka.com.INAsmiyasaka.com......" 削除(.は、ワイルドカード文字)
#
IP4=$(echo $IP3 | sed -e "s/;smiyasaka.com.INAsmiyasaka.com......//g")
#
#echo "IP4 : $IP4"
#
#
数字と"."以外削除しIPアドレスだけにする
#
IP5=$(echo $IP4 | sed -e "s/[^0-9\.]//g")
#
#
IPアドレスの出力
#
echo "$IP5"
#
get_dataのデータ、不要なのでファイルを削除する。
#
rm get_data
#


○ perlのプログラム上で ipnamesrv.sh を実行させる方法。

以下が、perlで、作成したプログラムです。

# dig smiyasaka.com コマンドをシェルスクリプト

#(ipnamesrv.sh)を実行して取得する。
#   パスの設定は、フルパスで。
#
$myip = `/var/www/html/○○○○/ipnamesrv.sh`;
#

● 以下は、dig smiyasaka.comコマンド直接実行した時のリスト。
グローバルIPアドレスは、;; ANSWER SECTION:の次の行で示されています。
Aのリストは、時間をおいて、digを実行した時のリストで、ネームサーバの情報があります。
@のリストは、連続して、digを実行した時のリストです。
  ※ 私のドメインの次の数字は、コマンドを実行するごとに変わります。

   @グローバルIPアドレスのみの結果リスト


; <<>> DiG 9.6-ESV-R4-P3 <<>> smiyasaka.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64561
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;smiyasaka.com.IN A

;; ANSWER SECTION:
smiyasaka.com. 893 IN A 133.123.130.65

;; Query time: 1 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Thu Dec 8 09:37:37 2011
;; MSG SIZE rcvd: 47

   Aネームサーバのデータ表示のある時の:結果リスト


; <<>> DiG 9.6-ESV-R4-P3 <<>> smiyasaka.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37910
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
;smiyasaka.com.IN A

;; ANSWER SECTION:
smiyasaka.com. 1200 IN A 133.123.130.65

;; AUTHORITY SECTION:
smiyasaka.com. 1200 IN NS ns1.value-domain.com.
smiyasaka.com. 1200 IN NS ns2.value-domain.com.

;; Query time: 56 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Thu Dec 8 09:52:51 2011
;; MSG SIZE rcvd: 96

上記の処理を perl で作成したらこんなに簡単になりました。H25.05.03
※※ 最近判明した事 ※※
dig www.smiyasaka.comdig smiyasaka.com の出力結果が違う事。
dig www.smiyasaka.com の方が出力結果が少ないので下記の様に perl でプログラムを作成 してみました。 参考にしてください。

#!/usr/bin/perl
#------------------------------------------------
# ネームサーバーからグルパルIPアドレスを取得する。
#------------------------------------------------
#
「変数の宣言を強制する。使用する変数のスコープ(有効範囲)を厳格に求める。」宣言を
#
して置く。
use strict;
#------------------------------------------------
#
ドメインで dig コマンドを実行し、パイプで
#
結果を get_data に格納する
#
open( get_data, "dig www.smiyasaka.com |");
#
while(<get_data>) {
 #
 chomp;   
<---- 改行コードを削除
 #
スペースで分割して配列に代入
 my @Data = split(" ", $_ );
 #
先頭がドメインの行を抽出
 if ( $Data[0] eq 'www.smiyasaka.com.' ){
  #
IPアドレスを出力
  #
   print $Data[4], "\n";
  #
 }
}
close(get_data);


3. perlの関数 inet_aton を使用して、グローバルIPアドレスを取得する方法

 以下が、perlで、作成したプログラムです。 $host = 'www.smiyasaka.com';    <---- 自分のホスト名
#
use Socket;
#
$myip = inet_ntoa(inet_aton($host));
<---- 自分のグローバルIPアドレス取得

解 説
use Socket; ……… ネットワークプログラムで使用するperlの関数を使用する宣言をする。
inet_aton($host) ……… $hostに設定されているホスト名をIPアドレスに変換する。
inet_ntoa(○○○) ……… IPアドレスを表示可能な型式に変換する。


4. perlの環境変数を使用して、アクセスしてきたグローバルIPアドレスを取得する方法。

あなたのグローバルIPアドレスとあなたのホスト名が、取得できます。
以下が、perlで、作成したプログラムです。

#
#
アクセス先のIPアドレスを取得
#
$ipaddr = $ENV{'REMOTE_ADDR'};
<---- あなたのグローバルIPアドレス取得
#
#
IPアドレスからホスト名を取得
#
$hostname = gethostbyaddr(pack("C4",split(/\./,$ipaddr)),2);
#
ホスト名を取得出来ない時には、「不明」にする。
if(!$hostname) {
  $hostname = "不明";
}

この結果は、以下の様な情報が取得できます。
REMOTE_ADDR = 133.123.130.65
ホスト名が、取得できないときには、"不明" の文字になります。
HOST_NAME = opt-133.123.130.65.client.pikara.ne.jp


5. windowsでグローバルIPアドレスを取得する方法

ドメインからグローバルIPアドレス・グローバルIPアドレスからホスト名の取得は、windowsのコマ ンドプロンプトとから、 nslookupコマンドで行います。
※ 参考情報 ※ windowsのコマンドプロンプトが見つからない時には、「 プログラムとファイル の検索 」から、cmd.exe と入力検索をして、プログラム(1)の下に表示した cmd.exe をクリック してください。
nslookup www.smiyasaka.com
この結果は、以下の様にグローバルIPアドレスが取得できます。


C:\Users\miyasaka>nslookup www.smiyasaka.com
サーバー: web.setup
Address:   192.168.0.1

権限のない回答:
名前: www.smiyasaka.com
Address: 133.123.130.65
-------------------------------------------------------------------------
nslookup 115.30.180.233
この結果、以下の様にホスト名が取得できます。
-------------------------------------------------------------------------
C:\Users\miyasaka>nslookup 133.123.130.65
サーバー: web.setup
Address: 192.168.0.1

名前: opt-133.123.130.65.client.pikara.ne.jp
Address: 133.123.130.65


TOPへ戻る