Anthos Service Mesh 사용자 인증 구성

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

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

작동 방식

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

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

최종 사용자 인증

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

사용자 인증 서비스 설치

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

기본 요건

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

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

사용자 인증 서비스를 설치하려면 ASM 설치를 맞춤설정하여 메시 수준의 외부 승인 제공업체를 추가해야 합니다.

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

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

    /install_asm \
     --project_id "PROJECT_ID" \
     --cluster_name "CLUSTER_NAME" \
     --cluster_location "CLUSTER_LOCATION" \
     --mode install \
     --enable_all \
     --custom_overlay user-auth-overlay.yaml
    

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

OIDC 클라이언트 구성 준비

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

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

    사용자 인증 정보로 이동

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

    • 애플리케이션 유형웹 애플리케이션으로 설정합니다.
    • 승인된 리디렉션 URIhttps://localhost:8443/_gcp_anthos_callback으로 설정합니다.

    저장을 클릭합니다.

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

    export OIDC_CLIENT_ID='<your-client-id>'
    export OIDC_CLIENT_SECRET='<your-client-secret>'
    export OIDC_ISSUER_URI='https://accounts.google.com'
    # The host where your application is served from, such as https://example.com
    export OIDC_REDIRECT_HOST='<your-oidc-redirect-host>'
    export OIDC_REDIRECT_PATH='<your-oidc-redirect-path>'
    

kpt 패키지 가져오기

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

  1. kpt 패키지를 가져옵니다.

    kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth@release-1.0 .
    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 istio-system secret tls userauth-tls-cert --key=key.pem \
    --cert=cert.pem
    

암호화 및 서명 키 적용

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

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

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

  1. 키를 생성한 후 키 데이터를 동일한 형식으로 입력합니다.

    cat ./samples/rctoken_signing_key.json
    {
      "keys":[
         {
            "kty":"RSA",
            "kid":"rsa-signing-key",
            "K":"YOUR_KEY", # k contains a Base64 encoded PEM format RSA signing key.
            "useAfter": 1612813735, # unix timestamp
         }
      ]
    }
    
    cat ./samples/cookie_encryption_key.json
    {
      "keys":[
         {
            "kty":"oct",
            "kid":"key-0",
            "K":"YOUR_KEY",
            "useAfter": 1612813735
         }
      ]
    }
    
  2. authservice가 자체 파일 시스템에 마운트할 Kubernetes 보안 비밀을 만듭니다.

    Istiod 배포를 확인하여 REVISION 라벨 값을 찾을 수 있습니다.

    kubectl create namespace asm-user-auth
    kubectl label namespace asm-user-auth istio.io/rev=REVISION --overwrite
    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 네임스페이스에 사용자 인증 서비스 및 배포를 만듭니다.

  1. oauth 변수를 설정합니다. 클라이언트 ID와 보안 비밀은 Kubernetes 보안 비밀로 저장되므로 Base64를 사용하여 인코딩합니다.

    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientID $(echo -n ${OIDC_CLIENT_ID} | base64 -w0)
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientSecret $(echo -n ${OIDC_CLIENT_SECRET} | base64 -w0)
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.issuerURI ${OIDC_ISSUER_URI}
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.redirectURIHost ${OIDC_REDIRECT_HOST}
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.redirectURIPath ${OIDC_REDIRECT_PATH}
    
  2. 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: ""
      oauthCredentialsSecret:
        name: "oauth-secret"
        namespace: "asm-user-auth"
      issuerURI: "https://accounts.google.com"
      redirectURIHost: ""
      redirectURIPath: "/_gcp_asm/authenticate"

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

설치 후 작업 수행

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

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

이 섹션에서는 Online Boutique 샘플 애플리케이션을 예시로 사용하여 사용자 인증을 사용 설정하는 방법을 보여줍니다.

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

또한 설치 프로세스는 위에서 만든 TLS 인증서 userauth-tls-cert를 사용하여 HTTPS 트래픽을 제공하는 Istio 게이트웨이를 만듭니다. 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. 이 게이트웨이를 사용하여 HTTPS 트래픽을 제공하고, 포트 전달을 사용하여 애플리케이션에 로컬로 액세스하려면 Online Boutique 애플리케이션을 업데이트합니다.

    kubectl apply -f./samples/boutique-route.yaml -n demo
    kubectl port-forward service/istio-ingressgateway 8443:443 -n istio-system
    

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

  2. https://localhost:8443/에서 Online Boutique 샘플 애플리케이션에 액세스할 수 있는지 확인합니다.

사용자 인증 확인

이제 Online Boutique 애플리케이션 서비스에서 최종 사용자가 Google 계정을 통해 로그인해야 합니다.

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

  2. 로그인한 후 다음을 클릭하여 Online Boutique 홈페이지로 리디렉션되는지 확인합니다.

승인 정책 구성

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

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

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

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

    apiVersion: security.istio.io/v1beta1
    kind: RequestAuthentication
    metadata:
     name: require-rc-token
     namespace: istio-system
    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
     namespace: istio-system
    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
    

환경별 설정 구성

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

또한 UserAuthConfig CRD에 구성된 tokenEndpointauthorizationEndpointVirtualService에 구성된 경로가 있는지 확인합니다. 이전 설치 단계에서는 asm-user-auth/userauth-oidc VirtualService에서 이를 설정했습니다.

키 관리 및 순환

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
      }
   ]
}

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

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

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

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

사용자 인증 구성 세부정보

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

필드 이름 설명
authentication.oidc 이 섹션에서는 OIDC 엔드포인트 구성과 OIDC 흐름에 사용되는 매개변수를 설명합니다.
authentication.oidc.certificateAuthorityData OIDC 승인 서버 도메인의 SSL 인증서입니다.
authentication.oidc.clientSecret JSON 페이로드에 OAuth2 OIDC client_id 및 client_secret을 포함하는 Kubernetes Opaque 유형 보안 비밀에 대한 보안 비밀 참조입니다.
authentication.oidc.issuerURI 출력 RCToken에서 발급기관으로 사용할 URI입니다.
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 범위입니다.
authentication.oidc.groupsClaim `idtoken`에 그룹 클레임이 포함되어 있으면 이 필드를 사용하여 이름을 나타냅니다. 이 서비스를 지정하면 이 클레임의 데이터가 출력 RCToken의 `groups` 클레임에 전달됩니다.
authentication.outputJWTAudience `authservice`에 의해 생성된 RCToken의 대상입니다. 사이드카는 이 대상 값과 대조해 수신 RCToken을 검증할 수 있습니다.

멀티 클러스터 배포

Anthos 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

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

FAQ

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

    Anthos Service Mesh 업그레이드 프로세스에 따라 명령줄에서 user-auth.yaml 오버레이 파일을 지정하여 install_asm를 수행합니다.

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

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