
HTTPサーバの負荷
Windowsでは SMB(Server Message Block)、Linuxでは NFS(Network File System)、Windows・Linux共通のものとして CIFS(Common Internet File System)と呼ばれる通信プロトコルでファイル共有を行う。
これに対して HTTP(Hypertext Transfer Protocol)は WWW(World Wide Web)のために開発されたプロトコルで、RFCによって標準化されている。
両者の決定的な違いは、SMB、NFS、CIFSがステートフルなのに対し、HTTPはステートレスであることだ。

コンピュータ間の通信(プロトコル)はキャッチボールに似ている。
まず、通信相手に接続開始の掛け声をかけ、相手は受信準備が整ったことを返答する。そしてデータやファイルのやり取りをはじめる。このときも、受信側は、ちゃんと受信できていることを逐一応答する。すべての通信が終わったら、通信を切断すると連絡し、相手が切断したことを確認する。この接続開始から切断までの一連の通信をセッションと呼ぶ。
この一連の作業がプロトコルである。ステートフルは、セッション中の通信状態をお互いが保持する。一方のステートレスは、データやファイルのやり取りは1回だけで、その都度セッションが切れる。ステートレスでは、複数のファイルの送受信を行うには接続と切断を繰り返し行う必要がある。

一見するとステートフルの方が優秀なプロトコルに見えるが、通信状態が悪いとセッションの維持が難しくなり、通信状態を保持していることがかえって足枷となってしまう。ステートレスであれば、通信状態が悪いときには再度セッションし直せば(再読み込みすれば)解決する。
インターネット黎明期には、いまほどネットワーク回線が安定していなかったので、HTTPプロトコルはステートレスの方が都合がよかったのである。

ステートレスでは接続と切断を繰り返すので、サーバの負荷が大きい。その後 WWWは進化し、ECサイトのように前ページで入力した商品の内容を記憶したりするために Cookieを使ってセッションを継続しているように見せかけるようになった。このCookieも、毎回送受信されるため、サーバへの負荷となっている。

HTTPサーバ側も負荷分散システムを導入するなどして対策は講じているものの、同じURLや同じサーバに対して連続的にHTTP通信することは、そのHTTPサーバに対して余計な負荷をかけることになりかねない。
とくに画像や動画といったファイルサイズが大きいファイルを連続的にダウンロードされると負荷が大きい。そこで、Apacheで、指定した拡張子をダウンロードされない直リン拒否設定をすることにした。
これに対して HTTP(Hypertext Transfer Protocol)は WWW(World Wide Web)のために開発されたプロトコルで、RFCによって標準化されている。
両者の決定的な違いは、SMB、NFS、CIFSがステートフルなのに対し、HTTPはステートレスであることだ。

コンピュータ間の通信(プロトコル)はキャッチボールに似ている。
まず、通信相手に接続開始の掛け声をかけ、相手は受信準備が整ったことを返答する。そしてデータやファイルのやり取りをはじめる。このときも、受信側は、ちゃんと受信できていることを逐一応答する。すべての通信が終わったら、通信を切断すると連絡し、相手が切断したことを確認する。この接続開始から切断までの一連の通信をセッションと呼ぶ。
この一連の作業がプロトコルである。ステートフルは、セッション中の通信状態をお互いが保持する。一方のステートレスは、データやファイルのやり取りは1回だけで、その都度セッションが切れる。ステートレスでは、複数のファイルの送受信を行うには接続と切断を繰り返し行う必要がある。

一見するとステートフルの方が優秀なプロトコルに見えるが、通信状態が悪いとセッションの維持が難しくなり、通信状態を保持していることがかえって足枷となってしまう。ステートレスであれば、通信状態が悪いときには再度セッションし直せば(再読み込みすれば)解決する。
インターネット黎明期には、いまほどネットワーク回線が安定していなかったので、HTTPプロトコルはステートレスの方が都合がよかったのである。

ステートレスでは接続と切断を繰り返すので、サーバの負荷が大きい。その後 WWWは進化し、ECサイトのように前ページで入力した商品の内容を記憶したりするために Cookieを使ってセッションを継続しているように見せかけるようになった。このCookieも、毎回送受信されるため、サーバへの負荷となっている。

HTTPサーバ側も負荷分散システムを導入するなどして対策は講じているものの、同じURLや同じサーバに対して連続的にHTTP通信することは、そのHTTPサーバに対して余計な負荷をかけることになりかねない。
とくに画像や動画といったファイルサイズが大きいファイルを連続的にダウンロードされると負荷が大きい。そこで、Apacheで、指定した拡張子をダウンロードされない直リン拒否設定をすることにした。
RewriteRule による直リン拒否設定
Apacheの mod_rewriteモジュールは、URLの書き換えやリダイレクト処理を行う――主機能からは想像しにくいのだが、これを使うことで直リンを拒否できる。

まず、mod_rewriteモジュールが有効になっていることを確認する。

RewriteCond は、後述する RewriteRule の実行条件を定義する。
ここでは、変数 %{HTTP_REFERER}――つまりリファラ(直前にアクセスしていたページ) が !^http(s)?://www.pahoo.org にマッチすれば――つまり、ぱふぅ家ホームページのURLにマッチしなければ、後述の RewriteRule を実行する――つまり、直リンできないようにするという設定になる。NCフラグは、マッチング時に大文字・小文字を区別しないことを指定する。この RewriteCond は自サイトに合わせて変更してほしい。

