회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
*KubeCon + Cloud Native North America 2023에서 발표한 <Beyond Passwords: Keycloak's Contributions to IAM(Identity and Access Management) + Security>를 정리한 글입니다. 발표 내용을 3회로 나누어 발행합니다. 1부에서는 키클락에 대한 기능 소개와 이점에 대해 살펴보았습니다. 이번 2부에서는 키클락을 구성하기 위해 실행해야 할 사전 작업을 알아보고, 3부에서는 키클락을 사용하여 EKS, GKE와 같은 관리형 쿠버네티스 클러스터를 통합인증 하여 관리하는 방법에 대해 살펴봅니다. 발표 자료는 KubeCon NA 2023 홈페이지에서 다운받으실 수 있습니다.
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
*KubeCon + Cloud Native North America 2023에서 발표한 <Beyond Passwords: Keycloak's Contributions to IAM(Identity and Access Management) + Security>를 정리한 글입니다. 발표 내용을 3회로 나누어 발행합니다. 1부에서는 키클락에 대한 기능 소개와 이점에 대해 살펴보았습니다. 이번 2부에서는 키클락을 구성하기 위해 실행해야 할 사전 작업을 알아보고, 3부에서는 키클락을 사용하여 EKS, GKE와 같은 관리형 쿠버네티스 클러스터를 통합인증 하여 관리하는 방법에 대해 살펴봅니다. 발표 자료는 KubeCon NA 2023 홈페이지에서 다운받으실 수 있습니다.
1부: 신원확인, 통합인증관리 오픈소스 ‘키클락’을 알아보자
2부: 키클락 구성을 위한 기나긴 사전 작업 한번에 보기
3부: 키클락을 활용한 통합 인증 실습하기
이번 2부에서 살펴볼 내용은 다음과 같습니다.
테스트를 위한 사전 준비 작업
모두가 이러한 실습 환경을 꾸미고 테스트할 수 없다는 것을 알고 있기 때문에 가능한 자세하게 실습하는 느낌으로 설명하였습니다. 이를 통해서 내용을 개괄적으로 이해할 수 있으면 좋겠습니다.
지난 번 게시글을 통해서 키클락에 대해 어느정도 이해하셨을 것으로 생각합니다.
이제 실제로 멀티 쿠버네티스 환경에 있는 인증들을 키클락을 통해서 통합 관리하는 방법에 대해서, 실습을 통해 배워보도록 하겠습니다. 통합 인증을 구성하기 위해서 앞서 보여드렸던 [그림 1] 다이어그램과 같은 쿠버네티스 클러스터를 배포하고, 키클락을 구성하기 위해서 긴 사전 작업이 필요합니다.
실습을 진행하기 위해서 사용하는 스크립트 파일을 Git clone을 통해서 내려받습니다.
root@k8s:~# git clone https://github.com/sysnet4admin/IaC.git
Cloning into 'IaC'...
remote: Enumerating objects: 2440, done.
remote: Counting objects: 100% (688/688), done.
remote: Compressing objects: 100% (282/282), done.
remote: Total 2440 (delta 394), reused 673 (delta 379), pack-reused 1752
Receiving objects: 100% (2440/2440), 17.93 MiB | 6.57 MiB/s, done.
Resolving deltas: 100% (1337/1337), done.
Keycloak으로 이동한 후에 디렉터리 구조를 살펴봅니다.
root@k8s:~# cd IaC/Keycloak/
root@k8s:~/IaC/Keycloak# tree
.
├── oncloud-1.site
│ ├── Deploy-infra
│ │ ├── 1-1.deploy-gke-env-w-keycloak.sh
│ │ ├── 1-2.deploy-gke-ingress-4-https-keycloak.yaml
│ │ ├── 1-3.clientconfig-gke-keycloak-w-oidc.yaml
│ │ ├── 2-1.deploy-eks-env-only.sh
│ │ ├── eksctl-config
│ │ │ └── keycloak-w-oidc.yaml
│ │ └── planB-keycloak-by-helm.yaml
│ ├── EKS
│ │ ├── 1.clusterrolebinding-4-devops-group-as-admin.yaml
│ │ ├── 2-oncloud-1.swtich-ctx-hoon-to-soojin.sh
│ │ └── 3.set-cred-4-oidc-user.sh
│ ├── GKE
│ │ ├── 1.clusterrolebinding-4-devops-group-as-admin-NOTWORK.yaml
│ │ ├── 2-hoon.clusterrolebinding-4-devops-user-as-admin.yaml
│ │ └── 2-soojin.clusterrolebinding-4-devops-user-as-admin.yaml
│ └── kubelogin-installer.sh
├── oncloud-2.site
│ ├── Deploy-infra
│ │ ├── 1-1.deploy-gke-env-w-keycloak.sh
│ │ ├── 1-2.deploy-gke-ingress-4-https-keycloak.yaml
│ │ ├── 1-3.clientconfig-gke-keycloak-w-oidc.yaml
│ │ ├── 2-1.deploy-eks-env-only.sh
│ │ ├── eksctl-config
│ │ │ └── keycloak-w-oidc.yaml
│ │ └── planB-keycloak-by-helm.yaml
│ ├── EKS
│ │ ├── 1.clusterrolebinding-4-devops-group-as-admin.yaml
│ │ ├── 2-oncloud-2.swtich-ctx-hoon-to-soojin.sh
│ │ └── 3.set-cred-4-oidc-user.sh
│ ├── GKE
│ │ ├── 1.clusterrolebinding-4-devops-group-as-admin-NOTWORK.yaml
│ │ ├── 2-hoon.clusterrolebinding-4-devops-user-as-admin.yaml
│ │ └── 2-soojin.clusterrolebinding-4-devops-user-as-admin.yaml
│ └── kubelogin-installer.sh
├── prerequisite-install-tools.sh
└── README.md
10 directories, 28 files
root@k8s:~/IaC/Keycloak#
Keycloak 디렉터리에 있는 prerequisite-install-tools.sh 셸 스크립트를 실행합니다.
(참고: 이 부분을 실행한다고 해서 모든 필요 구성이 완료되지 않습니다. 환경에 따라 더 필요한 내용이 있을 수 있습니다.)
root@k8s:~/IaC/Keycloak# cat prerequisite-install-tools.sh
#!/usr/bin/env bash
# krew
(
set -x; cd "$(mktemp -d)" &&
OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
KREW="krew-${OS}_${ARCH}" &&
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
tar zxvf "${KREW}.tar.gz" &&
./"${KREW}" install krew
)
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
# eskctl
brew install eksctl
# kubelogin for GCP
gcloud components install kubectl-oidc
# kubelogin for AWS
kubectl krew install oidc-login
해당 스크립트는 실습에 필요한 gcloud, eksctl, krew를 설치 또는 내려받습니다. 물론 이것 이외에도 환경에 따라 더 많은 사전 준비 작업이 필요할 수 있습니다. 사전에 필요한 내용들이 있다는 것을 명시적으로 알리기 위해서 작성된 스크립트라고 보면 됩니다.
이 실습에서 키클락 통합 인증에 필요 충족 조건인 HTTPS 프토토콜로 키클락으로 접속할 수 있게 조치하기 위해서, 구글 클라우드에서 관리하는 관리형 인증서(MANAGE CERTIFICATE)를 통해 인증서를 사용하도록 처리할 것입니다.
구글에서 관리하는 관리형 인증서를 사용하기 위해 필요한 것이 퍼블릭 환경에서 사용할 수 있는 도메인입니다. 이와 같이 퍼블릭 클라우드 서비스를 이용하여 도메인을 통한 HTTPS 인증서 발급이 가능합니다. 이렇게 인증서를 발급하는 방식을 DNS Authorization이라고 합니다. AWS 이용시에는 Route53을 이용하면 됩니다.
도메인은 호스팅케이알, 가비아, goDaddy 와 같은 도메인 이름 등록기관 업체 홈페이지에서 일정 기간 동안 '임대(lease)'할 수 있습니다. 2편에서는 oncloud-1.site 라는 도메인을 사용해서 진행하도록 하겠습니다.
도메인을 구매하였다면 구글 클라우드에 Cloud DNS 서비스에 아래와 같이 현재 도메인을 연결해주도록 하겠습니다.
위 단계를 전부 진행했다면 이제 키클락을 배포할 GKE 클러스터 배포를 위해서 1번 단계에서 내려받은 디렉터리에서 ./oncloud-1.site/Deploy-infra 디렉터리로 이동합니다. 나타난 디렉터리에서 1-1.deploy-gke-env-w-keycloak.sh셸 스크립트를 실행하도록 하겠습니다. 이 셸 스크립트는 셸 환경 변수로 구글 클라우드 프로젝트, GKE가 배포되는 지역(Zone), GKE의 클러스터 이름과 클러스터 버전을 입력받아서 구글 클라우드로 공인 IP를 생성하고, GKE 클러스터를 입력 값에 맞게 설정한 다음 helm을 통하여 키클락을 배포하도록 설정하고 있습니다. 코드 내용 중 일부를 확인해보면서 GKE 클러스터 생성부터 키클락이 배포되는지 정리해보겠습니다.
<노트>
여기서부터 설명되는 코드는 일부만 발췌해서 설명하는 방식으로 진행되기 때문에 앞 뒤의 코드는 생략되어 있는 경우가 많습니다. 따라서 전체 코드를 살펴보자고 한다면, 해당 파일을 직접 열어서 보시는 것을 권장드립니다.
</노트>
# static ingress IP. It will attach to Domain
gcloud compute addresses create hj-keycloak-oncloud-1-static-ip \
--global \
--ip-version IPV4
키클락이 사용할 공인 IP를 미리 예약하는 것입니다. 이렇게 예약된 공인 IP는 추후 키클락이 배포가 완료된 다음에 GKE에 내장 인그레스 컨트롤러를 통해서 HTTPS 접속이 가능한 도메인과 IP 주소 매핑이 진행됩니다.
# Deploy GKE cluster for keycloak
gcloud container clusters create $KUBE_CLUSTER \
--num-nodes=3 \
--zone=${GCP_ZONE} \
--no-enable-autorepair \
--no-enable-autoupgrade \
--location-policy=BALANCED \
--enable-identity-service \
--cluster-version="${CLUSTER_VERSION}" \
--release-channel=None \
--labels=keycloak=oncloud-1
GKE 클러스터를 생성하는 명령입니다. 이때 GKE에서 키클락 통합 인증을 구성하기 위해 --enable-identity-service 옵션을 사용해서 외부 OIDC를 통한 쿠버네티스 클러스터 인증이 가능하도록 설정합니다. 또한 GKE 클러스터의 경우 자동으로 쿠버네티스 버전이 업그레이드되는 기능이 존재합니다. 이는 실습을 구성했을 때 버전에 따른 사이드 이펙트가 발생할 가능성이 있기 때문에 버전 자동 업그레이드가 진행되지 않도록 --no-enable-autorepair, --no-enable-autoupgrade 옵션을 같이 사용합니다.
# Deploy keycloak
helm install keycloak oci://registry-1.docker.io/bitnamicharts/keycloak \
--set auth.adminUser=admin \
--set auth.adminPassword=admin \
--set production=true \
--set proxy=edge \
--version 17.1.1
GKE 클러스터가 생성된 다음 kubeconfig를 gcloud 명령으로 가져오게 됩니다. 그다음 OCI 차트 저장소로부터 키클락을 설치합니다. 이렇게 키클락을 설치하게 되면 키클락이 동작하는 데 필요한 포스트그레스큐엘 데이터베이스와 키클락이 배포가 됩니다. 이렇게 배포된 키클락의 초기 ID와 패스워드는 admin 입니다.
현재 디렉터리의 1-2.deploy-gke-ingress-4-https-keycloak.yaml 을 kubectl create 을 통해 쿠버네티스 오브젝트를 배포합니다. 이 때 Ingress와 함께 ManagedCertificate, FrontendConfig 와 같은 구글 클라우드의 커스텀 오브젝트가 같이 배포됩니다.
먼저 ManagedCertificate의 내용을 살펴보겠습니다.
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: keycloak-managed-cert
spec:
domains:
- "oncloud-1.site"
oncloud-1.site 도메인에 구글이 관리하는 인증서를 만들라는 내용을 담고 있습니다. 이때 spec.domains 아래로 적용이 되어야 하는 도메인을 입력해야 합니다. 여기서는 oncloud-1.site를 사용하도록 하겠습니다. 이렇게 구성하게 되면 외부에서 키클락 접속 시 oncloud-1.site 라는 도메인으로 접근이 가능합니다.
다음으로 FrontendConfig의 내용을 확인하겠습니다.
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: keycloak-config
spec:
redirectToHttps:
enabled: true
키클락에 첫 화면(프론트엔드)에 접속 시 사용할 네트워크 설정을 입력하는 오브젝트입니다. 여기서는 HTTP 프로토콜로 접속 시 자동으로 HTTPS로 리다이렉트를 처리하라는 내용에 설정이 되어 있습니다.
실제 인그레스(Ingress)가 생성되는 부분입니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: keycloak-ingress
annotations:
spec.ingressClassName: "gce"
kubernetes.io/ingress.global-static-ip-name: "hj-keycloak-oncloud-1-static-ip"
networking.gke.io/managed-certificates: "keycloak-managed-cert"
networking.gke.io/v1beta1.FrontendConfig: "keycloak-config"
spec:
defaultBackend:
service:
name: keycloak
port:
number: 80
이와 같은 설정을 ingress 오브젝트에서 애너테이션으로 참조해, GKE 내부 인그레스 컨트롤러를 통해 키클락을 외부에서 HTTPS 접속할 수 있도록 하는 것입니다. 위 과정을 통해서 키클락을 구성하는 경우 구글이 HTTPS 인증서를 발급하는 데 30분에서 2시간 정도가 소요됩니다.
먼저 GKE에 배포가 완료된 키클락의 주소인 https://oncloud-1.site 로 접속해보겠습니다.
접속하면 다음과 같은 화면이 나타납니다. 나타난 화면에서 아이디는 admin,비밀번호는 admin을 입력하면 배포된 키클락에 접속할 수 있습니다.
접속이 되었다면 좌측 메뉴에 Realm이라고 하는 단위를 설정하는 드롭다운 UI가 있습니다. 현재는 master 값으로 지정이 되어있습니다. 이 Realm은 쿠버네티스의 네임스페이스처럼 키클락 사용자, 인증 대상 애플리케이션 그리고 역할과 같은 것들을 관리하는 공간이라고 이해하시면 됩니다.
이 화면에서 쿠버네티스 통합 인증을 위한 목적으로 사용할 다른 Realm를 생성하기 위해서 Create Realm을 누릅니다.
Create realm 화면에서 쿠버네티스 클러스터 통합 인증을 위해서 Realm name에 kubernetes를 입력하고 Create 버튼을 눌러 kubernetes라는 realm을 생성하도록 하겠습니다.
다음으로 키클락에서 인증에 대상이 되는 단위를 지정하는 Client를 설정하도록 하겠습니다. 이를 위해 키클락 화면 좌측에 위치한 Clients 메뉴로 이동하겠습니다. 나타나는 화면에서 Create client 메뉴를 눌러서 새로운 Client를 생성하도록 하겠습니다.
Client를 생성하면 다음과 같은 화면이 나타납니다.
클라이언트는 쿠버네티스 클러스터 인증에 사용될 것이기 때문에 구분을 위해서 클라이언트 ID와 이름을 모두 k8s-auth로 설정합니다. 다음으로, 인증 시 사용할 클라이언트 타입을 OpenID Connect로 설정하도록 하겠습니다. 여기서 사용하는 OpenID Connect는 JWT(Json Web Token)을 이용하여 사용자 정보를 받아서 사용자의 신원을 확인하는 인증 프로토콜입니다. 마지막으로 Always display in UI 값을 On으로 설정한 다음 Next를 눌러 다음으로 이동하겠습니다.
Client에 대해서 인증과 인가 설정을 모두 활성화하여야 통합 인증이 가능하므로, Client Authentication 및 Client Authorization 모두 On으로 선택한 다음 Next를 눌러서 다음으로 이동하겠습니다.
클라이언트가 인증 사업자(IdP, Identity provider)를 통하여 인증이 완료된 다음에, id 정보를 전달할 곳을 설정하기 위한 화면입니다. 여기서 Valid redirect URIs를 http://localhost:8000 그리고 http://localhost:18000으로 설정한 다음 Save를 눌러서 Client 생성을 완료합니다.
이번 실습에서는 사용자 정보에 기본 그룹 정보를 함께 포함시켜서 쿠버네티스 인증을 처리하고자 합니다. 이렇게 하는 이유는 쿠버네티스에서 직접 RBAC을 통해서 인가를 하기 위해서이며, RBAC을 기본 그룹 단위로 하는 이유는 특별한 설정을 하지 않아도 기본 적용되어 사용이 편리하기 때문입니다. 위의 내용을 처리하기 위해서 Client scopes 탭 메뉴로로 이동합니다.
먼저 Assigned client scope 목록에서 k8s-auth-dedicated를 클릭합니다.
group 필드를 JWT에 추가하기 위해서 Add mapper 드롭다운 버튼의 From predefined mappers를 클릭합니다.
Add predefined mappers 팝업(또는 모달)이 열립니다. 이 중 groups 를 선택하고 Add 버튼을 클릭합니다.
이 'groups' mapper는 JWT groups 키에 사용자의 Realm Role을 매핑하는 역할을 합니다. 이를 통해서 사용자의 Realm role이 JWT에 groups 정보로 추가가 됩니다.
다음으로 사용자에게 적용할 Realm Role을 만들기 위해서 키클락 좌측 메뉴에 위치한 Realm roles 메뉴로 이동 후 Create roles버튼을 클릭합니다.
JWT에 group 필드로 설정하는 값을 devops로 지정하기 위해서 Realm role의 이름을 devops 로 설정하고 Save를 누릅니다.
키클락에서 사용자를 추가하였을 때 사용자 관리를 위한 그룹이 필요합니다. 좌측에 Groups 메뉴로 이동해서 devops 그룹을 만들도록 하겠습니다.
Realm Role과 혼선이 생기지 않도록 그룹의 이름을 devops-group으로 설정하고 Create를 누릅니다.
devops-group 그룹이 생성되었다면, 그룹 단위로 역할을 부여해 devops-group에 있는 사람들은 devops 역할을 가질 수 있도록 'Role mapping' 탭으로 이동한 후, Assign role를 누릅니다.
앞서 생성한 devops 역할을 devops-group 그룹에 설정하기 위해서 devops 체크박스를 선택한 다음에 Assign을 누릅니다.
이 과정을 통해서 우리는 통합 인증에 필요한 인증 설정을 완료하였습니다. 다음으로는 실습 편의를 위하여 키클락 외부로부터 사용자가 키클락에 등록이 될 때 기본적으로 devops-group에 추가되도록 설정하도록 하겠습니다.
좌측 하단에 Realm settings 메뉴 아래 User registration 탭으로 이동합니다. 나타난 화면에서 Default groups탭을 선택 하고 Add groups버튼을 클릭합니다.
최초 사용자가 devops-group 그룹에 들어갈 수 있도록 devops-group을 선택 후 Add를 클릭합니다.
Add 버튼을 누른 후 아래와 같이 Realm에 새롭게 추가되는 사용자에 대해서 devops-group에 추가되도록 설정한 것을 확인할 수 있습니다.
앞서 [그림 1] 다이어그램에서 구글 API를 통해서 사용자를 가져오는 것을 확인할 수 있습니다. 이는 구글 API를 통해 구글 사용자 정보를 키클락에 저장시키는 기능인 Identity providers를 사용해서 연동을 진행합니다. 이 연동을 구성하기 위해서 먼저 구글 API에 접근할 수 있는 권한을 설정해야 합니다. 따라서 구글 클라우드 콘솔에서 Google API & Services > Credentials 메뉴로 이동하여서 연동 정보를 받은 후 키클락에서 구글 로그인을 통한 사용자 정보를 받을 수 있도록 처리하겠습니다.
구글 클라우드 콘솔 이동하였을 때 상단의 + CREATE CREDENTIALS를 클릭하고 OAuth client ID를 선택합니다.
Application type은 현재 키클락이 웹으로 배포되어있으니 Web application으로 설정하고, 이름은 hj-keycloak-oncloud-1-cred로 설정하고 Create를 누릅니다.
생성을 완료하면 keycloak Client의 Client ID와 Client Secret이 출력된 팝업으로 나타납니다.
Client ID와 Client Secret은 키클락과 구글 사용자 인증정보를 연결해주는 역할을 합니다.
이 부분은 팝업으로 보기 어려우므로 [그림 25]를 통한 연결 구조로 다시 한번 설명하겠습니다.
정보를 확인하였다면 다시 키클락에서 Identity providers 메뉴로 이동한 후, 구글을 선택해서 구글 사용자가 키클락에 등록될 수 있도록 합니다.
구글 클라우드의 Google API & Services > Credentials 메뉴에서 생성한 Client ID(hj-keycloak-oncloud-1-cred)의 Client ID와 Client secret 값을 Google API & Services의 keycloak Client에서 명시된 Client ID와 Client secret 값으로 입력합니다.
여기서 Client ID와 Client Secret은 공개키와 개인키 역할을 합니다. Client ID는 공개되어 있지만, Client ID를 통해 받은 JWT를 복호화 하는 역할은 Client Secret이 수행합니다. 그렇기 때문에 Client Secret은 공개되면 안 되는 중요한 정보입니다.
구글 클라우드의 Google API & Services > Credentials 메뉴에서 생성한 Client ID(hj-keycloak-oncloud-1-cred)의 Authorized redirect URIs 주소를 Keycloak의 Redirect URI주소로 입력합니다.
이를 그림으로 표현하면 다음과 같습니다.
키클락과 구글 클라우드 콘솔에 대해서 값을 위와 같이 같이 설정한 후, 키클락의 설정을 적용하기 위해 Save를 클릭합니다.
EKS 등 관리형 쿠버네티스 서비스들은 OIDC 방식의 인증을 구성할 때, 사용자 인증하는 방식으로 이메일 인증을 요구합니다. 이런 보안 요구사항을 만족하기 위해서 이메일 인증 옵션을 켠 후, 구글 SMTP 서버를 사용해서 이메일을 보낼 수 있는 설정을 진행하도록 하겠습니다.
키클락에서 이메일 인증 기능을 통해 이메일 발송을 설정하기 위해서, 키클락 관리자에 정보를 채워야합니다. 따라서 우측 상단 admin 드롭다운을 클릭한 다음에 Manage account를 누릅니다.
눌러서 나타난 화면에서 관리자 정보를 변경하기 위해서 Personal info 를 클릭합니다.
관리자의 이메일과 이름을 입력 후 Save를 클릭합니다.
다시 진행하던 이메일 발송 설정을 하기 위해 상단의 Back to security admin console을 클릭합니다.
오른쪽 상단에 admin의 이름이 변경된 것을 확인합니다.
사용자의 이메일 인증을 사용하기 위해서 Realm settings 메뉴의 로그인 탭에서 스크롤을 내려 Verify email 옵션을 On으로 설정합니다.
이메일 인증에 대한 옵션이 켜졌다면, 이메일을 보내기 위한 설정을 진행하기 위해서 Realm Settings에 Email 탭으로 이동합니다.
Email 탭의 Template 설정을 아래와 같이 구성합니다.
Email 탭 아래 Connection & Authentication 설정을 아래와 같이 구성합니다.
입력 후, Save를 눌러서 저장합니다.
길고 험난한 사전 작업을 완료했습니다. 앞으로는 키클락의 Client를 활용해 여러 쿠버네티스 클러스터의 인증을 OIDC를 통해서 처리하는 실습을 진행하도록 하겠습니다.
요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.