諸事情により言語側での IP チェック処理をしたくないため、MySQL で完結出来ないかなぁと探してみたのですが、ピンポイントで欲している情報がなかったため、色々試行錯誤した結果のメモ的な。
◆やりたいこと
- DB 上に IP およびネットマスクが登録されている
- 接続元 IP が DB に登録されている情報にマッチするかチェック
- OK であれば、先へ進める
- NG であれば、もちろん弾く
まず、テーブルとサンプルデータを用意。
Yahoo! 様と Google 様にご協力いただきました(勝手に)
本当であれば Yahoo! 様は2つ、Google 様は3つあるのですが、各1つずつ利用サンプルとして利用させていただきました。
DROP TABLE IF EXISTS `tbl_IPMask`;
CREATE TABLE `tbl_IPMask` (
`id` int(10) unsigned auto_increment NOT NULL,
`ip` int(10) unsigned NOT NULL,
`mask` int(10) unsigned NOT NULL,
`name` varchar(40) collate utf8_bin NOT NULL,
`cdate` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_ip` (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO tbl_IPMask values
(0, INET_ATON(’124.83.128.0′), INET_ATON(’255.255.128.0′), ‘yahoo.co.jp’, CURRENT_TIMESTAMP),
(0, INET_ATON(’74.125.0.0′), INET_ATON(’255.255.0.0′), ‘google.co.jp’, CURRENT_TIMESTAMP);
1.登録済みネットマスクの取得
DB に登録してあるネットマスクをユニークで抜き出します。
2.接続があった IP をチェック
MySQL には INET_ATON() と INET_NTOA() という関数があるので、これを利用します。
MySQL :: MySQL 5.1 リファレンスマニュアル :: 11.10.4 その他の関数
取得したユニークなマスクの分だけループして以下の SQL を回します。
Yahoo! 様の場合「124.83.139.192」Google 様の場合「74.125.91.104」から接続があったこととします。
SELECT COUNT(id) FROM tbl_IPMask WHERE ip=(INET_ATON(’124.83.139.192′) & 4294934528);
– Google 様の場合
SELECT COUNT(id) FROM tbl_IPMask WHERE ip=(INET_ATON(’74.125.91.104′) & 4294901760);
上記を実行すると「1」が返ってきます。「0」が返ってきた場合、NG なので弾きます。
登録されている情報にもよりますが、「0=NG」「0<>OK」とした方が良いかと思われます。
もっと良いやり方があれば、是非に教えていただければ!
via.MySQL :: MySQL 5.1 リファレンスマニュアル :: 11.10.4 その他の関数
