Cloud Service Mesh 사용자 인증 구성

TRAFFIC_DIRECTOR컨트롤 플레인 구현이 있는 경우 이 기능은 허용 목록에서만 지원됩니다. 지원팀에 문의하여 조직에 이 기능을 허용 목록에 추가해 달라고 요청하세요.

Cloud Service Mesh 사용자 인증은 배포된 워크로드에 대한 브라우저 기반 최종 사용자 인증 및 액세스 제어를 위한 통합 솔루션입니다. 이를 통해 사용자 인증을 위해 기존 ID 공급업체(IDP)와 통합할 수 있으며, Istio API 및 승인 정책을 액세스 관리에 사용할 수 있습니다. Istio JSON Web Token(JWT) 인증의 사용자 친화적인 대안입니다.

일반적인 사용 사례는 조직에서 Cloud Service Mesh를 사용해 애플리케이션을 웹 호스팅하여 직원이 웹브라우저를 통해 액세스할 수 있도록 하는 것입니다. 또한 조직은 기존 ID 공급업체를 사용하여 사용자 ID를 관리해야 합니다. Cloud Service Mesh 사용자 인증을 사용하면 사용자가 표준 웹 기반 OpenID Connect(OIDC) 로그인 및 동의 흐름을 사용하여 손쉽게 인증할 수 있습니다. 사용자가 인증하면 Cloud Service Mesh에서 Istio 승인 정책을 실행하고 승인에 성공하면 해당 ID를 보안 사용자 인증 정보 형식으로 워크로드에 전송합니다.

작동 방식

Cloud Service Mesh 사용자 인증에는 새로운 구성요소인 authservice가 도입되었습니다. 이 구성요소는 인증에 대한 모든 수신 요청을 가로채는 외부 승인 서비스인 Envoy 기반 인그레스와 통합됩니다. authservice는 OIDC 프로토콜의 클라이언트 측을 구현하고 사용자가 브라우저를 통해 애플리케이션에 액세스할 수 있도록 해 줍니다. 여기에서 사용자는 양방향 인증 및 동의 흐름을 완료하여 단기 세션을 설정하게 됩니다. authservice는 업계 표준 프로토콜을 구현하여 OIDC 승인 서버 역할을 할 수 있는 모든 ID 공급업체와 통합됩니다. 사용자가 인증되면 주 구성원 정보는 JWT 형식의 RCToken으로 캡슐화되고 authservice로 서명된 다음 인그레스의 Istio 승인 레이어로 전달됩니다. 이 모델은 메시에 들어오는 트래픽에 대한 경계 액세스 제어를 제공합니다. 사용자가 리소스에 액세스하도록 승인되면 주 구성원 정보를 가져오고 세분화된 액세스 제어를 실행할 수 있도록 이 RCToken도 마이크로서비스에 전달됩니다.

다음 다이어그램은 메시의 authservice 위치와 인그레스, 워크로드, 사용자의 브라우저, 기존 IDP와 같은 메시의 다른 부분과 맺고 있는 관계를 보여줍니다.

최종 사용자 인증

관리자는 Cloud Service Mesh를 설치하는 동안 authservice를 부가 기능으로 설치할 수 있습니다. 설치된 authservice는 OIDC 엔드포인트 구성 및 UserAuth 커스텀 리소스에 정의된 기타 관련 설정을 읽습니다. 관리자는 Cloud Service Mesh ExternalAuthorization API를 사용하여 auth_server를 인그레스의 필터로 구성할 수 있습니다.

사용자 인증 서비스 설치

다음 단계에서는 authservice를 구성하는 방법을 설명합니다.

기본 요건

종속 도구 설치 및 클러스터 검증의 단계를 따라 다음을 수행합니다.
  • 비공개 클러스터에서 관리형 Cloud Service Mesh를 사용하는 경우 클러스터에서 이그레스 트래픽을 IDP로 보낼 수 있는지 확인합니다.

그런 다음, 다음 단계에 따라 기본 요건을 충족하는지 확인하세요.

사용자 인증 오버레이를 사용한 설치 맞춤설정

사용자 인증 서비스를 설치하려면 Cloud Service Mesh 설치를 맞춤설정하여 메시 수준의 외부 승인 제공업체를 추가해야 합니다. 필요한 단계는 관리형 또는 클러스터 내 Cloud Service Mesh 사용 여부에 따라 다릅니다.

