助け合いフォーラム

LinuC

LinuC Lv2-202(Ver10.0)
問題ID : 23216
問題を開く
Requireディレクティブを使ったアクセス制御で複数の条件を設定する際、全ての条件に合致したら許可されるディレクティブはどれか。

この問題はプレミアムコンテンツです。

上に戻る

RequireAnyの中でRequire notが使えない理由

公開日 2024/09/08

本文の正誤とは直接関係ないですが
参考の中のでRequireAnyの中でRequire notが使えない理由の説明の意味がよく分かりません。

「否定条件(Require not)の結果は偽(拒否)を返しますが、真(許可)を返さないため、ディレクティブ内のいずれかの条件が真であるかどうかを判定するの動作に影響を及ぼしません。」

たとえば、
Require ip 10.0.0.1 の場合・・・アクセス元が10.0.0.1なら真、192.168.0.1なら偽を返す、
Require not ip 10.0.0.1 の場合・・・アクセス元が10.0.0.1なら偽、192.168.0.1なら真を返す、
かと思いましたが「真(許可)を返さない」の意味が分かりません。
Require not ip 10.0.0.1 の場合、アクセス元が10.0.0.1なら偽というのは合ってる?では192.168.0.1なら何を返すのか?
Require notだけ、たとえ条件(の否定)が合致しても真は返さない特殊な仕様だとういことでしょうか?

それだったらもう少しその特殊な仕様を強調するなりはっきりロジックで書くなりしないと、ただ真偽が反転するだけの前提で
考えると、なぜ問題なのか悩んでいまうと思いますが。
逆に、真を返すことが絶対にない仕様なのであれば、RequireAllの中なら問題がない理由もよく分かりません。
RequireAllは中の条件が全て真なら真とするディレクティブなのであれば、Require notが真を返さないならRequireAllが真になること
もまたあり得ないことになってしまうのでは。

2024/09/10 22:13

ここ、自分もかなりわかりづらかった記憶があります。

Require not ip 10.0.0.1 の場合、アクセス元が10.0.0.1なら偽というのは合ってる?では192.168.0.1なら何を返すのか?
Require notだけ、たとえ条件(の否定)が合致しても真は返さない特殊な仕様だとういことでしょうか?

Require not については、真を返すことはなく、偽または中立を返します。
意味が解らないと思いますが、実際そう書かれてます。

https://httpd.apache.org/docs/2.4/ja/mod/mod_authz_core.html#require

The result of the Require directive may be negated through the use of the not option. As with the other negated authorization directive , when the Require directive is negated it can only fail or return a neutral result, and therefore may never independently authorize a request.

この中立(neutral result)というのは、どうやら条件を評価しない場合に返るもののようです。
よって「10.0.0.1」の場合、すなわち条件に合致する場合には「偽」が返るものと思われます。
(このあたりの説明が「真を返さない」という説明になっているのでしょうが、実際「中立を返す」とか書かれてもよくわからないんだろうなと思った記憶があります。)

逆に、真を返すことが絶対にない仕様なのであれば、RequireAllの中なら問題がない理由もよく分かりません。
RequireAllは中の条件が全て真なら真とするディレクティブなのであれば、Require notが真を返さないならRequireAllが真になることもまたあり得ないことになってしまうのでは。

たとえばこういう条件のとき、
<RequireAll>
①Require all granted
②Require not ip 10.0.0.1
</RequireAll>

①は常に真を返します。
②は、例えば 10.0.0.1 だったら 条件に合致する=偽を返し、
RequireAllの動作としては、すべての条件に合致しない=アクセスが拒否される という動作になるものと思われます。

さらに、Require not の条件に合致しない、例えば 192.168.0.1 のような場合には、
先ほどの同じページ RequireAll の説明に以下のようにあります。

If none of the directives contained within the directive fails, and at least one succeeds, then the directive succeeds. If none succeed and none fail, then it returns a neutral result. In all other cases, it fails.

・一つも偽を返さない+一つ以上が真の場合には成功を返す
・どれも真でなく、偽でもない場合は中立を返す
・それ以外は失敗を返す

192.168.0.1 からアクセスがあったとき、②Require not は「中立」を返すはずです。
このとき、①は真、②が中立を返すために、「一つも偽を返さない+一つ以上が真の場合には成功を返す」
の要件に当てはまり、アクセスできる という動作のようです。

中立という言葉を考えると、<RequireAll> は「全ての条件が失敗しない場合に真」と理解した方がよいのかもしれません。


コメント

m miki_y

2024/09/10 23:29

詳しく教えていただきありがとうございます!助かります! 中立という概念があるのですね。 プログラム言語のBooleanやそれを返す関数の扱いと同じ感覚で当てはめて 考えようとすると理解しにくくなりますね。 といってもApacheもプログラムなわけですが、、、 真偽の論理積・論理和というよりスリーステート(もしくはそれ以上?)の評価値 で判断して設定ファイルをパースしているのかもしれませんね。 慣れない考え方ですが、記載いただいた考え方で大筋理解できました。 重ねて、詳細なご説明ありがとうございました。

この返信に対して
コメントを記入できます

この投稿に対して返信しませんか?