0

特定の IP アドレスと IP 範囲が特定のアクションを実行するのをブロックしようとしています。現在、SELECT * FROM blocked WHERE ip=$_SERVER['REMOTE_ADDR']->num_rows が > 0 を返す場合、ユーザーをリダイレクトします。

これは完全な IP アドレスで機能しますが199.90.*.*、たとえばデータベースに入力した場合、どのように一致させることができますか? また、データベースに IP を保存する最良の方法は何でしょうか?

4

3 に答える 3

4

あなたの質問への答えは、使用することlikeです:

SELECT *
FROM blocked
WHERE $_SERVER['REMOTE_ADDR'] like replace(ip, '*', '%')

のワイルドカードlike'%'ではなく で'*'あるため、アスタリスクがパーセント記号に置き換えられます。実際には のような文字列を保存すると思います'199.199.%.%'が、上記はわかりやすくするためのものです。

これで問題は技術的に解決されますが、MySQL はこれらの比較にインデックスを使用しない可能性があるため、別の問題があります (こちらを参照)。影響は、ブロックされたテーブルの大きさによって異なります。100 行ある場合、これは問題にならない可能性があります。100,000 あれば、おそらくそうです。

ブロックされたテーブルにワイルドカードを使用する代わりに、列としてFromIPとを使用することもできToIPます。次に、「199.199. .」のようなものは、単に「199.199.000.000」および「199.199.999.999」として保存されます。クエリは次のようになります。

where $_SERVER['REMOTE_ADDR'] between FromIP and ToIP

そして、あなたは に索引を持っているでしょうblocked(FromIP, ToIP)

于 2013-06-20T18:12:25.377 に答える
0

あなたの最善の解決策は、INET_ATON関数を使用することです。

IPv4 ネットワーク アドレスのドット付きクワッド表現を文字列として指定すると、アドレスの数値をネットワーク バイト オーダー (ビッグ エンディアン) で表す整数が返されます。

したがって、特定の範囲で IP を探したい場合は、次のようなクエリを使用します。

SELECT * FROM blocked WHERE INET_ATON($_SERVER['REMOTE_ADDR']) between INET_ATON(this_ip) and INET_ATON(this_other_ip).

私が思うに、MySQL データベースに IPv4 アドレスを格納する最良の方法は、その関数を使用してint値に変換し、そのように格納することです。また、その表現から IP を取得する場合は、INET_NTOAintを使用します。

IP を として保存するintと、クエリは次のように終了します。

SELECT * FROM blocked WHERE INET_ATON($_SERVER['REMOTE_ADDR']) between this_ip and this_other_ip.

199.90.*.* を使用する代わりに (199.90.0.0) を使用します。

于 2013-06-20T18:32:31.523 に答える
0

最初に完全な IP アドレスを確認し、次に最後のバイトを * でマスクして、それを確認し、次に最後の 2 バイト、というように確認します。このようにして、具体的なものから具体性の低いものへと移行し、ヒットすると IP がブロックされます。これはおそらく最も効率的な方法ではありませんが、ログイン時に一度だけ行う必要があると思います。

簡単にするために、IP アドレスを文字列として保存します。

別の解決策として、IP アドレスをバイト配列として保存することもできますが、それでは何も容易にはならないと思います。たとえば、コマンドライン ツールの SQL ツールを使用すると、保守性が大幅に低下します。

于 2013-06-20T18:05:18.763 に答える