RewriteRule は
ここでは、正規表現パターンは \.(jpg|jpeg|png|gif|webp)$ なので、前述の拡張子のいずれかで終わるURLにマッチする。置換URLは - で、当然、置換先は存在しない。Fフラグは HTTPステータスの403 Forbidden を返す。

動画や圧縮ファイルの直リン(直ダウンロード)も禁止したければ、RewriteRule の正規表現パターンに追加すればいい。

まず、mod_rewriteモジュールが有効になっていることを確認する。
sudo a2enmod rewriteもし無効なら、次のコマンドで有効化する。
sudo systemctl restart apache2たとえば画像ファイル(拡張子 .jpg .jpeg .png .webp .gif)の直リンを禁止したければ、.htaccessファイルに次のように追記する。
<IfModule mod_rewrite.c>まず、RewriteEngine On で mod_rewriteモジュールを有効化する。
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http(s)?://www.pahoo.org [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F]
</IfModule>

RewriteCond は、後述する RewriteRule の実行条件を定義する。
RewriteCond 文字列|変数 正規表現パターン [フラグ]のように記述し、文字列または変数が正規表現パターンにマッチしたら、RewriteRule を実行する。
ここでは、変数 %{HTTP_REFERER}――つまりリファラ(直前にアクセスしていたページ) が !^http(s)?://www.pahoo.org にマッチすれば――つまり、ぱふぅ家ホームページのURLにマッチしなければ、後述の RewriteRule を実行する――つまり、直リンできないようにするという設定になる。NCフラグは、マッチング時に大文字・小文字を区別しないことを指定する。この RewriteCond は自サイトに合わせて変更してほしい。

RewriteRule は
RewriteRule 正規表現パターン 置換URL [フラグ]のように書く。リクエストURLが正規表現パターンにマッチしたら、置換URLに置換する。
ここでは、正規表現パターンは \.(jpg|jpeg|png|gif|webp)$ なので、前述の拡張子のいずれかで終わるURLにマッチする。置換URLは - で、当然、置換先は存在しない。Fフラグは HTTPステータスの403 Forbidden を返す。

動画や圧縮ファイルの直リン(直ダウンロード)も禁止したければ、RewriteRule の正規表現パターンに追加すればいい。
RewriteCond による直リン許可設定
このままだと、自分がアクセスしたときに画像処理がしにくくなる。そこで、次のように RewriteCond を追加する。
ここでは、変数 %{REMOTE_ADDR}――つまりアクセスしているIPアドレスが !xxx.xxx.xxx.xxx にマッチすれば――ここには、あなたがアクセスしているIPアドレスを記入する。そのIPアドレスであれば、直リンを許可する。

このままでは、検索エンジン(クローラー)の画像検索に引っかからなくなったり、SNSに投稿するときに画像が添付されない。
そこで、次のように RewriteCond を追加することで、これらの課題を解決する。
また、変数 %{HTTP_REFERER}――つまりユーザーエージェントに twitter, Twitterbot, facebookexterna, Bsky を含むなら RewriteRule を発動しない。Bskyは Bluesky のエージェントだ。
<IfModule mod_rewrite.c>RewriteCond は複数行書くことが可能で、それそれの条件はOR結合される。
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http(s)?://www.pahoo.org [NC]
RewriteCond %{REMOTE_ADDR} !xxx.xxx.xxx.xxx [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F]
</IfModule>
ここでは、変数 %{REMOTE_ADDR}――つまりアクセスしているIPアドレスが !xxx.xxx.xxx.xxx にマッチすれば――ここには、あなたがアクセスしているIPアドレスを記入する。そのIPアドレスであれば、直リンを許可する。

このままでは、検索エンジン(クローラー)の画像検索に引っかからなくなったり、SNSに投稿するときに画像が添付されない。
そこで、次のように RewriteCond を追加することで、これらの課題を解決する。
<IfModule mod_rewrite.c>ここでは、リファラが google, googlebot, bing, msn, "^https?://(www\.)?bluesky\.social" を含むなら RewriteRule を発動しない――つまり直リンできるようにする。
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http(s)?://www.pahoo.org [NC]
RewriteCond %{HTTP_REFERER} !google\. [NC]
RewriteCond %{HTTP_REFERER} !googlebot\. [NC]
RewriteCond %{HTTP_REFERER} !bing\. [NC]
RewriteCond %{HTTP_REFERER} !msn\. [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?bluesky\.social/ [NC]
RewriteCond %{HTTP_USER_AGENT} !(twitter|Twitterbot|facebookexterna|Bsky) [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F]
</IfModule>
また、変数 %{HTTP_REFERER}――つまりユーザーエージェントに twitter, Twitterbot, facebookexterna, Bsky を含むなら RewriteRule を発動しない。Bskyは Bluesky のエージェントだ。
リファラやエージェントの偽装
ご承知のようにリファラやエージェントは簡単に偽装できるので、この設定は完全とは言えない。ただ、当サイトでこの設定をしたところ、画像を集めているクローラーと思われるアクセスは激減し、サーバ負荷は正常に戻ったことで、目的は達成された。
参考サイト
- Apache 2.4:Apache.org
- mod_rerite module:Apache.org
(この項おわり)
近年、機械学習システムのための学習データを採取するクローラーがネット上を回っており、当サイトも「大きな写真」として公開している画像データをまとめてダウンロードされ、Apache に負荷がかかる事態となった。そこで、自分時自身と主要な検索エンジンやSNSサイトには直リンを許し、それ以外は直リンさせないように設定することにした。以下、HTTP通信の負荷と、直リン拒否設定について解説する。