관리됨

  1. 사용자 인증 MeshConfig를 포함하도록 ConfigMap을 업데이트합니다. 다음 명령어에서 관리형 Cloud Service Mesh를 프로비저닝할 때 사용한 것과 동일한 REVISION_LABEL을 사용합니다(예: asm-managed, asm-managed-rapid 또는 asm-managed-stable).

    kubectl edit configmap istio-REVISION_LABEL -n istio-system
    
  2. MeshConfig의 mesh 필드 아래에 다음 텍스트를 추가합니다.

    mesh: |-
    ...
      extensionProviders:
      - name: "asm-userauth-grpc"
        envoyExtAuthzGrpc:
          service: "authservice.asm-user-auth.svc.cluster.local"
          port: "10003"
    
  3. asm-user-auth 네임스페이스를 만듭니다.

    kubectl create namespace asm-user-auth
    
  4. 네임스페이스의 삽입을 사용 설정합니다. 이 단계는 컨트롤 플레인 구현에 따라 다릅니다.

    관리형(TD)

    기본 삽입 라벨을 네임스페이스에 적용합니다.

    kubectl label namespace asm-user-auth \
        istio.io/rev- istio-injection=enabled --overwrite
    

    관리형(Istiod)

    권장: 다음 명령어를 실행하여 네임스페이스에 기본 삽입 라벨을 적용합니다.

    ```sh
    kubectl label namespace asm-user-auth \
        istio.io/rev- istio-injection=enabled --overwrite
    ```
    

    관리형 Istiod 컨트롤 플레인이 있는 기존 사용자: 기본 삽입을 사용하는 것이 좋지만 버전 기반 삽입은 지원됩니다. 다음 안내를 따르세요.

    1. 다음 명령어를 실행하여 사용 가능한 출시 채널을 찾습니다.
    kubectl -n istio-system get controlplanerevision
    

    출력은 다음과 비슷합니다.

    NAME                AGE
    asm-managed-rapid   6d7h
    

    출력에서 NAME 열 아래의 값은 Cloud Service Mesh 버전에 사용 가능한 출시 채널에 해당하는 버전 라벨입니다.

    1. 네임스페이스에 버전 라벨을 적용합니다.

      kubectl label namespace asm-user-auth \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      
  5. asm-user-auth 네임스페이스에 Istio 게이트웨이를 설치합니다.

    kubectl apply -n asm-user-auth -f DIR_PATH/samples/gateways/istio-ingressgateway
    

클러스터 내

  1. 사용자 인증 오버레이 예시를 가져와서 업데이트합니다(메시에 맞춤설정이 있는 경우). 소스 제어에서 이 오버레이 파일을 유지하는 것이 좋습니다.

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/asm-user-auth/v1.2.3/overlay/user-auth-overlay.yaml > user-auth-overlay.yaml
    
  2. 오버레이가 포함된 Cloud Service Mesh 설치에 따라 Google 제공 스크립트를 사용하여 사용자 인증 오버레이로 Cloud Service Mesh를 설치합니다. 예를 들면 다음과 같습니다.

    ./asmcli install \
      --project_id PROJECT_ID \
      --cluster_name CLUSTER_NAME \
      --cluster_location CLUSTER_LOCATION \
      --fleet_id FLEET_PROJECT_ID \
      --output_dir DIR_PATH \
      --enable_all \
      --custom_overlay user-auth-overlay.yaml
    

    사용자 인증 kpt 패키지는 AuthorizationPolicy를 만들어 pkg/ext-authz.yaml로 지정된 외부 승인 제공업체를 참조합니다.

  3. asm-user-auth 네임스페이스를 만듭니다.

    kubectl create namespace asm-user-auth
    
  4. 네임스페이스의 삽입을 사용 설정합니다.

    권장: 다음 명령어를 실행하여 네임스페이스에 기본 삽입 라벨을 적용합니다.

      kubectl label namespace asm-user-auth \
          istio.io/rev- istio-injection=enabled --overwrite
    

    기본 삽입을 사용하는 것이 좋지만 버전 기반 삽입이 지원됩니다. 다음 안내를 따르세요.

    1. 다음 명령어를 사용하여 istiod에서 버전 라벨을 찾습니다.

      kubectl get deploy -n istio-system -l app=istiod -o \
        jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. 네임스페이스에 버전 라벨을 적용합니다. 다음 명령어에서 REVISION_LABEL은 이전 단계에서 확인한 istiod 버전 라벨의 값입니다.

      kubectl label namespace asm-user-auth \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      
  5. asm-user-auth 네임스페이스에 Istio 게이트웨이를 설치합니다.

    kubectl apply -n asm-user-auth -f DIR_PATH/samples/gateways/istio-ingressgateway
    

