Okta 및 NGINX Ingress Controller를 사용하여 Kubernetes용 OpenID Connect 인증 구현

오늘날의 랜섬웨어 및 Bot 기반 공격 환경에서 앱과 API를 보호하는 것은 매우 중요합니다. WAF(Web Application Firewall)와 같은 메커니즘과 함께 User identities를 인증하고 권한 부여 제어를 시행하는 것은 비즈니스 애플리케이션을 보호하는 중요한 방법입니다.

인증 및 권한 부여를 구현하는 가장 직접적인 방법은 애플리케이션 자체에 있습니다. 이는 사용자 기반이 적고 앱을 자주 업데이트할 필요가 없을 때 작동할 수 있지만 규모에 따라 빠르게 유지될 수 없게 됩니다. 우선, 사용자가 여러 앱 각각에 대해 다른 계정 이름과 비밀번호를 기억해야 할 때 로그인을 시도할 때 종종 실망스러운 “잘못된 사용자 이름 또는 비밀번호” 메시지가 표시되어 다음과 같은 안전하지 않은 솔루션에 의존하게 됩니다. 쉽게 추측되는 “abc123” 암호. 그리고 우리는 모두 모니터에 비밀번호 알림이 있는 포스트잇 메모가 후광으로 장식된 것을 본 적이 있습니다!

SSO(Single Sign-On) 기술은 하나의 자격 증명 세트를 위해 별도의 사용자 이름과 암호를 모두 제거하여 이러한 문제를 부분적으로 해결할 수 있습니다. 사용자는 IdP(Identity Provider)로 한 번만 로그인하여 많은 앱에 액세스할 수 있습니다. 그러나 개발자는 SSO 시스템과 인터페이스하기 위해 앱에 코드를 포함해야 하며, 이는 특히 애플리케이션이 복잡해짐에 따라 매우 어려울 수 있습니다.

조직이 확장되고 급증하는 사용자 기반의 요구 사항을 충족해야 함에 따라 인증 및 권한 부여와 같은 앱 기능과 관련이 없는 요구 사항을 애플리케이션 계층에서 오프로드(offload)하는 것이 중요해집니다. Kubernetes에서 중앙 집중식 인증 및 권한 부여를 위한 이상적인 위치는 클러스터에 들어오는 모든 트래픽을 조사하고 적절한 서비스로 라우팅할 수 있는 Ingress 컨트롤러입니다. 이를 통해 개발자는 인증 논리를 구축, 유지 관리 및 복제해야 하는 부담에서 벗어날 수 있으며 기본 Kubernetes API를 사용하여 수신 계층에서 SSO 기술을 쉽게 활용할 수 있습니다.

이 모범사례에서는 NGINX Plus 기반 NGINX Ingress Controller로 본격적인 SSO 솔루션을 구현하고 Okta를 사전 구성된 IdP(ID 공급자)로 사용하여 OIDC 인증 코드 흐름을 지원하는 방법을 보여줍니다.

참고: 이 기능은 NGINX 오픈소스 기반 NGINX Ingress Controller에서 사용할 수 없습니다.

목차

1. 전제 조건
2. IdP 사전 구성
3. NGINX Ingress Controller 구성
  3-1. 클라이언트 자격 증명 암호 정의
  3-2. 인증(Auth) Endpoint 가져오기
  3-3. NGINX Ingress OIDC 정책 정의
  3-4. VirtualServer 개체 정의
4. 환경 테스트
5. 애플리케이션에 사용자 추가
6. SSO용 다중 앱 통합 생성
7. 결론

1. 전제 조건

Kubernetes 환경에서 작업한 경험이 있다고 가정합니다. 또한 다음이 필요합니다.

  • Kubernetes 환경 – NGINX Ingress Controller는 Amazon Elastic Kubernetes(EKS), 베어메탈, Google Kubernetes Engine(GKE), Microsoft Azure Kubernetes Service(AKS), Rancher Kubernetes Engine 및 Red hat Openshift를 비롯한 다양한 Kubernetes 플랫폼은 물론 바닐라 Kubernetes에서도 지원됩니다.
  • NGINX Plus 기반 NGINX Ingress Controller – NGINX Plus 기반 버전의 NGINX Ingress Controller에 대한 유효한 라이선스가 있어야 합니다. 30일 무료 평가판을 요청하여 오늘 라이선스를 시작할 수 있습니다. 추가 정보는 설명서를 참조하십시오.
  • Okta 개발자 계정 – Okta를 IdP로 구성하려면 먼저 개발자 계정에 가입하십시오. 또는 Okta 명령줄 인터페이스(CLI)를 다운로드하고 okta register 명령을 실행하여 새 계정에 등록합니다. 작성 당시 Okta CLI는 베타 버전이며 프로덕션 사용에는 권장되지 않습니다.

