web-dev-qa-db-ja.com

複数のルールに対するApache htaccessの複数の書き換え条件

私はウェブサイトを乗っ取って、以前の開発者が複数の.htaccess書き換えルール、これは短い例です:

RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing$ landing.php?page=$1

書き換え条件はすべてのルールで常に同じですが、書き換えルールを組み合わせる方法があるので、条件を1回だけ記述する必要がありますか?

スキップフラグを調査しましたが、後方参照はできません。私が見る限り、それらの条件で後方参照は必要ありませんが、最善のアプローチをスキップしていますか?それとも、これを達成するためのベストプラクティスはありますか? (QSAフラグを使用するように勧められた人がいますが、調査の結果、私が達成したいこととは関係ないと思います。)

2
Tom
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$

この厄介な条件ブロックは、SSL(Let's Encrypt?)セキュリティ証明書を自動更新するすべてのRewriteRuleディレクティブの前にcPanelによって自動的に挿入されます。これらの条件により、検証ファイル(SSL証明書を更新するために必要)にアクセスできることが保証されます。

残念ながら、cPanelがこの方法でこの処理を行う理由を理解することができませんでした。これはメンテナンスの悪夢である可能性があり、これらの条件によって壊れたディレクティブに遭遇しました(確かに、ディレクティブは最初は完全ではありませんでした) )。 (私はcPanelフォーラムで質問してみましたが、良い反応がありませんでした。)

...リライトルールを組み合わせる方法があるので、条件を1回だけ記述する必要がありますか?

はい。 .htaccessファイルとreverseの意味でこれらの条件を独自のブロックに移動できるため、リクエストが一致しない場合にRewriteRuleをトリガーするだけでなくパターン(negated regexを使用)。リクエストがパターンに一致する場合、それ以上の書き換えを防ぐことができます。例えば:

# BEGIN cPanel SSL CERT RENEWAL
RewriteCond %{REQUEST_URI} ^/[0-9]+\..+\.cpaneldcv$ [OR]
RewriteCond %{REQUEST_URI} ^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$ [OR]
RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$ [OR]
RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^ - [L]
# END cPanel SSL CERT RENEWAL

CondPattern!(否定)プレフィックスの削除と、最初の3つの条件の追加のORフラグに注意してください。次に、RewriteRuleは、リクエストが一致した場合にmod_rewriteディレクティブがさらに処理されるのを防ぎます。

(Apache 2.4.8以降では、これらのディレクティブを完全にサーバー構成に移動できます。RewriteOptions InheritDownBeforeを使用してください。)

次に、以前にあったRewriteRuleディレクティブだけを続けます(ただし、Lフラグを追加しました)。

RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3 [L]
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2 [L]
RewriteRule ^(.*)/landing$ landing.php?page=$1 [L]

おそらく、残りの書き換えにLフラグを含める必要があります。

必要に応じて、これら3つの書き換えを1つのディレクティブに結合することもできますが、アプリケーションが空のURLパラメータを処理するかどうかによって異なります。

(だれかがQSAフラグの使用を提案しましたが、調査の結果、私が達成したいこととは関係ないと思います。)

はい、それは実際にはこの特定の問題とは何の関係もありません。 QSA(クエリ文字列追加)フラグを使用すると、リクエストに存在するすべてのクエリ文字列を、RewriteRuleに書き込んでいるクエリ文字列とマージできます(substitution

3
MrWhite