Apachehtaccess複数のルールの複数の書き換え条件

Nov 23 2017

私はウェブサイトを乗っ取って、前の開発者が複数の.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フラグを使用するように提案しましたが、調査の結果、それは私が達成したいこととは何の関係もないと思います。)

回答

3 MrWhite Nov 23 2017 at 23:23
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、SSL(Let's Encrypt?)セキュリティ証明書を自動更新するときに、すべてのディレクティブの前にcPanelによって自動的に挿入されます。これらの条件により、検証ファイル(SSL証明書を更新するために必要)にアクセスできるようになります。

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

...リライトルールを組み合わせて、条件を1回だけ書き込む必要があるようにする方法はありますか?

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

# 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つの条件の追加フラグに注意してください。そしてべきリクエストマッチ処理されて、さらにmod_rewriteのディレクティブを防ぐことができます。ORRewriteRule

(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 置換を