2. IdP 사전 구성

클라우드 서비스는 IdP가 필요한 위치에서 사용자 ID를 검색하고 확인할 위치를 알아야 합니다. IdP는 디지털 ID를 안전하게 관리 및 저장하고 공격자가 사용자를 가장하기 위해 ID를 도용할 수 없도록 합니다.

이 섹션에서는 Okta CLI를 사용하여 Okta를 IdP로 미리 구성하여 Okta에서 앱 통합이라고 부르는 것을 생성합니다.

1. okta 로그인 명령을 실행하여 Okta 개발자 계정으로 Okta CLI를 인증합니다. 프롬프트에서 Okta 도메인과 API 토큰을 입력합니다.

$ okta login 
Okta Org URL: https://your-okta-domain
Okta API token: your-api-token

2. 앱 통합 생성:

$ okta apps create --app-name=mywebapp --redirect-uri=http[s]://ingress-controller-hostname/_codexch
  • –app-name은 애플리케이션 이름을 정의합니다(여기서는 mywebapp).
  • –redirect-uri는 로그인이 리디렉션되는 URI를 정의합니다(여기서는 ingress-controller-hostname/_codexch).

3. 프롬프트에 대한 응답으로 응용 프로그램 유형을 지정하십시오. 처음에는 1(웹 응용 프로그램을 나타냄) 다음으로 5(나열된 것 이외의 프레임워크를 나타냄)로 지정합니다.

Type of Application
(The Okta CLI only supports a subset of application types and properties):
> 1: Web
> 2: Single Page App
> 3: Native App (mobile)
> 4: Service (Machine-to-Machine)
Enter your choice [Web]: 1
Type of Application
> 1: Okta Spring Boot Starter
> 2: Spring Boot
> 3: JHipster
> 4: Quarkus
> 5: Other
Enter your choice [Other]: 5
Configuring a new OIDC Application, almost done:
Created OIDC application, client-id: 0oa1mi...OrfQAg5d7

3. NGINX Ingress Controller 구성

NGINX Ingress Controller의 NGINX Plus 기반 버전을 사용자를 인증하는 중계 당사자로 구성합니다.

3-1. 클라이언트 자격 증명 암호 정의

보안상의 이유로 OIDC 정책 개체에서 클라이언트 암호를 하드코딩하는 것은 지원되지 않습니다. 대신 클라이언트 암호의 base64 인코딩 값이 포함된 데이터로 Kubernetes 암호를 만듭니다.

apiVersion: v1
kind: Secret
metadata:
  name: oidc-secret
type: nginx.org/oidc
data:
  client-secret: base64-encoded-value-of-client-secret 

그런 다음 Secret(여기에서는 client-secret.yaml)이 포함된 YAML 파일을 적용합니다.

$ kubectl apply –f client-secret.yaml

3-2. 인증(Auth) Endpoint 가져오기

OAuth 2.0 및 OpenID Connect API를 사용하여 Okta가 권한 부여 서버에서 노출하는 Endpoint에 대한 정보를 얻으십시오.

로컬 머신에서 다음 명령을 실행하여 Okta 엔드포인트에 대한 정보를 출력합니다. 샘플 출력에 표시된 것처럼 authorization_endpoint, token_endpoint 및 jwks_uri의 값을 기록해 두십시오. 다음 섹션에서 사용합니다.

$ curl -i https://your-okta-domain/.well-known/openid-configuration
{
    "authorization_endpoint": "https://your-okta-domain/oauth2/v1/authorize",
    ...
    "jwks_uri": "https://your-okta-domain/oauth2/v1/keys",
    ...
    "token_endpoint": "https://your-okta-domain/oauth2/v1/token",
 ...
 }

3-3. NGINX Ingress OIDC 정책 정의

OIDC 기반 인증에 대한 지원이 NGINX Ingress Controller 1.10.0에 추가되었습니다. 자세한 내용은 NGINX STORE Best Practices에서 OpenID Connect 및 NGINX Ingress Controller를 사용한 쉽고 강력한 싱글 사인온을 읽어보세요.

OIDC 인증의 NGINX Ingress Controller 구현은 NGINX Ingress Controller에서 OIDC 정책을 정의하는 Kubernetes 사용자 지정 리소스인 정책 개체를 사용합니다.

1. Policy 개체의 authEndpoint, tokenEndpoint 및 jwksURI 필드에 이전 섹션에서 얻은 정보를 삽입합니다.

