요건
- keycloak을 이용하여 그라파나에 접속할 수 있도록 SSO 설정
환경
- Ubuntu 20.04 서버 1대
- Docker version 24.0.4
프로세스
- keycloak과 SSO
- 환경 준비
- Grafana 설치
- keycloak 설치 및 접속설정
- Realm, Client 생성 및 설정
- jwt 토큰 발급 테스트 및 Grafana 설정 변경
- Grafana 접속 및 SSO 확인
주의사항
- 서버의 공인아이피를 통해 리다이렉트 되는 작업이 있으므로 서버의 ACG의 인바운드에 공인아이피에 대한 포트 허용 설정을 진행해야 합니다.
1. Keycloak과 SSO
◆ keycloak이란?
Keycloak은 오픈 소스 기반의 단일 로그인 (SSO) 및 ID 및 접근 관리 솔루션입니다. Red Hat에서 개발하고 지원하는 프로젝트이며, 기업에서 웹 및 모바일 애플리케이션, 서비스, API 등을 보호하고 사용자 인증 및 권한 부여를 관리하는 데 사용됩니다.
주요 기능으로는 단일 로그인(SSO), 사용자 관리, 클라이언트 애플리케이션 지원, ID 및 접근제어등이 있습니다.
◆ SSO란?
SSO(단일 로그인)는 사용자가 여러 시스템 또는 서비스에 대해 단일 인증으로 접근하는 기술입니다. 사용자가 한 번 로그인하면, 다른 연결된 시스템이나 서비스에서 별도의 인증 없이 자동으로 로그인됩니다. 또한 SSO는 사용자 경험과 보안을 향상시키는데 도움이 됩니다.
이번에는 Keycloak의 SSO 기능을 이용해 Grafana에 로그인해보도록 하겠습니다.
2. 환경 준비
1대의 Ubuntu 20.04 서버를 준비하고 Docker를 설치합니다.
저는 Naver Cloud Platform을 통해 1대의 서버를 준비하였습니다.
아래글을 참조하여 Docker 설치까지 진행합니다.(도커 버전의 경우 설치 시점에 따라 더 높은 버전으로 설치될 수 있습니다.)
2022.08.29 - [Docker-k8s] - NCP Server(ubuntu)를 이용한 Docker, kubernetes 설치(k8s cluster 구축)
3. Grafana 설치
도커 명령어를 통해 Grafana 설치를 진행합니다.
docker run -d -p 3000:3000 grafana/grafana
도커 웹페이지에 접속하여 admin 계정으로 로그인한 뒤, 비밀번호를 변경합니다.
초기 계정 : admin/admin
*그라파나 웹 접속
http://서버공인아이피:3000
*접속 이후 비밀번호 변경 진행
4. keycloak 설치 및 접속설정
도커 명령어를 통해 keycloak 이미지를 받아오고 관리자 페이지 접속을 위한 아이디와 비밀번호를 설정합니다.
릴리즈 버전이 여러가지 있지만 이번에는 22.0.1버전으로 진행하도록 하겠습니다.
docker run -dti -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:22.0.1 start-dev
서버의 아이피를 통해 keycloak에 접속합니다.
http://서버공인아이피:8080
이후 진행할 설정을 위해 Administration Console에 접속해야 합니다만, 실행 이후 접속해보면 아래와 같이 HTTPS required라는 문구가 뜨면서 접속이 되지 않습니다.
관리자 콘솔 접속을 위해 도커 컨테이너 내부에 들어가서 추가 설정을 진행합니다.
docker exec -it [keycloak 컨테이너 아이디] bash
cd /opt/keycloak/bin
./kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin
Enter password: 관리자 비밀번호 입력
./kcadm.sh update realms/master -s sslRequired=NONE
설정을 마치고 다시 웹페이지로 돌아와서 관리자 콘솔을 클릭후 계정을 입력하면 아래와 같은 화면을 확인할 수 있습니다.
5. realm, client 생성 및 설정
keycloak으로 SSO 설정을 진행하기 전에 먼저 Realm과 client라는 개념에 대해서 알아야 합니다.
◆Keycloak Realm: Keycloak에서는 하나의 Realm은 독립된 보안 영역으로, 사용자, 클라이언트 애플리케이션, 사용자 그룹, 역할 등을 관리하는 단위입니다. 서버는 여러 개의 Realm을 가질 수 있으며, 각 Realm은 완전히 격리된 환경을 제공합니다.
◆Keycloak Client: 클라이언트는 Keycloak Realm 내에서 인증과 권한 부여를 받기 위해 등록된 애플리케이션입니다. 각 클라이언트는 자체적인 클라이언트 ID와 시크릿(비밀 키)을 가지고 있으며, 이를 사용하여 Keycloak과 통신하고 보안 기능을 활용합니다. 클라이언트는 웹 애플리케이션, 모바일 앱, 서비스 등 다양한 종류의 애플리케이션을 나타냅니다.
이번에는 Master Realm을 그대로 사용하지 않고 새로운 Realm을 생성합니다. > "Create Realm"
keycloak 설정 순서는 다음과 같습니다.
Realm 생성 -> Client 생성 -> Client Roles 설정 -> Client scopes 설정 -> User 생성
1.Realm 생성
Grafana라는 이름으로 새로운 Realm을 생성합니다.
추가로 새로 생성한 Realm 접속시 HTTPS Required를 막기 위해 Realm Settings > General > Require SSL 설정을 "None"으로 설정합니다.
2. Client 생성
생성한 Realm이 설정된 것을 확인하고 Clients > Create client를 통해 클라이언트 생성을 진행합니다.
클라이언트 아이디를 지정합니다.
Client ID : grafana-client
Capability config는 아래와 같이 설정합니다.
*Client authentication을 체크하지 않으면 추후 client-secret을 확인할 수 있는 credential 탭이 보이지 않습니다.
Login settings에서 다음과 같이 설정합니다.
*Root URL : 서비스의 root url
*Valid redirect URIs : 로그인/로그아웃 이후 리다이렉트되는 URI
Root URL : ${authBaseUrl}
...
Valid redirect URIs
- http://서버의공인아이피:3000/*
- http://서버의공인아이피:8080/*
3. Client Role 설정
Client > Client detalis > Roles 에서 클라이언트 역할을 생성합니다.
역할 생성 이후 "Add associated roles" 를 설정합니다.
4. Client Scopes 설정
클라이언트 애플리케이션 권한 부여를 위해 Client Scopes를 생성합니다.
Client scopes > grafana-client-dedicated
먼저 Full scope allowed 를 Off로 변경합니다.
인증된 사용자의 프로필 정보를 가져와서 클라이언트 애플리케이션에 제공하기 위해 생성한 Mappers를 설정합니다.
Mappers > Configure a new mapper
Mapper type : User Client Role
Name : Roles
Client ID : grafana-client
...
Token Claim Name : roles
...
*나머지는 기본 설정으로 진행합니다.
생성한 클라이언트를 사용할 실제 유저를 생성합니다.
Users > Create user
Username : test
Email : test@naver.com
생성한 유저의 패스워드를 설정합니다.
> Credentials
Client와 마찬가지로 user에 역할을 매핑합니다.
> Role mapping
6. jwt 토큰 발급 테스트 및 Grafana 설정 변경
토큰이 정상적으로 발행되는 것을 확인하기 위해 jwt 토큰 발급 테스트를 진행할 수 있습니다.
curl -s \
-d "client_id=grafana-client" \
-d "client_secret=<Client에서 확인한 시크릿>" \
-d "username=test" \
-d "password=test" \
-d "grant_type=password" \
"http://localhost:8080/realms/Grafana/protocol/openid-connect/token"
출력된 json 내용은 https://jwt.io/#debugger-io 에서 디코딩할 수 있습니다.
토큰이 정상적으로 발급되었다면 아래와 같이 확인할 수 있습니다.
그라파나 컨테이너 내부로 들어가서 설정 변경을 진행합니다.
docker exec -it [그라파나 컨테이너 아이디] --user root bash
cd /usr/share/grafana/conf
vi defaults.ini
...
[server]
...
domain = 서버의공인아이피
...
(맨 마지막에 입력)
############## keycloakOAuth #######################
[auth.generic_oauth]
enabled = true
name = keycloakOAuth
allow_sign_up = true
client_id = grafana-client
client_secret = <Client에서 확인한 시크릿>
scopes = openid profile
auth_url = http://서버의공인아이피:8080/realms/Grafana/protocol/openid-connect/auth
token_url = http://서버의공인아이피:8080/realms/Grafana/protocol/openid-connect/token
api_url = http://서버의공인아이피:8080/realms/Grafana/protocol/openid-connect/userinfo
####################################################
그라파나 컨테이너를 빠져나온 후 재시작합니다.
docker restart [그라파나컨테이너아이디]
7. Grafana 접속 및 SSO 확인
그라파나웹에 접속하면 기존에 보이지 않던 "Sign in with keycloakOAuth"가 생긴 것을 확인할 수 있습니다.
해당 버튼을 클릭하고 keycloak에서 생성한 유저로 접속합니다.
SSO를 통해 그라파나에 접속한 것을 확인할 수 있습니다.