envoyは非常に高機能なプロキシですが、Basic認証のフィルタ機能はありません。 Set basic authentication to the endpointで議論されているように、同等の機能をLuaスクリプトで実装することは可能です。
issueの リンクに掲載されているコードは、 RFC7617のロジックを実装したものです。Basic認証そのものの説明になってしまいますが、概略は以下のような処理です。
- authorizationヘッダーの内容のマッチ検証
- “Basic b2s6dGVzdDE=“の形式であること。BasicはRFC7617の指定する定型句
- “b2s6dGVzdDE=“の部分は、“id:pass"形式の文字列をBase64エンコードしたもの
- 認証NGの場合は、RFC7617の指定するヘッダーとともに、HTTP401をレスポンス
issueの実装例は古いため、 APIv3に合わせて実装する必要があります。
Luaの機能は、公式Dockerにインクルードされており、単にconfigにコードを記載するだけで動作します。リファレンスに利用例の解説があります。関数envoy_on_request()
はリクエストをフックするイベントハンドラです。
動作確認は、ブラウザでアクセスしながら確認すると良いでしょう。また、無効な設定を書いた場合、envoyの起動メッセージにエラー出力されるため、合わせて確認が必要です。
Basic認証じたいが柔軟性の低い認証方式であるため、直接の機能サポートは手薄ですが、適切なLuaスクリプトを書けば目的の挙動にはなります。
Per Route Configuration
Luaのフィルタはlistner.filter_chains[].filters[].http_filters[]
に書けます。
Luaの呼び出し方はいくつかの方式がありますが、
Per Route Configurationという構成が主流となりました。
source_codes
に名前付きの関数(下の例ではbasicauth.lua)として登録しておきます。
http_filters:
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
source_codes:
basicauth.lua:
inline_string: |
function envoy_on_request(request_handle)
if string.match(request_handle:headers():get(":path"), "/protected_path")
then
if request_handle:headers():get("authorization") == "Basic b2s6dGVzdDE="
then
return
end
request_handle:respond(
{[":status"] = "401", ["WWW-Authenticate"] = "Basic realm=\"Unknown\""}, "Unauthorized"
)
end
end
# inline_code is deprecated in v1.23.0
inline_code: |
function envoy_on_request(request_handle)
-- do nothing
return
end
- name: envoy.filters.http.router
v1.22以前ではinline_code
は必須項目であるため、上の例のように何もしないダミーコードを登録しておく必要があります。
また、コード末尾のenvoy.filters.http.router
は一般的なルーティングのフィルタです。定義階層の参考であり、Luaを利用するためのコードではありません。
呼び出しの制御は、以下のようにrouteのtyped_per_filter_config
で定義できます。なお、typed_per_filter_configはVirtualHostのレイヤにも定義可能です。
"@type": type.googleapis.com/envoy.config.route.v3.RouteConfiguration
virtual_hosts:
- name: example
domains:
- "example.com"
routes:
- match:
prefix: "/protected_path"
route:
cluster: upstream_host
typed_per_filter_config:
envoy.filters.http.lua:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
name: basicauth.lua
- match:
prefix: "/"
route:
cluster: upstream_host
typed_per_filter_config:
envoy.filters.http.lua:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
disabled: true
LuaPerRouteの設定には、disabled
またはname
を指定できます。
Chuma Takahiro