OIDC 클라이언트 구성 준비

다음 단계에 따라 OIDC 클라이언트 구성을 설정합니다. 이 가이드에서는 Google을 IDP로 사용하지만 OIDC 인증을 지원하는 IDP는 모두 사용할 수 있습니다.

  1. Google Cloud 콘솔에서 API 및 서비스 > 사용자 인증 정보로 이동합니다.

    사용자 인증 정보로 이동

  2. 사용자 인증 정보 만들기로 이동한 다음 OAuth 클라이언트 ID를 선택합니다. 필요한 경우 OAuth 동의 화면 옵션을 설정한 후 다음 옵션을 구성합니다.

    • 애플리케이션 유형웹 애플리케이션으로 설정합니다.
    • 승인된 리디렉션 URIhttps://REDIRECT_HOST/REDIRECT_PATH로 설정합니다. 예를 들어 localhost의 경우 https://localhost:8443/_gcp_asm_authenticate로 설정할 수 있습니다.

    저장을 클릭합니다.

  3. 또한 나중에 사용할 수 있도록 OIDC 클라이언트 구성을 저장합니다.

    export OIDC_CLIENT_ID=CLIENT_ID
    export OIDC_CLIENT_SECRET=CLIENT_SECRET
    export OIDC_ISSUER_URI=ISSUER_URI
    export OIDC_REDIRECT_HOST=REDIRECT_HOST
    export OIDC_REDIRECT_PATH=REDIRECT_PATH
    

kpt 패키지 가져오기

다음 단계를 따라 공개 저장소에서 권장 authservice 구성을 설치합니다. 아래 명령어는 최신 authservice 컨테이너를 검색하여 이를 asm-user-auth 네임스페이스의 포드로 시작합니다. 또한 모든 요청을 가로채도록 인그레스를 구성합니다.

kpt 패키지를 가져옵니다.

kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth.git/@v1.2.3 .
cd asm-user-auth/

인그레스 게이트웨이용 리디렉션 URL 및 보안 비밀 설정

OAuth2에는 HTTPS로 보호되는 엔드포인트에서 호스팅되는 리디렉션 URL이 필요합니다. 아래 명령어는 예시용으로 Istio 인그레스 게이트웨이용으로 자체 서명 인증서를 생성하여 설정을 간소화한 것입니다.

  1. 자체 서명 인증서를 생성합니다.

    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
     -days 365 -nodes -subj '/CN=localhost'
    
  2. 인그레스 게이트웨이가 HTTPS 트래픽을 호스팅할 보안 비밀을 만듭니다.

    kubectl create -n asm-user-auth secret tls userauth-tls-cert --key=key.pem \
    --cert=cert.pem
    

암호화 및 서명 키 적용

authservice가 성공적으로 작동하려면 두 개의 키 세트가 필요합니다. 첫 번째는 암호화 및 복호화를 위한 대칭 키입니다. 이 키는 세션 상태를 쿠키로 설정하기 전에 세션 상태를 암호화하는 데 사용됩니다.

두 번째 키 세트는 공개 키/비공개 키 쌍입니다. 이 키는 인증된 사용자 정보를 JWT 형식으로 RCToken으로 서명하는 데 사용됩니다. 이 키 쌍의 공개 키는 사이드카가 JWT를 확인하는 데 사용할 수 있는 사전 정의된 엔드포인트에 게시됩니다.

