この一連の記事は書きかけです。
今後、更新を中止する可能性もありますのでご了承ください。
次回:
1. やりたいこと
Apache 2.4 以降で稼働しているwebページへのアクセスを "ISP単位で" 集計し、
極端な高頻度でアクセスがある ISP からのアクセスがあった場合は、一定期間 429 Too Many Requests を返すようにしたい。
ISPの同一性判定にはAS番号を用いる。
1-1. 実験環境
- OS: Rocky Linux 9
- http(s)サーバ: Apache/2.4.62
- サーバ設定ファイル (通称
httpd.conf) のパス:/etc/httpd/conf/httpd.conf - (ユーザ:グループ):
apache:apache - ドキュメントルート:
/var/www/html
- サーバ設定ファイル (通称
- php: PHP 8.0.30 (cli)
- パス:
/usr/bin/php
- パス:
- SQLite3(phpに同梱されているもの): version 3.34.1
- その他インストールしたもの
-
nanoエディタ: version 5.6.1
-
1-2. ISPと「AS番号」とは
インターネットサービスプロバイダ。
「プロバイダに開示請求」と言った文脈でも出てくるプロバイダのことで、ネット利用者をインターネットに繋げる事業者。
日本国内の例で言えば、ドコモ、So-net、KDDI、NUROなど。
ISPは、ネット利用者とインターネットの架け橋であると同時に、「インターネットを構成するネットワークの単位」の一種でもある。「インターネットを構成するネットワークの単位」のことをAS (自律システム) という。
平たく言えば、AS同士の相互通信によって、
ネット利用者A
<-> Aさんの利用するISP(AS) // ここから インターネット
<-> 他のAS1
<-> ...(全部AS)...
<-> Bさんの利用するISP(AS) // ここまで インターネット
<-> ネット利用者B
というように繋がっている。
ASにはそれぞれ固有の「AS番号」が振られている。
なので、AS番号を特定できれば、それがそのままISPの識別が出来たということになる。 →厳密には違うので、気になる人は「蛇足」を読んでください。
蛇足
本当は、ISPとAS番号は一対一対応にはなっていない。
なので厳密にISP単位でのアクセス制限をしたいのであれば、別の方法を検討する必要がある。
「一つのISPが複数のAS番号を持つ場合」も、逆に「複数のISPが共通のAS番号を持つ場合」もある。
例えば、大企業が地域や国ごとにAS番号を分けている場合や、
B社がA社に吸収合併されて一つのISPになったにも関わらず、AのAS番号とBのAS番号を両方使い続ける場合などは、
「一つのISPが複数のAS番号を持つ場合」に相当する。
また、複数の子会社ISPが、親会社の一つのAS番号を共用している場合は、
「複数のISPが共通のAS番号を持つ場合」に相当する。
(蛇足 ここまで)
2. 手順
次の手順で、今回のやりたいこと
極端な高頻度でアクセスがある (AS番号) からのアクセスがあった場合は、一定期間 429 Too Many Requests を返す
を実現する。
- Apache で、リクエストごとにphpを実行できるようにする
- Apache と phpプログラムで、リクエストごとに ipアドレスを記録できるようにする
- Apache と phpプログラムで、アクセス可否を判定できるようにする (仮)
- phpプログラムで、ipアドレスから AS番号を求め、AS番号からipアドレス範囲を求める
- Apache と phpプログラムで、アクセス可否を判定できるようにする (本番)
- 429 Too Many Requests ページをカスタマイズする
2-1. 手順1の目的
まず、「アクセスの多いAS番号だけ 429 Too Many Requests に転送する」という機能は Apacheには無い。
そこで、リクエストごとにApache から phpプログラムを呼んで、phpプログラムのほうで何とかしたい。
そのためにまずは「リクエストごとに phpを実行する」を実現するのが手順1である。
2-2. 手順2~3の目的
手順1で Apache と phpプログラムを連携させる際に、
- Apache が phpプログラムに ipアドレスを渡す必要がある
- (phpプログラムは、 ipアドレス を受け取らない限り、AS番号の求めようがない)
- Apache は phpプログラムから判定結果を受けとる必要がある
- (Apacheが判定結果を受け取れなければ、phpプログラムに判定を任せた意味がない)
そのため、ipアドレスの受け渡しを手順2で実現し、
判定結果(ダミー)の受け渡しを手順3で実現する。
手順3で、ダミーの判定結果を受け渡しするのは、判定プログラムをまだ書いていない(手順4以降で書く)からである。
2-4. 手順4の目的
phpプログラムで、「そのAS番号が429 Too Many Requests に転送されるべきであるか」を判定するには、
「ipアドレスからAS番号を特定する」仕組みがそもそも必要である。
これには外部API ipinfo.io を利用するのだが、毎回APIを呼んでいては先方に多大なご迷惑をかけてしまう。
そこで、「AS番号からipアドレス範囲を求める」ことをしてその結果をデータベースに保存しておくことにする。
データベースに情報があれば、APIを呼ばずに済む。
「AS番号からipアドレス範囲を求める」のには、別の外部API RIPEstat を利用する。
このプログラムを書くのが手順4である。
2-5. 手順5~6の目的
(明らかだろう。説明を省略する。)
次回: