カスタムヘッダー「username」と「role」を使用してユーザーとその役割を識別する、Apache Reverse-Proxyの背後で実行されているサービスがあります。
Apache HTTPDで、カスタムHTTPヘッダー「groupmembership」に「viewer」、「publisher」、「administrator」のいずれかが含まれているユーザーへのアクセスを制限したい。
Apacheは、ユーザーを認証し、HTTPヘッダー「username」と「groupmembership」にデータを入力する別のプロキシの背後にあります。ここで、「groupmembership」の内容は、グループをコンマで区切ったリストです。
参考までに、アーキテクチャのドラフトを含めました。 http-proxy-auth
これはどのようにして可能でしょうか? Require expr %{HTTP:iv_groupmembership} in { 'viewer', 'publisher', 'administrator' }
内で<Location />
のようなrequireディレクティブを使用してみましたが、役に立ちませんでした。
代わりにこれはmod_rewriteで動作しますか?
Mod_proxyとmod_rewriteを使用したリバースプロキシ設定は次のとおりです。
RewriteEngine on
<Proxy *>
Allow from all
</Proxy>
ProxyRequests Off
# store variable values with dummy rewrite rules
RewriteRule . - [E=req_scheme:%{REQUEST_SCHEME}]
RewriteRule . - [E=http_Host:%{HTTP_Host}]
RewriteRule . - [E=req_uri:%{REQUEST_URI}]
# set header with variables
RequestHeader set X-RSC-Request "%{req_scheme}e://%{http_Host}e%{req_uri}e"
RewriteCond %{HTTP:Upgrade} =websocket
RewriteRule /(.*) ws://localhost:3939/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /(.*) http://localhost:3939/$1 [P,L]
ProxyPass / http://172.17.0.1:3939/
ProxyPassReverse / http://172.17.0.1:3939/
ヒントをありがとう。
編集:基本的に、質問は次のようになります。groupmembership
ヘッダーのカンマ区切りのリストに「管理者」、「発行者」、または「閲覧者」が含まれているかどうかを確認するにはどうすればよいですか。
これでうまくいくはずです。ヘッダーgroupmembership
にカンマ区切りのリストがある場合は、最初の正規表現を使用します。アクセスを許可するには、リスト内の1つの値が一致する必要があります。
iv_groupmembership
の正確な値と一致させる場合は、 二番目 3番目の式(および最初のコメント)。
編集:
RequestHeader set role
の例を追加し、必要に応じてコメントを外します。私はこれをHeader set role
でテストしただけですが(レスポンスではバックエンドはありません)、RequestHeader
でも同じように機能するはずです。Edit2:
<Location/>
を削除X-Auth-Token
チェックとgroupmembership
を組み合わせた例を追加サンプル設定:
# test for string in comma-separated values, one of the values must match
<If "%{HTTP:groupmembership} !~ /(^|,)(viewer|publisher|administrator)(,|$)/">
# combined: X-Auth-Token must be set or one of the roles must exist
# <If "%{HTTP:X-Auth-Token} == '' && %{HTTP:groupmembership} !~ /(^|,)(viewer|publisher|administrator)(,|$)/">
# alternative: test for a single value in "iv_groupmembership" (exact match)
# <If "! %{HTTP:iv_groupmembership} in { 'viewer', 'publisher', 'administrator' }">
Require all denied
</If>
# set role of groupmembership
# <If "%{HTTP:groupmembership} =~ /(^|,)viewer(,|$)/">
# RequestHeader set role viewer
# </If>
# <ElseIf "%{HTTP:groupmembership} =~ /(^|,)publisher(,|$)/">
# RequestHeader set role publisher
# </ElseIf>
# <ElseIf "%{HTTP:groupmembership} =~ /(^|,)administrator(,|$)/">
# RequestHeader set role administrator
# </ElseIf>
# set role of iv_groupmembership
# RequestHeader set role "expr=%{HTTP:iv_groupmembership}"
Apacheのヘッダー(RequestHeader set iv_groupmembership "viewer"
など)を変更して構成をデバッグ/テストすることはできません。ヘッダーを非常に早く設定する必要があります。
https://httpd.Apache.org/docs/2.4/expr.html#vars
式パーサーは、%{HTTP_Host}という形式の多数の変数を提供します。変数の値は、それが評価される要求処理のフェーズに依存する場合があることに注意してください。たとえば、<If>ディレクティブで使用される式は、認証が行われる前に評価されます。したがって、この場合、%{REMOTE_USER}は設定されません。
コマンドラインからwgetを使用して構成をテストできます。localhost
をホスト名に置き換えます。
# HTTP/1.1 403 Forbidden
wget -S -O - http://localhost
wget -S -O - --header='groupmembership: xviewer' http://localhost
wget -S -O - --header='groupmembership: administratorx' http://localhost
wget -S -O - --header='iv_groupmembership: xviewer' http://localhost
# HTTP/1.1 200 OK
wget -S -O - --header='groupmembership: foo,viewer' http://localhost
wget -S -O - --header='groupmembership: publisher,foo' http://localhost
wget -S -O - --header='iv_groupmembership: viewer' http://localhost
wget -S -O - --header='iv_groupmembership: publisher' http://localhost
wget -S -O - --header='iv_groupmembership: administrator' http://localhost
Apache/2.4.25(Debian)でテスト済み
@Freddyに感謝します。承認部分のRequire
およびExpressionsディレクティブを使用し、<Virtualhost>
内にRequestHeader
ディレクティブを配置して、ロールヘッダーを設定しました。
最終的な設定は次のようになります。
<VirtualHost *:443>
ServerName ...
DocumentRoot /var/www/html
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/httpd/ssl/...
SSLCertificateKeyFile /etc/httpd/ssl/...
RewriteEngine on
#ProxyPreserveHost on
<Proxy *>
Allow from all
</Proxy>
ProxyRequests Off
# store variable values with dummy rewrite rules
RewriteRule . - [E=req_scheme:%{REQUEST_SCHEME}]
RewriteRule . - [E=http_Host:%{HTTP_Host}]
RewriteRule . - [E=req_uri:%{REQUEST_URI}]
# set header with variables
RequestHeader set X-RSC-Request "%{req_scheme}e://%{http_Host}e%{req_uri}e"
RewriteCond %{HTTP:Upgrade} =websocket
RewriteRule /(.*) ws://localhost:3939/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /(.*) http://localhost:3939/$1 [P,L]
# test for string in comma-separated values, one of the values must match
<If "%{HTTP:iv_groupmembership} !~ /(^|,)(Viewer|Publisher|Administrator)(,|$)/ && -z %{HTTP:X-Auth-Token} && %{HTTP:Authorization} !~ /Key .+/">
Require all denied
</If>
# set role of groupmembership
<If "%{HTTP:iv_groupmembership} =~ /(^|,)Viewer(,|$)/">
RequestHeader set Role viewer
</If>
<ElseIf "%{HTTP:iv_groupmembership} =~ /(^|,)Publisher(,|$)/">
RequestHeader set Role publisher
</ElseIf>
<ElseIf "%{HTTP:iv_groupmembership} =~ /(^|,)Administrator(,|$)/">
RequestHeader set Role administrator
</ElseIf>
</Virtualhost>
どうもありがとう!
編集:Require
ディレクティブにロジックを追加して、ヘッダーX-Auth-Token
が存在する場合でもアクセスを許可する方法を教えてください。
Edit2: Apache式ロジックへのポインタに対して@Freddyに感謝します。「X-Auth-Token」ヘッダーの存在についてテストを-z %{HTTP:X-Auth-Token}
で適合させ、別の条件を追加することができました「authorization」ヘッダー内にキーを含むリクエストをパススルーします。