Access: 2104660
p-lux.net Ver.10.00 by Ryogo
AlmaLinux 9 + Apache に mod_xsendfile を導入したので備忘録
■はじめに

X-Sendfile とは、PHPなどのスクリプト経由で実ファイルを配信するための Apache モジュールです。

通常、PHPでファイルを読み込んで出力すると、下記のような問題があります。
・メモリを消費する
・大容量ファイルでパフォーマンスが落ちる
・Range配信などが煩雑になる

X-Sendfile を使うと、
「認可だけPHPで行い、実ファイル送信はApacheに任せる」
という構成が可能になります。

用途の例としては、ログインしている人にしかダウンロードさせたくないデータがあるけれど、
実ファイル(mp3やzip)のURLをSNSなどにばらまかれてダウンロードされたら困るという時などがあげられます。

余談ですが、仕事などで完全に限定的な人にだけ渡したい場合はダイジェスト認証などの方が楽です。
用途に合わせて使い分けていきましょう。



■ 環境情報

本記事では AlmaLinux 9 + Apache 2.4 系を前提とします。
昨今はもっぱら Nginx も流行っていますが、その場合は X-Accel-Redirect などで調べてみるといいかと思います。



■ mod_xsendfile のインストール

まずはEPELとCRBを有効化し、モジュールをインストールします。
# sudo dnf -y install epel-release
# sudo dnf config-manager --set-enabled crb
# sudo dnf -y install mod_xsendfile

設定テスト
# sudo apachectl configtest

問題なければ再起動
# sudo systemctl restart httpd

この際、reload を使いたくなりますが、個人的には不安です。
まだ、非公開環境などで好きに再起動できるなら restart をオススメします。



■ 配信用ディレクトリの作成

X-Sendfileで送信を許可する実ファイル置き場を作ります。
# sudo mkdir -p /var/www/xsendfile_data

テスト用ファイル作成(任意だが確認用として推奨)
# sudo sh -c 'echo "X-Sendfile OK." > /var/www/xsendfile_data/test.txt'

所有者とパーミッション設定
# sudo chown -R apache:apache /var/www/xsendfile_data
# sudo chmod 750 /var/www/xsendfile_data

※ 実運用では公開ディレクトリ配下に置かず、直接URLでアクセスできない場所に置くのが基本です。
ただ、有料製品などの重要なデータでなく、「ちょっと隠蔽したい」ぐらいなら管理しやすいディレクトリでもいいでしょう。



■ Apache 側の設定

httpd.conf もしくは VirtualHost 内に以下を追加します。

- X-Sendfile ----
# X-Sendfile を有効化
XSendFile On
# X-Sendfile で送ってよい実ファイルの置き場
XSendFilePath /var/www/xsendfile_data
-----------------

設定確認
# sudo apachectl configtest

反映
# sudo systemctl reload httpd
※こちらは reload で間違いなく大丈夫です。



■ PHP 側のテストコード

例えば xsendfile_test.php に以下を書きます。

<?php
header('X-Sendfile: /var/www/xsendfile_data/test.txt');
exit;

このphpへブラウザでアクセスし、「X-Sendfile OK.」と表示されれば成功です。
Apache でリバースプロキシを導入したので備忘録
■はじめに

リバースプロキシとは、クライアントからのリクエストを一度受け取り、別のサーバへ転送してその結果を返す仕組みのことです。

見た目上は「同じドメイン」にアクセスしているように見えますが、
内部的には別サーバで処理させることができます。

今回の想定は下記です。
・現サーバ(フロント)
・新サーバ(バックエンド)

今回は例として、 /reverse_proxy_test/ だけを新サーバへ転送します。



■ 現サーバ(フロント側)の設定

まずはSSL終端を行う現サーバ側の設定です。

<VirtualHost *:443>
ServerName p-lux.net
DocumentRoot /var/www/p-lux.net/

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/p-lux.net/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/p-lux.net/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/p-lux.net/chain.pem

<Location "/reverse_proxy_test/">
# 元の Host ヘッダをバックエンドへ渡す
ProxyPreserveHost On
# X-Forwarded-For などのヘッダを自動付与
ProxyAddHeaders On
# 指定パスを新サーバへ転送
ProxyPass "http://NEW_SERVER_IP/reverse_proxy_test/"
ProxyPassReverse "http://NEW_SERVER_IP/reverse_proxy_test/"
</Location>

</VirtualHost>

※ NEW_SERVER_IP は新サーバのIPアドレスに置き換えること。
※ mod_proxy / mod_proxy_http が有効になっていることが前提です。



■ 新サーバ(バックエンド側)の設定

新サーバ側は通常のVirtualHost設定に加え、
リバースプロキシ経由のIPを正しく取得する設定を行います。

<VirtualHost *:80>
ServerName p-lux.net
DocumentRoot /var/www/html/p-lux.net/public/

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy OLD_SERVER_IP
</VirtualHost>

※ OLD_SERVER_IP は現サーバのIPアドレス。

転送するだけなら、この設定はやらなくても動きますが、
これをやっておかないと、新サーバ側は全てのアクセスを旧サーバのIPとして判断してしまいます。
ログの保存やアクセス判定など、なにかとやっておかないと不便なので、この設定は行うことを強く推奨します。

余談ですが、なぜ RemoteIPTrustedProxy で旧サーバのIPだけ信用するようにしているのかと言うと、
これをしないと、ユーザがヘッダ情報を好きに送りつけて、好きなIPとなりすましてアクセスできてしまうためです。
例えば、せっかく自分のIPだけしか入れないページを作っても、ユーザはIPを誤魔化して侵入できてしまうわけです。
そのため、RemoteIPTrustedProxy で許可したIP(今回の場合、旧サーバ)からの情報だけを正規のIPとして処理しています。
ウサ耳娘とXXXしないと出られない部屋

© 2003-2026 p-lux.net, Ryogo.

ページトップへ