사용자 인증 kpt 패키지에는 빠른 설정을 위한 두 개의 샘플 키가 있습니다. 그러나 원하는 키 관리 시스템을 사용하여 이러한 키를 대신 생성할 수 있습니다.

  1. 다음 형식으로 세션 암호화 키를 준비하거나 cat ./samples/cookie_encryption_key.json에서 볼 수 있는 pkg의 샘플을 사용합니다.

    {
      "keys":[
         {
            "kty":"oct",
            "kid":"key-0",
            "K":"YOUR_KEY",
            "useAfter": 1612813735
         }
      ]
    }
    

    다음 명령어를 사용하여 테스트 AES 키를 생성할 수 있습니다.

    openssl enc -aes-256-cbc -k mycustomkey -P -md sha1 | grep key
    
  2. 다음 형식으로 RCToken 서명 키를 준비하거나 cat ./samples/rctoken_signing_key.json으로 볼 수 있는 pkg의 샘플을 사용합니다.

    {
      "keys":[
         {
            "kty":"RSA",
            "kid":"rsa-signing-key",
            "K":"YOUR_KEY",  # k contains a Base64 encoded PEM format RSA signing key.
            "useAfter": 1612813735  # unix timestamp
         }
      ]
    }
    

    다음 명령어를 사용하여 테스트 256비트 RSA 비공개 키를 생성할 수 있습니다.

    openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:256
    
  3. authservice가 자체 파일 시스템에 마운트할 Kubernetes 보안 비밀을 만듭니다.

    kubectl create secret generic secret-key  \
        --from-file="session_cookie.key"="./samples/cookie_encryption_key.json" \
        --from-file="rctoken.key"="./samples/rctoken_signing_key.json"  \
        --namespace=asm-user-auth
    

사용자 인증 서비스 배포

다음 명령어는 asm-user-auth 네임스페이스에 사용자 인증 서비스 및 배포를 만듭니다.

사용자 인증 구성에 필요한 값을 설정합니다. 클라이언트 ID와 보안 비밀은 Kubernetes 보안 비밀로 저장되므로 Base64를 사용하여 인코딩합니다. 사용 가능한 모든 setter를 보려면 공개 저장소에 방문하세요.

kpt fn eval pkg --image gcr.io/kpt-fn/apply-setters:v0.2 --truncate-output=false -- \
  client-id="$(echo -n ${OIDC_CLIENT_ID} | base64 -w0)" \
  client-secret="$(echo -n ${OIDC_CLIENT_SECRET} | base64 -w0)" \
  issuer-uri="${OIDC_ISSUER_URI}" \
  redirect-host="${OIDC_REDIRECT_HOST}" \
  redirect-path="${OIDC_REDIRECT_PATH}"

kpt 패키지를 적용합니다.

# Remove the potential alpha version CRD if exists.
kubectl delete crd userauthconfigs.security.anthos.io
kubectl apply -f ./pkg/asm_user_auth_config_v1beta1.yaml
kubectl apply -f ./pkg

authserviceUserAuthConfig CRD를 사용하여 최종 사용자 인증을 제공합니다. UserAuthConfig는 런타임 구성이 가능하고 업데이트를 통해 authservice 동작을 변경할 수 있으며 모든 OIDC 승인 서버에 대해 엔드포인트를 사용하여 구성할 수 있습니다.

cat pkg/user_auth_config.yaml로 파일을 볼 수 있으며, 파일에는 다음 필드가 포함되어 있습니다.

apiVersion: security.anthos.io/v1beta1
kind: UserAuthConfig
metadata:
  name: user-auth-config
  namespace: asm-user-auth
spec:
  authentication:
    oidc:
      certificateAuthorityData: ""  # kpt-set: ${ca-cert}
      issuerURI: "<your issuer uri>"  # kpt-set: ${issuer-uri}
      proxy: ""  # kpt-set: ${proxy}
      oauthCredentialsSecret:
        name: "oauth-secret"  # kpt-set: ${secret-name}
        namespace: "asm-user-auth"  # kpt-set: ${secret-namespace}
      redirectURIHost: ""  # kpt-set: ${redirect-host}
      redirectURIPath: "/_gcp_asm_authenticate"  # kpt-set: ${redirect-path}
      scopes: ""  # kpt-set: ${scopes}
      groupsClaim: ""  # kpt-set: ${groups}
  outputJWTAudience: "test_audience"  # kpt-set: ${jwt-audience}

user_auth_config.yaml 필드에 대한 자세한 설명은 사용자 인증 구성 세부정보를 참조하세요.

설치 후 작업 수행

이전 설치 단계를 완료한 후에 다음 작업을 수행해야 합니다.

애플리케이션에 사용자 인증 사용

이 섹션에서는 httpbin을 예시로 사용하여 사용자 인증을 사용 설정하는 방법을 보여줍니다.

Cloud Service Mesh 사용자 인증은 CUSTOM 유형의 승인 정책을 사용하여 OIDC 흐름을 트리거합니다.

