.htaccessファイルをnginxに変換するのに問題があります。 3つの.htaccessファイルがあります。最初の.htaccessファイルはドキュメントルートにあり、次のとおりです。
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^img-(.*)\.html img.php?id=$1 [L]
RewriteRule ^slide-(.*)\.html slider.php?id=$1 [L]
RewriteRule ^page-(.*)\.html page.php?name=$1 [L]
RewriteRule ^contact\.html$ contact.php [QSA,L,NC]
2番目の.htaccessファイルは、uploadというフォルダーにあります。
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?foo\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*\.(jpe?g|gif|bmp|png)$ nohotlink.gif [L]
<Files ~ "\.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$">
order allow,deny
deny from all
</Files>
そして、3番目で最後の.htaccessファイルは、「small」という名前のアップロードフォルダのサブディレクトリにあります。
RewriteEngine Off
これで、/ etc/nginxにincludesというフォルダーを作成し、次の書き換えルールを使用して3つの個別の.accessファイルを作成しました。
ドキュメントのルートディレクトリにある最初の.htaccessファイルについて、/ etc/nginx/includesにroot.accessというファイルを作成しました。このファイルには次のものがあります。
# nginx configuration
location /img {
rewrite ^/img-(.*)\.html /img.php?id=$1 break;
}
location /slide {
rewrite ^/slide-(.*)\.html /slider.php?id=$1 break;
}
location /page {
rewrite ^/page-(.*)\.html /page.php?name=$1 break;
}
location /contact {
rewrite ^/contact\.html$ /contact.php break;
}
「upload」フォルダーにある2番目のファイルについて、upload.accessというファイルを/ etc/nginx/includesに作成しました。このファイルには次のものが含まれています。
# nginx configuration
location /upload {
if ($http_referer !~ "^http://(.+\.)?foo\.com/"){
rewrite .*\.(jpe?g|gif|bmp|png)$ /nohotlink.gif break;
}
}
location ~ \.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$ {
deny all;
}
そして、3番目の最後のファイルについては、/ etc/nginx/includesの名前small.accessにファイルを作成しました。このファイルの内容は次のとおりです。
# nginx configuration
location /upload/small {
}
サーバーブロック構成ファイルには、次のものがあります。
location / {
try_files $uri $uri/ /index.php;
include /etc/nginx/includes/root.access;
}
location /upload {
include /etc/nginx/includes/upload.access;
}
location /upload/small {
include /etc/nginx/includes/small.access;
}
この構成では、サイトを試すときに403エラーが発生します。 Nginxエラーログレポート:
[error] 18156#0: *7 access forbidden by rule, client: 111.**.**.**, server: foo.com, request: "POST /upload.php HTTP/1.1", Host: "foo.com", referrer: "http://foo.com/"
現在、Apacheではすべてが問題なく機能します。しかし、なぜ403エラーが発生するのかわかりません。また、私が述べたように、403エラーを超える書き換えルールがまったく正しく機能しないことも心配です。誰かがこれで私を助けることができますか?ここで何が悪いのかわかりません。
これは、構成のこの部分の標準的なnginxの動作です。
location /upload {
if ($http_referer !~ "^http://(.+\.)?foo\.com/"){
rewrite .*\.(jpe?g|gif|bmp|png)$ /nohotlink.gif break;
}
location ~ \.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$ {
deny all;
}
}
なぜですか?
ロケーションの仕組みを明確にしましょう:nginxが構成ファイルを読み取ると、ロケーションブロックが3つのタイプに分類されます:
location = /upload { }
location /upload { }
location ~ /upload { }
リクエストがnginxに届くと、場所の選択プロセスは次のようになります。
したがって、あなたの場合、.php
拡張子に一致するロケーションブロックは、URIの/upload
部分に一致するロケーションブロックよりも優先されます。
編集:ソリューションの明確化、代替ソリューションが追加されました。
^~
を使用すると、nginxにステップ2の動作を変更するように指示できます。これにより、正規表現の場所の検索をバイパスして、一致するプレフィックス付きの場所がすぐに使用されます。したがって、2つの解決策があります:
ソリューション1:
upload.access:
if ($http_referer !~ '^http://(.+\.)?foo\.com/') {
rewrite '.*\.(jpe?g|gif|bmp|png)$' '/upload/nohotlink.gif' break;
}
if ($uri ~ '\.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$') {
return 403;
}
同じサーバーブロック
ソリューション2:
upload.access:
if ($http_referer !~ '^http://(.+\.)?foo\.com/') {
rewrite '.*\.(jpe?g|gif|bmp|png)$' '/upload/nohotlink.gif' break;
}
location ~ \.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$ {
deny all;
}
サーバーブロック:
location ^~ /upload {
include /etc/nginx/includes/upload.access;
}
これで、phpファイル処理を転送する場所を設定しない場合、現在の構成では何も起こりません。nginx fastcgi module を確認してください。次に、root.accessファイルの書き換えルールを変更して、現在の場所のコンテキストで解決されないようにする必要があります(つまり、一意のフォールバック場所を1つ作成し、break
をlast
に変更してnginxに通知します。書き換え後に場所選択プロセスを再度実行します)。