apiVersion: k8s.nginx.org/v1
kind: Policy
metadata:
  name: oidc-policy
spec:
  oidc:
    clientID: client-id
    clientSecret: oidc-secret
    authEndpoint: https://your-okta-domain/oauth2/v1/authorize
    tokenEndpoint: https://your-okta-domain/oauth2/v1/token
    jwksURI: https://your-okta-domain/oauth2/v1/keys

2. 정책을 적용합니다(여기서 oidc.yaml에 정의됨).

$ kubectl apply -f oidc.yaml

3. (선택 사항) 정책의 유효성을 확인합니다.

$ kubectl get policy 

NAME          STATE   AGE
oidc-policy   Valid   2m

3-4. VirtualServer 개체 정의

VirtualServer 및 VirtualServerRoute는 들어오는 트래픽을 Kubernetes 클러스터의 백엔드 애플리케이션으로 라우팅하기 위한 규칙을 프로비저닝하는 NGINX Ingress 리소스입니다. OIDC 정책이 적용되려면 VirtualServer 또는 VirtualServerRoute 리소스에서 참조되어야 합니다.

1. / 경로 접두사 아래에 OIDC 정책을 참조하여 요청이 app-server-payload 서비스에 프록시되기 전에 접두사와 일치하는 경로를 요청하는 사용자가 인증되도록 합니다.

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: app-ingress
spec:
  host: unit-demo.linkpc.net
  upstreams:
  - name: app-server-payload
    service: app-server-svc
    port: 80
  routes:
  - path: /
    policies:
    - name: oidc-policy
    action:
      proxy: 
        upstream: app-server-payload

2. VirtualServer 리소스를 적용합니다(여기에서 app-virtual-server.yaml에 정의됨).

$ kubectl apply -f app-virtual-server.yaml

3. (선택 사항) 리소스의 유효성을 확인합니다.

$ kubectl get vs

NAME          STATE   HOST                   IP    PORTS   AGE
app-ingress   Valid   unit-demo.linkpc.net                 2m

4. 환경 테스트

OIDC Okta 통합이 올바르게 작동하는지 테스트하려면 브라우저의 주소 표시줄에 NGINX Ingress Controller의 호스트 이름을 입력하십시오. Okta 로그인 포털로 리디렉션되며 여기에서 Okta 개발자 계정의 자격 증명을 입력하여 backend 애플리케이션에 액세스할 수 있습니다.

성공적으로 인증되면 app-server-payload 업스트림 서비스에 액세스할 수 있습니다.

5. 애플리케이션에 사용자 추가

대부분의 경우 조직의 여러 사용자가 앱에 액세스해야 합니다. Okta 관리 콘솔의 디렉토리 범주 아래 사람 페이지에서 각 사용자를 추가합니다.

6. SSO용 다중 앱 통합 생성

Okta를 IdP로, NGINX Ingress Controller를 중계 당사자로 사용하여 SSO를 구성하여 하나의 애플리케이션에서 인증 프로세스를 오프로드(offload)했습니다. 실제로는 사용자가 단일 자격 증명 집합을 사용하여 많은 응용 프로그램에 액세스할 수 있도록 하고 싶을 것입니다. 사용자가 액세스할 수 있는 응용 프로그램을 다양화할 수 있는 유연성을 원할 수도 있습니다.

다른 애플리케이션을 Okta와 통합하고, 다른 OIDC 정책을 정의하고, VirtualServer 리소스에서 정책을 참조하여 이를 수행할 수 있습니다. 다이어그램에 표시된 예에는 NGINX Ingress Controller의 외부 IP 주소로 확인되는 두 개의 하위 도메인인 unit-demo.marketing.net 및 unit-demo.engineering.net이 있습니다. NGINX Ingress Controller는 하위 도메인을 기반으로 마케팅 앱 또는 엔지니어링 앱으로 요청을 라우팅합니다. 사용자에게 액세스 권한을 부여하려면 Okta GUI의 할당 탭에서 사용자를 적절한 각 애플리케이션과 연결합니다. 그런 다음 Okta는 인증된 사용자에게 해당 애플리케이션에 액세스할 수 있는 단기 세션 쿠키를 부여합니다.

7. 결론

NGINX Ingress Controller를 릴레이 당사자로, Okta를 IdP로 사용하여 Kubernetes에서 OIDC 기반 SSO를 구현하면 개발자의 인증 및 권한 부여를 오프로드(offload)하여 개발자가 앱에서 비즈니스 로직을 최적화하는 데 집중할 수 있습니다.

NGINX STORE 뉴스레터 및 최신 소식 구독하기

* indicates required