Istio 게이트웨이를 설치한 후 위에서 만든 TLS 인증서 userauth-tls-cert를 사용하여 HTTPS 트래픽을 제공하도록 구성합니다. 다음은 방금 설치한 pkg/gateway.yaml 구성입니다.

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: userauth
  namespace: asm-user-auth
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: userauth-tls-cert
---
# This ensures the OIDC endpoint has at least some route defined.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: userauth-oidc
  namespace: asm-user-auth
spec:
  gateways:
  - userauth
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /status
    - uri:
        prefix: "your-oidc-redirect-path"
    name: user-auth-route
    route:
    - destination:
        host: authservice
        port:
          number: 10004
  1. default 네임스페이스에 라벨을 지정하여 배포에 istio-proxy 자동 삽입을 사용 설정합니다.

    kubectl label namespace default istio.io/rev=REVISION --overwrite
    
  2. httpbindefault 네임스페이스에 배포합니다.

    kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml -n default
    
  3. 이 게이트웨이를 사용하여 HTTPS 트래픽을 제공하고, 포트 전달을 사용하여 애플리케이션에 로컬로 액세스하려면 httpbin을 업데이트합니다.

    kubectl apply -f./samples/httpbin-route.yaml -n default
    kubectl port-forward service/istio-ingressgateway 8443:443 -n asm-user-auth
    
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
      namespace: default
    spec:
      gateways:
      - asm-user-auth/userauth
      hosts:
      - '*'
      http:
      - match:
        - uri:
            prefix: /ip
        - uri:
            prefix: /headers
        name: httpbin-routes
        route:
        - destination:
            host: httpbin.default.svc.cluster.local
            port:
              number: 8000
    

    포트 8443의 인그레스 게이트웨이는 애플리케이션에 로컬로 액세스할 수 있도록 localhost로 전달됩니다.

  4. samples/rctoken-authz.yaml을 배포하여 RequestAuthentication 및 AuthorizationPolicy를 사용 설정하여 요청의 RCToken을 확인합니다.

    kubectl apply -f ./samples/rctoken-authz.yaml -n asm-user-auth
    

    samples/rctoken-authz.yaml 예시:

    apiVersion: security.istio.io/v1beta1
    kind: RequestAuthentication
    metadata:
      name: require-rc-token
    spec:
      selector:
        matchLabels:
          istio: ingressgateway
      jwtRules:
      - issuer: "authservice.asm-user-auth.svc.cluster.local"
        audiences:
        - "test_audience"
        jwksUri: "http://authservice.asm-user-auth.svc.cluster.local:10004/_gcp_user_auth/jwks"
        fromHeaders:
        - name: X-ASM-RCTOKEN
        forwardOriginalToken: true
    ---
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: require-rc-token
    spec:
      selector:
        matchLabels:
          istio: ingressgateway
      action: ALLOW
      rules:
      - when:
        - key: request.auth.claims[iss]
          values:
          - authservice.asm-user-auth.svc.cluster.local
        - key: request.auth.claims[aud]
          values:
          - test_audience
    

사용자 인증 확인

httpbin은 2개의 경로를 처리합니다. /ip는 공개적으로 액세스할 수 있으며 /headers는 최종 사용자가 구성된 IDP를 통해 로그인해야 합니다.

  1. https://localhost:8443/ip에 방문하여 직접 /ip에 액세스할 수 있는지 확인합니다.

  2. https://localhost:8443/headers으로 이동하여 OIDC 로그인 페이지가 표시되는지 확인합니다.

  3. 로그인한 후 다음을 클릭하여 /headers 페이지로 리디렉션되는지 확인합니다.

승인 정책 구성

이전 단계의 구성을 완료하면 웹 기반 인증 흐름을 통해 각 사용자가 리디렉션됩니다. 흐름이 완료되면 authservice는 인증된 사용자 정보를 전송하는 데 사용하는 JWT 형식의 RCToken을 생성합니다.

  1. 인그레스에서 Istio 승인 정책을 추가하여 인증된 사용자마다 승인 검사가 수행되도록 합니다.

    kubectl apply -f ./samples/httpbin-authz.yaml -n asm-user-auth
    
  2. httpbin-authz.yaml 파일은 인그레스 게이트웨이를 구성하여 authservice에서 발급한 RC 토큰을 검증하고, JWT에 대상 및 발급기관과 같은 원하는 필드가 포함된 경우에만 승인합니다.

    다음 승인 정책 예시를 참조하세요.

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: require-rc-token
    spec:
      selector:
        matchLabels:
          istio: ingressgateway
      action: ALLOW
      rules:
      - to:
        - operation:
            paths: ["/ip"]
      - to:
        when:
        - key: request.auth.claims[iss]
          values:
          - authservice.asm-user-auth.svc.cluster.local
        - key: request.auth.claims[aud]
          values:
          - test_audience
        - key: request.auth.claims[sub]
          values:
          - allowed_user_sub_1  # Change this with the "sub" claim in the RC token. Wildcard '*' will match everything.
    

