📌

istioでWASMを使ってBasic認証を行う

2021/12/08に公開

istioでWASMを使ってBasic認証を行う

オフィシャルで紹介されていた。WASMを使う方法を試してみる。

目的

istioを使って、アプリケーションに手を入れず、またnginxなどのProxyを入れることもなくistioとenvoyだけでBasic認証を実装する。

環境

  • envoy: 1.11.2
  • istio: 1.11.2
  • basic-auth wasm: 1.11.0

注意

オフィシャルのドキュメント にもあるように、あくまでこの機能は現在experimentalであるため、プロダクションで利用しないほうがよいだろう。

明らかな問題点として今の所Secretやファイルから user/passwordを読み込む方法がなくEnvoyFilter manifestにベタ書きするしかない。これに関してもオフィシャルのREADMEやissueで言及されている。

そのため実験的に利用する以下のような人達向け

  • Firewallなど別の方法で安全が担保されている状態でちょっとしたものを公開するとき、アプリケーションにわざわざBasic認証実装したくない人
  • EnvoyFilterの基本を知りたい人
  • istioでWASM拡張の機能を試してみたい人

実際の手順

基本的に、オフィシャルのサンプルがあるのでそれに従って

sample manifestsを書いた

httpbinbasic-authという名前でデプロイし、そこに対してbasic認証を行う。

httpbinをデプロイする

とりあえず定番のDeployment + Service + Gateway + VirtualService + DestinationRule の基本構成でhttpbinをデプロイする。

サンプルの以下のファイル

  • deployment.yaml
  • gateway.yaml
  • service.yaml
  • traffic-management.yaml

istioを使ってる人にとっては特に変わったこともしていないので割愛

EnvoyFilterを適用する

いよいよ本題でFilterはWASMの導入とWASMのコンフィグで二段階に分かれている

basic-auth-filter.yaml がWASMの導入でDownload先や定義Protoなんかが書いてある、これに関しては基本的にいじる部分はないのでそのまま適用してよい。
肝心なのは config-filter.yaml で、この中にWASMがどういった挙動を行うのかというコンフィグが書いてある。

# NOTE: https://github.com/istio-ecosystem/wasm-extensions/tree/master/extensions/basic_auth
#
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
 name: basic-auth-config
 namespace: basic-auth
spec:
 configPatches:
 - applyTo: EXTENSION_CONFIG
   match:
     context: SIDECAR_INBOUND
   patch:
     operation: ADD
     value:
       name: istio.basic_auth
       typed_config:
         "@type": type.googleapis.com/udpa.type.v1.TypedStruct
         type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
         value:
           config:
             #... 中略
             # The configuration for the Wasm extension itself
             configuration:
               '@type': type.googleapis.com/google.protobuf.StringValue
                # 現時点ではSecretやConfigMapからここに値を設定する方法がないため、credentialsが剥き出しになってしまうことに注意する。
                # 一時的に運用したいなどクリティカルではないものに利用する
                #
                # 以下の例では https://$HOST/ip 以下のURLに対してbasic認証をかける
               value: |
                 {
                   "basic_auth_rules": [
                     {
                       "prefix": "/ip",
                       "request_methods":[ "GET", "POST" ],
                       "credentials":[ "ok:test", "YWRtaW4zOmFkbWluMw==" ]
                     }
                   ]
                 }

これによって、ごくごく小さな影響範囲でアプリケーションに手を入れることもなく、nginxなどを手前に用意することもなくistioだけでBasic認証をすることができた。よかったよかった
WASMの実装も読みきれる量だしちょっとした拡張なら自分でもかけそうな気がする良いサンプルだった。


おまけtips: Filterを挿入する位置を考える

オフィシャルのサンプルと違う部分はサンプルのまま利用するとIngress Gatewayに適用され、全てのリクエストに対してWASM拡張が適用されてしまうため、
spec.configPatches[].match.context=SIDECAR_INBOUND に変更を行い適用する範囲をSidecar proxyのINBOUNDに絞る。

diff --git a/example/basic-auth/basic-auth-filter.yaml b/example/basic-auth/basic-auth-filter.yaml
index 0116d1a0..7073e4cd 100644
--- a/example/basic-auth/basic-auth-filter.yaml
+++ b/example/basic-auth/basic-auth-filter.yaml
@@ -7,7 +7,7 @@ spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
-     context: GATEWAY
+     context: SIDECAR_INBOUND
      listener:
        filterChain:
          filter:

overview

参考資料

GitHubで編集を提案

Discussion