환경별 설정 구성

이전 단계에서는 빠른 설정을 위해 localhost와 자체 서명 HTTPS 인증서를 사용합니다. 실제 프로덕션 용도로는 example.com과 같은 자체 도메인을 사용하세요.

또한 certificateAuthorityData에 의도한 루트 인증서 콘텐츠가 있는지 확인합니다. 예를 들어 IDP에서 시스템 루트 인증서를 신뢰할 수 있으면 IDP를 비워 둘 수 있습니다. HTTPS 연결을 종료하는 HTTPS 프록시가 있으면 프록시 루트 인증서로 설정해야 합니다.

키 관리 및 순환

authservice에서는 두 개의 키 세트가 사용됩니다. 각 키를 독립적으로 순환할 수 있습니다. 그러나 키를 순환하기 전에 순환 작동 방식을 이해하는 것이 중요합니다.

두 키는 JSON 형식으로 되어 있습니다. useAfter 필드는 키가 사용되기 시작할 것으로 간주하는 시점의 타임스탬프를 지정합니다. 키 순환 시 JSON에 이전 키와 새 키를 모두 포함해야 합니다. 예를 들어 다음 예시에서 new-key는 타임스탬프 1712813735 이후에만 사용됩니다.

{
   "keys":[
      {
         "kty":"RSA",
         "kid":"old-key",
         "K":"...", # k contains a Base64 encoded PEM format RSA signing key.
         "useAfter": 1612813735, # unix timestamp
      }
      {
      "kty":"RSA",
         "kid":"new-key",
         "K":"...", # k contains a Base64 encoded PEM format RSA signing key.
         "useAfter": 1712813735, # unix timestamp
      }
   ]
}

Cloud Service Mesh는 브라우저 쿠키에 저장된 세션 데이터를 암호화하는 데 대칭 키를 사용합니다. 기존 세션의 유효성을 보장하기 위해 authservice는 키 세트의 모든 키를 사용하여 복호화를 시도합니다. 순환 시 authservice는 새 키를 사용하여 새 세션을 암호화하고 이전 키를 사용하여 복호화를 계속 시도합니다.

공개 키/비공개 키 쌍은 RCToken에 서명하는 데 사용됩니다. 공개 키는 JWT 확인을 위해 istiod를 통해 사이드카로 전송됩니다. authservice가 새 비공개 키를 사용하여 RCToken에 서명하기 전에 사이드카가 새 공개 키를 수신하는 것이 중요합니다. 이를 위해 authservice는 키가 추가된 직후 공개 키를 게시하기 시작하지만 상당한 시간 동안 기다린 뒤 해당 키를 사용하여 RCToken에 서명합니다.

요약하면 키 순환을 수행할 때 다음을 수행하는 것이 좋습니다.

  1. 필요에 따라 정기적 또는 주문형으로 키 순환을 수행합니다.
  2. JSON 형식에 현재 키와 새 키를 모두 포함합니다. 새 키는 미래의 타임스탬프와 연결되어야 합니다. 현재 시간보다 최소 몇 시간 전에 타임스탬프를 지정하는 것이 좋습니다.
  3. 새 키를 사용한 후에도 서비스가 정상 상태인지 모니터링하고 확인합니다. 새 키가 사용된 후 1일 이상 기다린 뒤 다음 단계로 이동합니다.
  4. JSON 항목에서 이전 키는 더 이상 필요하지 않으므로, 삭제합니다.

멀티 클러스터 배포

Cloud Service Mesh 사용자 인증은 멀티 클러스터 배포를 지원합니다. 위에 설명된 대로 각 클러스터에 사용자 인증을 배포해야 합니다. UserAuth 커스텀 리소스, OIDC 클라이언트 보안 비밀번호, 암호화 키와 같은 사용자 인증 구성을 각 클러스터에 복제해야 합니다.

기본적으로 인그레스 게이트웨이는 인증 요청을 authservice 인스턴스 중 하나로 부하 분산합니다. 대상 규칙을 사용하여 동일한 클러스터의 authservice로 요청을 전송하고 다른 클러스터의 authservice로만 장애 조치하도록 인그레스 게이트웨이를 구성할 수 있습니다.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: authservice-fail-over
  namespace: asm-user-auth
spec:
  host: authservice.asm-user-auth.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      localityLbSetting:
        enabled: true
        failover:
        - from:  us-east
          to: us-west
        - from: us-west
          to: us-east

이는 다른 구성과 마찬가지로 각 클러스터에서 구성되어야 합니다.

커스텀 클레임 매핑

커스텀 클레임 매핑을 구성하려면 spec.authentication.oidc.attributeMapping을 구성하여 원래 ID 공급업체의 IDToken에서 모든 매핑을 정의합니다. 키는 RCToken의 클레임 이름이 되며 값은 IDToken에서 클레임을 파싱하는 방법에 대한 CEL 표현식입니다. assertion을 사용하여 IDToken을 참조합니다.

예를 들면 다음과 같습니다.

spec:
  authentication:
    oidc:
      attributeMapping:
        aud_copy: assertion.aud
        decision: 'assertion.sub.startsWith("123") ? "success" : "fail"'

RCToken에서 중첩된 클레임 attributes에는 구성된 클레임이 포함됩니다.

"attributes": {
    "aud_copy": "foo.googleusercontent.com",
    "decision": "success"
}

CEL 표현식이 IDToken에서 값을 파싱하지 못하면 인증 흐름이 실패하지 않고 클레임을 무시합니다.

사용자 인증 업그레이드

  1. 새 user-auth 버전의 업데이트된 바이너리가 포함되어 있으므로 user-auth 패키지를 다시 설치합니다.

    kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth.git/@v1.2.3 .
    cd asm-user-auth/
    
  2. OIDC 클라이언트 구성을 저장합니다.

    export OIDC_CLIENT_ID=CLIENT_ID
    export OIDC_CLIENT_SECRET=CLIENT_SECRET
    export OIDC_ISSUER_URI=ISSUER_URI
    export OIDC_REDIRECT_HOST=REDIRECT_HOST
    export OIDC_REDIRECT_PATH=REDIRECT_PATH
    
  3. 사용자 인증 서비스를 배포하여 새 버전으로 업그레이드합니다.

사용자 인증 구성 세부정보

다음 표에서는 CRD의 각 필드를 설명합니다.

필드 이름 설명
authentication.oidc 이 섹션에서는 OIDC 엔드포인트 구성과 OIDC 흐름에 사용되는 매개변수를 설명합니다.
authentication.oidc.certificateAuthorityData OIDC 승인 서버나 HTTPS 프록시(있는 경우) 도메인의 SSL 루트 인증서입니다.
authentication.oidc.oauthCredentialsSecret JSON 페이로드에 OAuth2 OIDC client_id 및 client_secret을 포함하는 Kubernetes Opaque 유형 보안 비밀에 대한 보안 비밀 참조입니다.
authentication.oidc.issuerURI 출력 RCToken에서 발급기관으로 사용할 URI입니다.
authentication.oidc.proxy 해당하는 경우 서버를 OIDC IDP로 프록시합니다. http://user:password@10.10.10.10:8888 형식을 사용합니다.
authentication.oidc.redirectURIHost OAuth 종료 URI에 사용할 호스트입니다. 이 필드를 비워두면 대상 URL의 호스트가 사용되며 리디렉션 URI는 동적으로 조합됩니다.
이 값은 더 높은 수준의 도메인에서 사용자 인증 SSO 세션을 원하는 경우에 사용할 수 있습니다. 예를 들어 profiles.example.com/과 admin.example.com/ 간에 SSO를 사용 설정하려면 이 값을 example.com으로 설정하면 됩니다. 이렇게 하면 사용자 인증 세션을 example.com에서 설정하여 모든 하위 도메인 간에 공유되도록 합니다. 참고: 여러 도메인이 동일한 메시(example1.com 및 example2.com)에서 제공되는 경우 이 기능을 사용할 수 없으며 비워 두는 것이 좋습니다.
authentication.oidc.redirectURIPath authservice가 OAuth 흐름을 종료하는 엔드포인트 경로입니다. 이 URI 경로 및 호스트를 authentication.oidc.clientID의 승인 서버에서 승인된 리디렉션 URI로 등록해야 합니다.
또한 이 URI는 authservice가 사용 설정된 동일한 서비스 메시 및 인그레스에서 제공되어야 합니다.
authentication.oidc.scopes 인증 요청에서 요청되어야 하는 OAuth 범위입니다. 'openid' 범위 외에 요청되는 액세스 권한을 지정하기 위해 사용되는 쉼표로 구분된 식별자 목록입니다. 예: 'groups,allatclaim'.
authentication.oidc.groupsClaim idtoken에 그룹 클레임이 포함되어 있으면 이 필드를 사용하여 이름을 나타냅니다. 이 서비스를 지정하면 이 클레임의 데이터가 출력 RCToken의 groups 클레임에 전달됩니다. 이 클레임에는 쉼표로 구분된 문자열 목록이 포함되어야 합니다. 예: ['group1', 'group2'].
authentication.oidc.attributeMapping idtoken 다음 CEL 표현식에서 하나 이상의 클레임 매핑을 포함합니다. 모든 클레임이 assertion.X에서 참조되고 assertionaud_copy: assertion.aud.와 같이 원래 IDToken으로 참조됩니다.
authentication.outputJWTAudience authservice에 의해 생성된 RCToken의 대상입니다. 사이드카는 이 대상 값과 대조해 수신 RCToken을 검증할 수 있습니다.

문제 해결

  1. IDP에 대한 네트워크 접근성

    가능한 로그: error: TLS handshake failed.

    istio-proxy에 연결된 임시 컨테이너에서 curl을 실행하여 IDP 발급기관 URI를 호출하여 확인합니다. 예시는 Cloud Service Mesh 로그 수집을 참조하세요.

    연결할 수 없는 경우 클러스터의 방화벽 규칙이나 기타 네트워크 구성을 확인하세요.

  2. 루트 인증기관(CA) 인증서

    가능한 로그: error: The server's TLS certificate did not match expectations. 또는 error: TLS handshake failed.

    certificateAuthorityData에 올바른 루트 CA 인증서가 있는지 확인합니다. HTTPS 트래픽을 종료하는 HTTPS 프록시가 없으면 IDP의 루트 CA 인증서가 있어야 합니다. 이 인증서가 있으면 대신 프록시가 있어야 합니다.

  3. 리디렉션 경로 구성입니다.

    가능한 관찰: OIDC 인증 흐름 중에 404 오류 페이지 수신

    사용자 인증은 경로 속성을 사용하지 않고 'Set-Cookie' 헤더를 반환합니다. 이 경우 기본적으로 브라우저는 요청 URL의 디렉터리를 쿠키 경로(경로와 관련된 쿠키의 범위)로 사용합니다. 따라서 의도한 것이 아니라면 리디렉션 경로에 '/'를 포함하지 않는 것이 좋습니다.

  4. 사이드카가 jwksUri를 가져올 수 없습니다.

    일부 경우에 사이드카 제한으로 인해 jwksUri를 가져올 수 없습니다. 와일드 카드(예: ./* 또는 istio-system/*)를 사용하는 네임스페이스가 없으면 작동하지 않습니다. 이그레스 사이드카에 네임스페이스를 수동으로 추가해야 합니다.

FAQ

  1. 사용자 인증을 사용 설정하여 Cloud Service Mesh를 업그레이드하려면 어떻게 해야 하나요?

    Cloud Service Mesh 업그레이드 프로세스를 수행하고 명령줄에서 --custom_overlay user-auth-overlay.yamlasmcli install에 추가하여 오버레이 파일을 지정합니다.

  2. authservice에 얼마나 많은 리소스를 프로비저닝해야 하나요? 그리고 초당 처리할 수 있는 요청 수는 몇 개인가요?

    기본적으로 authservice는 vCPU 2.0개, 256Mi 메모리로 구성됩니다. 이러한 구성에서 authservice는 초당 500개의 요청을 처리할 수 있습니다. 더 많은 양의 요청을 처리하려면 요청 처리 용량과 대략 비례하는 더 많은 CPU를 프로비저닝해야 합니다. authservice의 여러 복제본을 구성하여 수평적 확장성을 높일 수도 있습니다.