Home
home

Lab - AWS IAM - ConsoleMe 설치

1. ConsoleMe 란?

: ConsoleMe는 Netflix에서 개발한 오픈 소스 도구로 AWS IAM 권한 및 자격 증명 관리를 보다 쉽게 만들어주는 중앙 제어 플랫폼 입니다.
이를 통해 AWS의 복잡한 IAM 정책을 간소화하고 사용자와 클라우드 관리자가 효율적으로 권한을 관리할 수 있습니다.
ConsoleMe 주요 기능
ConsoleMe 장점
ConsoleMe 아키텍처
ConsoleMe를 활용해야 하는 이유
대규모 조직에서 IAM 정책과 리소스를 중앙에서 효율적으로 관리 가능
JSON 기반의 복잡한 IAM 정책 구성을 단순화
보안 강화와 함께 중앙 집중식으로 클라우드 리소스를 관리 가능

2. ConsoleMe 설치

ConsoleMe를 설치하는 방법은 Docker와 Local로 구분할 수 있습니다.
실습은 EC2 인스턴스(t3.large)를 생성해서 진행합니다. (Ubuntu 24.04 AMI 기준) ConsoleMe 설치 방법은 오픈소스 특성 상 방법이 변경될 수 있으니 필요에 따라 아래 링크를 참고합니다. - Docker : https://hawkins.gitbook.io/consoleme/quick-start/docker - Local : https://hawkins.gitbook.io/consoleme/quick-start/local-development

2.1. ConsoleMe Docker 설치

필수 패키지 설치
sudo apt update sudo apt install -y docker.io sudo systemctl start docker sudo systemctl enable docker
Bash
복사
# docker 설치
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose --version
Bash
복사
# docker compose 설치
========================================= OUTPUT: docker-compose version 1.29.2, build 5becea4c :END
Bash
복사
sudo apt install unzip -y curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip >/dev/null 2>&1 ./aws/install
Bash
복사
# awscli 설치
========================================= OUTPUT: You can now run: /usr/local/bin/aws --version :END
Bash
복사
aws configure
Bash
복사
# awscli 자격 증명
========================================= INPUT: AWS Access Key ID [None]: [YOUR_ACCESS_KEY_ID] AWS Secret Access Key [None]: [YOUR_SECRET_ACCESS_KEY] Default region name [None]: ap-northeast-2 Default output format [None]: :END
Bash
복사
ConsoleMe 설치
git clone https://github.com/Netflix/consoleme.git ; cd consoleme
Bash
복사
# GitHub에서 ConsoleMe 소스 클론
docker-compose -f docker-compose-dockerhub.yaml -f docker-compose-dependencies.yaml pull
Bash
복사
# Docker 최신 이미지 가져오기
========================================= OUTPUT: Pulling consoleme-dynamodb ... done Pulling consoleme-redis ... done Pulling consoleme ... done Pulling consoleme-celery ... done Pulling consoleme-dynamodb_admin ... done :END
Bash
복사
docker-compose -f docker-compose-dockerhub.yaml -f docker-compose-dependencies.yaml up -d
Bash
복사
# 컨테이너 실행
========================================= OUTPUT: Creating consoleme-redis ... done Creating consoleme-dynamodb-admin ... done Creating consoleme-dynamodb ... done Creating consoleme_consoleme_1 ... done Creating consoleme_consoleme-celery_1 ... done :END
Bash
복사
docker ps
Bash
복사
# 컨테이너 상태 확인
========================================= OUTPUT: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0420be5199cc consoleme/consoleme "bash -c ' python sc…" 27 seconds ago Up 26 seconds 8081/tcp consoleme_consoleme-celery_1 2ba320996361 consoleme/consoleme "bash -c ' python sc…" 27 seconds ago Up 26 seconds 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp, 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp consoleme_consoleme_1 263792f15419 aaronshaf/dynamodb-admin:latest "tini node dist/dyna…" 18 minutes ago Up 18 minutes 0.0.0.0:8001->8001/tcp, :::8001->8001/tcp consoleme-dynamodb-admin 67f125072830 redis:alpine "docker-entrypoint.s…" 18 minutes ago Up 18 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp consoleme-redis 66c9357de229 cnadiminti/dynamodb-local "java -jar DynamoDBL…" 18 minutes ago Up 18 minutes 8000/tcp, 0.0.0.0:8005->8005/tcp, :::8005->8005/tcp consoleme-dynamodb :END
Bash
복사
ConsoleMe 메인 컨테이너 포트: 3000
Celery 작업자 컨테이너 포트: 8081
ConsoleMe 최초 웹 접속
ConsoleMe 메인 컨테이너 접근으로 3000 포트로 접근한다. (보안 그룹 3000 포트 Open)
ConsoleMe 최초 화면
ConsoleMe 설정 파일 선택
ConsoleMe 작동을 위해 YAML 설정 파일을 선택하고 그에 따라 구성합니다.
ConsoleMe 설정 파일을 선택하는 우선 순위는 아래와 같으며 순차적으로 대상을 로드합니다.
1.
환경 변수 CONFIG_LOCATION에 지정된 경로
2.
현재 작업 디렉터리에 위치한 consoleme.yaml 파일
3.
~/.config/consoleme/config.yaml
4.
/etc/consoleme/config/config.yaml
5.
example_config/example_config_development.yaml
별도의 설정 파일을 생성하지 않은 경우 가장 마지막 우선 순위인 example_config/example_config_development.yaml에 따라 작동합니다. (현재 실습 환경)
example_config/example_config_development.yaml
⇒ 해당 설정은 Local Development 방식으로 별도의 Authentication 없이 접근 가능합니다.
Docker 컨테이너 삭제
docker-compose -f docker-compose-dockerhub.yaml -f docker-compose-dependencies.yaml down
Bash
복사
# 컨테이너 삭제
========================================= OUTPUT: Stopping consoleme_consoleme_1 ... done Stopping consoleme_consoleme-celery_1 ... done Stopping consoleme-dynamodb-admin ... done Stopping consoleme-dynamodb ... done Stopping consoleme-redis ... done Removing consoleme_consoleme_1 ... done Removing consoleme_consoleme-celery_1 ... done Removing consoleme-dynamodb-admin ... done Removing consoleme-dynamodb ... done Removing consoleme-redis ... done :END
Bash
복사
docker system prune -a --volumes -f
Bash
복사
# 리소스 정리
docker ps
Bash
복사
# 컨테이너 상태 확인
========================================= OUTPUT: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES :END
Bash
복사
다음 ConsoleMe Local 설치를 위해 Docker 컨테이너를 삭제합니다.

2.2. ConsoleMe Local 설치

필수 패키지 설치
sudo apt install -y software-properties-common sudo add-apt-repository ppa:deadsnakes/ppa sudo apt update sudo apt install -y python3.8 python3.8-venv python3.8-dev sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1 sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 2 sudo update-alternatives --config python3
Bash
복사
# python 3.8 설치
========================================= INPUT: Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/bin/python3.8 2 auto mode 1 /usr/bin/python3.12 1 manual mode 2 /usr/bin/python3.8 2 manual mode Press <enter> to keep the current choice[*], or type selection number: 0 :END
Bash
복사
sudo apt install build-essential libxml2-dev libxmlsec1 libxmlsec1-dev libxmlsec1-openssl libssl-dev libffi-dev musl-dev libcurl4-openssl-dev pkg-config npm tree unzip -y
Bash
복사
# 종속성 도구 설치
curl -sL https://deb.nodesource.com/setup_14.x | sudo bash sudo apt-get install -y nodejs sudo npm install yarn -g
Bash
복사
# Nodejs/Yarn 설치
Docker 컨테이너 설치 - Redis와 DynamoDB
cd ~/consoleme
Bash
복사
# GitHub에서 ConsoleMe 소스 디렉터리 진입
docker-compose -f docker-compose-dependencies.yaml up -d
Bash
복사
# Docker 컨테이너 설치 (redis, dynamodb)
========================================= OUTPUT: Creating consoleme-dynamodb ... done Creating consoleme-redis ... done Creating consoleme-dynamodb-admin ... done :END
Bash
복사
docker ps
Bash
복사
# Docker 컨테이너 확인
========================================= OUTPUT: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c770d0eb0ab6 aaronshaf/dynamodb-admin:latest "tini node dist/dyna…" 13 seconds ago Up 12 seconds 0.0.0.0:8001->8001/tcp, :::8001->8001/tcp consoleme-dynamodb-admin 1d4577c972ea cnadiminti/dynamodb-local "java -jar DynamoDBL…" 13 seconds ago Up 12 seconds 8000/tcp, 0.0.0.0:8005->8005/tcp, :::8005->8005/tcp consoleme-dynamodb b20a9ccac470 redis:alpine "docker-entrypoint.s…" 13 seconds ago Up 11 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp consoleme-redis :END
Bash
복사
가상 환경에서 ConsoleMe 설치 스크립트 실행
python3 -m venv env . env/bin/activate
Bash
복사
# Python 3.8 가상 환경 생성
========================================= OUTPUT: (env) ... :END
Bash
복사
make install
Bash
복사
# make install 실행
python consoleme/__main__.py
Bash
복사
# ConsoleMe 실행
ConsoleMe를 systemd 구성을 하여 백그라운드에서 동작하도록 합니다. 기존 ConsoleMe 실행을 중지(Ctrl + C)하고 아래 작업을 수행합니다.
ConsoleMe systemd 구성
vi /usr/bin/consoleme.sh
Bash
복사
# consoleme 실행 스크립트 파일 생성
========================================= INPUT: #!/bin/bash source /root/consoleme/env/bin/activate python /root/consoleme/consoleme/__main__.py :END
Bash
복사
chmod +x /usr/bin/consoleme.sh
Bash
복사
# consoleme 실행 스크립트 권한 할당
vi /etc/systemd/system/consoleme.service
Bash
복사
# consoleme.service 파일 생성
========================================= OUTPUT: [Unit] Description=Run consoleme service. [Service] Type=simple User=root WorkingDirectory=/root/consoleme ExecStart=/usr/bin/consoleme.sh [Install] WantedBy=multi-user.target :END
Bash
복사
systemctl enable consoleme systemctl start consoleme systemctl status consoleme
Bash
복사
# 서비스 활성화 및 시작
현재 consoleme를 git clone한 경로는 /root/consoleme 입니다. 다른 경로에 위치할 경우 적절하게 경로를 맞춰 주길 바랍니다.
Celery 실행
동적으로 IAM 설정의 변경 내용을 반영하기 원할 때 Celery가 작동되어야 합니다.
. env/bin/activate cd ~/consoleme
Bash
복사
# 가상 환경 진입
celery -A consoleme.celery_tasks.celery_tasks worker -l DEBUG -B -E --concurrency=8
Bash
복사
# celery 실행
Celery systemd 추가
vi /usr/bin/consoleme.sh
Bash
복사
# consoleme 실행 스크립트 파일 생성
========================================= INPUT: #!/bin/bash source /root/consoleme/env/bin/activate celery -A consoleme.celery_tasks.celery_tasks worker -l DEBUG -B -E --concurrency=8 & python /root/consoleme/consoleme/__main__.py :END
Bash
복사
systemctl restart consoleme systemctl status consoleme
Bash
복사
# 서비스 활성화 및 시작
========================================= OUTPUT: ● consoleme.service - Run consoleme service. Loaded: loaded (/etc/systemd/system/consoleme.service; enabled; preset: enabled) Active: active (running) since Sat 2024-11-23 17:04:49 UTC; 5s ago Main PID: 16850 (consoleme.sh) Tasks: 13 (limit: 9367) Memory: 630.5M (peak: 630.5M) CPU: 10.895s CGroup: /system.slice/consoleme.service ├─16850 /bin/bash /usr/bin/consoleme.sh ├─16851 /root/env/bin/python3 /root/env/bin/celery -A consoleme.celery_tasks.celery_tasks worker -l DEBUG -B -E --concur> ├─16852 python /root/consoleme/consoleme/__main__.py ├─16867 /root/env/bin/python3 /root/env/bin/celery -A consoleme.celery_tasks.celery_tasks worker -l DEBUG -B -E --concur> ├─16869 /root/env/bin/python3 /root/env/bin/celery -A consoleme.celery_tasks.celery_tasks worker -l DEBUG -B -E --concur> ├─16870 /root/env/bin/python3 /root/env/bin/celery -A consoleme.celery_tasks.celery_tasks worker -l DEBUG -B -E --concur> ├─16871 /root/env/bin/python3 /root/env/bin/celery -A consoleme.celery_tasks.celery_tasks worker -l DEBUG -B -E --concur> └─16874 /root/env/bin/python3 /root/env/bin/celery -A consoleme.celery_tasks.celery_tasks worker -l DEBUG -B -E --concur> :END
Bash
복사
ConsoleMe 최초 웹 접속
ConsoleMe 메인 웹 접근으로 8081 포트로 접근한다. (보안 그룹 8081 포트 Open)
현재 아무런 제약 없이 ConsoleMe에 접근하는 것은 보안 상으로 굉장히 취약한 상황입니다. 테스트 및 개발 환경에서 인증 없이 사용하는 것을 권장하며, 상용 환경에는 당연히 ConsoleMe 사용에 대한 인증 및 인가 작업이 필요하겠네요.

3. ALB Auth 구성 (Cognito 활용)

ConsoleMe의 Web App 인증과 인가는 다양한 방식을 지원합니다.
Local Development (Auth bypass) ← 앞서 설치한 환경
ALB Auth (Recommended) ← ConsoleMe 추천 방식
Retrieving Google Groups
OIDC/OAuth2
SAML
Plain-Text Header
ConsoleMe에서 권장하고 있는 ALB를 통한 인증 방식에 대해 구성해 보겠습니다.
ALB Auth 방식은 인증이 활성화된 ALB로 JWT 검증으로 인증된 사용자와 그룹을 검색할 수 있습니다.
ALB Auth 인증은 Cognito 또는 OIDC(google, okta …)에 대해 인증을 해야 합니다.
이번 실습은 Cognito를 통한 인증 방식을 활용합니다.
Amazon Cognito 사용자 풀 요금은 월별 활성 사용자(MAU)를 기준으로 부과됩니다. 월별 사용자(MAU)가 50,000명까지는 무료로 제공합니다. (기본 기능을 사용한다는 가정하에) 그 이상부터 차등되어 MAU당 요금이 발생합니다. 참고 링크 : https://aws.amazon.com/ko/cognito/pricing/

3.1. Cognito 구성

Cognito 구성은 AWS 관리 콘솔에서 수행할 수 있지만, UI 변경에서 “대격변”이 일어날 수 있어 awscli를 통해 작업을 수행합니다.
Cognito 사용자 풀 생성
aws cognito-idp create-user-pool \ --pool-name consoleme-test \ --username-attributes email \ --username-configuration CaseSensitive=false
Bash
복사
# cognito 사용자 풀 생성 (email 로그인)
========================================= OUTPUT: { "UserPool": { "Id": "ap-northeast-2_CQkKir7Mt", "Name": "consoleme-test", ... :END
Bash
복사
USER_POOL_ID=$(aws cognito-idp list-user-pools --max-results 50 \ --query 'UserPools[?Name==`consoleme-test`].Id' \ --output text) USER_POOL_ARN=$(aws cognito-idp describe-user-pool \ --user-pool-id $USER_POOL_ID \ --query "UserPool.Arn" \ --output text) echo "export USER_POOL_ID=$USER_POOL_ID" >> /etc/profile echo "export USER_POOL_ARN=$USER_POOL_ARN" >> /etc/profile echo $USER_POOL_ID echo $USER_POOL_ARN
Bash
복사
# USER_POOL_ID와 USER_POOL_ARN 전역 변수 선언
aws cognito-idp update-user-pool \ --user-pool-id $USER_POOL_ID \ --admin-create-user-config '{"AllowAdminCreateUserOnly": true}'
Bash
복사
# 셀프 서비스 가입 비활성화 (Default: 활성화)
aws cognito-idp create-user-pool-domain \ --user-pool-id $USER_POOL_ID \ --domain consoleme-test
Bash
복사
# Cognito 도메인 설정
========================================= OUTPUT: { "ManagedLoginVersion": 1 } :END
Bash
복사
COGNITO_DOMAIN=$(aws cognito-idp describe-user-pool-domain \ --domain consoleme-test \ --query "DomainDescription.Domain" \ --output text) echo "export COGNITO_DOMAIN=$COGNITO_DOMAIN" >> /etc/profile echo $COGNITO_DOMAIN
Bash
복사
# Congnito 도메인 접두어 변수 선언
Cognito 앱 클라이언트 생성
MyDomain=ongja2.click echo "export MyDomain=$MyDomain" >> /etc/profile echo $MyDomain
Bash
복사
# 도메인 이름 변수 선언 (각자 도메인)
aws cognito-idp create-user-pool-client \ --user-pool-id $USER_POOL_ID \ --client-name consoleme-app \ --generate-secret \ --allowed-o-auth-flows "code" \ --allowed-o-auth-scopes "openid" "phone" "email" "profile" \ --allowed-o-auth-flows-user-pool-client \ --callback-urls "https://${MyDomain}/auth" "https://${MyDomain}/oauth2/idpresponse" \ --explicit-auth-flows "ALLOW_REFRESH_TOKEN_AUTH" "ALLOW_CUSTOM_AUTH" "ALLOW_USER_SRP_AUTH" "ALLOW_USER_PASSWORD_AUTH" \ --supported-identity-providers "COGNITO"
Bash
복사
# 앱 클라이언트 생성
========================================= OUTPUT: { "UserPoolClient": { "UserPoolId": "ap-northeast-2_CQkKir7Mt", "ClientName": "consoleme-app", ... :END
Bash
복사
CLIENT_ID=$(aws cognito-idp list-user-pool-clients \ --user-pool-id $USER_POOL_ID \ --query "UserPoolClients[?ClientName=='consoleme-app'].ClientId | [0]" \ --output text) CLIENT_SECRET=$(aws cognito-idp describe-user-pool-client \ --user-pool-id $USER_POOL_ID \ --client-id $CLIENT_ID \ --query "UserPoolClient.ClientSecret" \ --output text) echo "export CLIENT_ID=$CLIENT_ID" >> /etc/profile echo "export CLIENT_SECRET=$CLIENT_SECRET" >> /etc/profile echo $CLIENT_ID echo $CLIENT_SECRET
Bash
복사
# CLIENT_ID와 CLIENT_SECRET 전역 변수 선언
Cognito 구성 확인 (AWS 관리 콘솔)

3.2. ALB 구성

ALB 구성도 마찬가지로 awscli를 통해 작업을 수행합니다.
대상 그룹 생성 및 대상 등록
VPC_ID=$(aws ec2 describe-vpcs \ --filters "Name=tag:Name,Values=service" \ --query "Vpcs[0].VpcId" \ --output text) INSTANCE_ID=$(aws ec2 describe-instances \ --filters "Name=tag:Name,Values=ConsoleMe" \ --query "Reservations[0].Instances[0].InstanceId" \ --output text) echo "export VPC_ID=$VPC_ID" >> /etc/profile echo "export INSTANCE_ID=$INSTANCE_ID" >> /etc/profile echo $VPC_ID echo $INSTANCE_ID
Bash
복사
# VPC ID와 Instance ID 변수 선언
aws elbv2 create-target-group \ --name consoleme-tg \ --protocol HTTP \ --port 8081 \ --vpc-id $VPC_ID \ --target-type instance \ --health-check-protocol HTTP \ --health-check-path /healthcheck
Bash
복사
# 대상 그룹 생성
========================================= OUTPUT: { "TargetGroups": [ { "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:targetgroup/consoleme-tg/2d87415cc7501e4a", "TargetGroupName": "consoleme-tg", "Protocol": "HTTP", "Port": 8081, "VpcId": "vpc-02a32c94e0ac6b2d0", "HealthCheckProtocol": "HTTP", ... :END
Bash
복사
TG_ARN=$(aws elbv2 describe-target-groups \ --names consoleme-tg \ --query "TargetGroups[0].TargetGroupArn" \ --output text) echo "export TG_ARN=$TG_ARN" >> /etc/profile echo $TG_ARN
Bash
복사
# 대상 그룹 변수 선언
aws elbv2 register-targets \ --target-group-arn $(aws elbv2 describe-target-groups \ --names consoleme-tg \ --query "TargetGroups[0].TargetGroupArn" \ --output text) \ --targets Id=$INSTANCE_ID
Bash
복사
# 대상 그룹에 ConsoleMe 인스턴스 추가
각자의 VPC와 인스턴스의 Label 정보를 확인해서 ID 값을 추출합니다.
ALB 생성
SUBNET1_ID=$(aws ec2 describe-subnets \ --filters "Name=tag:Name,Values=service-public-01" \ --query "Subnets[0].SubnetId" \ --output text) SUBNET2_ID=$(aws ec2 describe-subnets \ --filters "Name=tag:Name,Values=service-public-02" \ --query "Subnets[0].SubnetId" \ --output text) echo "export SUBNET1_ID=$SUBNET1_ID" >> /etc/profile echo "export SUBNET2_ID=$SUBNET2_ID" >> /etc/profile echo $SUBNET1_ID echo $SUBNET2_ID
Bash
복사
# 서브넷 ID 변수 선언
SECURITY_GROUP_ID=$(aws ec2 create-security-group \ --group-name cm-alb-sg \ --description "Security group for ConsoleMe ALB" \ --vpc-id $VPC_ID \ --query "GroupId" \ --output text) aws ec2 authorize-security-group-ingress \ --group-id $SECURITY_GROUP_ID \ --protocol tcp \ --port 80 \ --cidr 0.0.0.0/0 aws ec2 authorize-security-group-ingress \ --group-id $SECURITY_GROUP_ID \ --protocol tcp \ --port 443 \ --cidr 0.0.0.0/0 echo "export SECURITY_GROUP_ID=$SECURITY_GROUP_ID" >> /etc/profile echo $SECURITY_GROUP_ID
Bash
복사
# 보안 그룹 생성 및 변수 선언
aws elbv2 create-load-balancer \ --name consoleme-alb \ --subnets $SUBNET1_ID $SUBNET2_ID \ --security-groups $SECURITY_GROUP_ID \ --type application
Bash
복사
# ALB 생성
========================================= OUTPUT: { "LoadBalancers": [ { "LoadBalancerArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:loadbalancer/app/consoleme-alb/1e7482529f166289", "DNSName": "consoleme-alb-126552146.ap-northeast-2.elb.amazonaws.com", "CanonicalHostedZoneId": "ZWKZPGTI48KDX", "CreatedTime": "2024-11-24T11:05:34.341000+00:00", "LoadBalancerName": "consoleme-alb", "Scheme": "internet-facing", "VpcId": "vpc-02a32c94e0ac6b2d0", ... :END
Bash
복사
ALB_ARN=$(aws elbv2 describe-load-balancers \ --names consoleme-alb \ --query "LoadBalancers[0].LoadBalancerArn" \ --output text) echo "export ALB_ARN=$ALB_ARN" >> /etc/profile echo $ALB_ARN
Bash
복사
# ALB ARN 변수 선언
각자의 서브넷의 Label 정보를 확인해서 ID 값을 추출합니다.
ALB 리스너 생성 및 설정
ACM_ARN=$(aws acm list-certificates \ --query "CertificateSummaryList[?DomainName=='${MyDomain}'].CertificateArn | [0]" \ --output text) echo "export ACM_ARN=$ACM_ARN" >> /etc/profile echo $ACM_ARN
Bash
복사
# ACM 인증서 ARN 변수 선언
aws elbv2 create-listener \ --load-balancer-arn $ALB_ARN \ --protocol HTTP \ --port 80 \ --default-actions '[{"Type": "redirect", "RedirectConfig": {"Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}]'
Bash
복사
# HTTP 80 리스너 생성
========================================= OUTPUT: { "Listeners": [ { "ListenerArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:listener/app/consoleme-alb/1e7482529f166289/a4690d1d210d8bc3", "LoadBalancerArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:loadbalancer/app/consoleme-alb/1e7482529f166289", "Port": 80, "Protocol": "HTTP", "DefaultActions": [ { "Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", ... :END
Bash
복사
echo $USER_POOL_ARN; echo $CLIENT_ID; echo $ACM_ARN; echo $TG_ARN
Bash
복사
# 변수 확인 (Cognito 사용자 풀 ID, Cognito 앱 클라이언트 ID, ACM 인증서 ARN, 대상 그룹 ARN
aws elbv2 create-listener \ --load-balancer-arn $ALB_ARN \ --protocol HTTPS \ --port 443 \ --certificates CertificateArn=$ACM_ARN \ --default-actions '[{"Type": "authenticate-cognito", "Order": 1, "AuthenticateCognitoConfig": {"UserPoolArn": "'$USER_POOL_ARN'", "UserPoolClientId": "'$CLIENT_ID'", "UserPoolDomain": "consoleme-test"}}, {"Type": "forward", "Order": 2, "TargetGroupArn": "'$TG_ARN'"}]'
Bash
복사
# HTTPS 443 리스너 생성
========================================= OUTPUT: { "Listeners": [ { "ListenerArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:listener/app/consoleme-alb/1e7482529f166289/a40fb85f6d4a4eee", "LoadBalancerArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:loadbalancer/app/consoleme-alb/1e7482529f166289", "Port": 443, "Protocol": "HTTPS", "Certificates": [ { "CertificateArn": "arn:aws:acm:ap-northeast-2:891377396078:certificate/fb494b49-797d-4880-aeb7-e57c29d7e6ac" } ], "SslPolicy": "ELBSecurityPolicy-2016-08", "DefaultActions": [ { "Type": "authenticate-cognito", "AuthenticateCognitoConfig": { "UserPoolArn": "arn:aws:cognito-idp:ap-northeast-2:891377396078:userpool/ap-northeast-2_CQkKir7Mt", "UserPoolClientId": "1v5he3bsjprf0fcfj3gpb8a0ar", "UserPoolDomain": "consoleme-test", "SessionCookieName": "AWSELBAuthSessionCookie", "Scope": "openid", "SessionTimeout": 604800, "OnUnauthenticatedRequest": "authenticate" }, "Order": 1 }, { "Type": "forward", "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:targetgroup/consoleme-tg/2d87415cc7501e4a", "Order": 2, "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:targetgroup/consoleme-tg/2d87415cc7501e4a", "Weight": 1 ... :END
Bash
복사
LISTENER_ARN=$(aws elbv2 describe-listeners \ --load-balancer-arn $ALB_ARN \ --query "Listeners[?Port==\`443\`].ListenerArn" \ --output text) echo "export LISTENER_ARN=$LISTENER_ARN" >> /etc/profile echo $LISTENER_ARN
Bash
복사
# HTTPS 443 리스너 ARN 변수 선언
aws elbv2 create-rule \ --listener-arn $LISTENER_ARN \ --priority 1 \ --conditions '[{"Field": "path-pattern", "PathPatternConfig": {"Values": ["/noauth/v1/challenge_poller/*", "/noauth/v1/challenge_generator/*", "/api/v1/get_roles*", "/api/v2/mtls/roles/*", "/api/v1/get_credentials*"]}}]' \ --actions '[{"Type": "forward", "ForwardConfig": {"TargetGroups": [{"TargetGroupArn": "'$TG_ARN'", "Weight": 1}]}}]'
Bash
복사
# HTTPS 443 리스너의 규칙에 조건 추가(1)
========================================= OUTPUT: { "Rules": [ { "RuleArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:listener-rule/app/consoleme-alb/1e7482529f166289/a40fb85f6d4a4eee/8d5bf02091cf5574", "Priority": "1", "Conditions": [ { "Field": "path-pattern", "Values": [ "/noauth/v1/challenge_poller/*", "/noauth/v1/challenge_generator/*", "/api/v1/get_roles*", "/api/v2/mtls/roles/*", "/api/v1/get_credentials*" ], "PathPatternConfig": { "Values": [ "/noauth/v1/challenge_poller/*", "/noauth/v1/challenge_generator/*", "/api/v1/get_roles*", "/api/v2/mtls/roles/*", "/api/v1/get_credentials*" ] } } ], "Actions": [ { "Type": "forward", "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:targetgroup/consoleme-tg/2d87415cc7501e4a", ... :END
Bash
복사
aws elbv2 create-rule \ --listener-arn $LISTENER_ARN \ --priority 2 \ --conditions '[{"Field": "path-pattern", "PathPatternConfig": {"Values": ["/api/v1/myheaders/?", "/api/v2/get_resource_url*"]}}]' \ --actions '[{"Type": "forward", "ForwardConfig": {"TargetGroups": [{"TargetGroupArn": "'$TG_ARN'", "Weight": 1}]}}]'
Bash
복사
# HTTPS 443 리스너의 규칙에 조건 추가(2)
========================================= OUTPUT: { "Rules": [ { "RuleArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:listener-rule/app/consoleme-alb/1e7482529f166289/a40fb85f6d4a4eee/6e19291639a3a908", "Priority": "2", "Conditions": [ { "Field": "path-pattern", "Values": [ "/api/v1/myheaders/?", "/api/v2/get_resource_url*" ], "PathPatternConfig": { "Values": [ "/api/v1/myheaders/?", "/api/v2/get_resource_url*" ] } } ], "Actions": [ { "Type": "forward", "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:targetgroup/consoleme-tg/2d87415cc7501e4a", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-2:891377396078:targetgroup/consoleme-tg/2d87415cc7501e4a", ... :END
Bash
복사
ALB 리스너 - HTTP 80
기본 규칙: HTTPS 443으로 리다이렉션
ALB 리스너 - HTTPS 443
기본 규칙: Amazon Cognito 연결, 대상 그룹 전달
신규 규칙 추가
조건1) 경로에 대한 대상 그룹 전달
/noauth/v1/challenge_poller/*
/noauth/v1/challenge_generator/*
/api/v1/get_roles*
/api/v2/mtls/roles/*
/api/v1/get_credentials*
조건2) 경로에 대한 대상 그룹 전달
/api/v1/myheaders/?
/api/v2/get_resource_url*
각자의 도메인에 대한 ACM 인증서 등록이 된 상태에서 ARN 값을 추출합니다.
ALB 구성 확인 (AWS 관리 콘솔)
Route 53 레코드에 ALB Alias 연결
HOSTED_ZONE_ID=$(aws route53 list-hosted-zones-by-name \ --dns-name "${MyDomain}." \ --query "HostedZones[0].Id" \ --output text | cut -d'/' -f3) echo "export HOSTED_ZONE_ID=$HOSTED_ZONE_ID" >> /etc/profile echo $HOSTED_ZONE_ID
Bash
복사
# 도메인의 Hosted Zone ID 변수 선언
ALB_DNS_NAME=$(aws elbv2 describe-load-balancers \ --load-balancer-arns $ALB_ARN \ --query "LoadBalancers[0].DNSName" \ --output text) echo "export ALB_DNS_NAME=$ALB_DNS_NAME" >> /etc/profile echo $ALB_DNS_NAME
Bash
복사
# ALB 도메인 주소 변수 선언
ALB_HOSTED_ZONE_ID=$(aws elbv2 describe-load-balancers \ --load-balancer-arns $ALB_ARN \ --query "LoadBalancers[0].CanonicalHostedZoneId" \ --output text) echo "export ALB_HOSTED_ZONE_ID=$ALB_HOSTED_ZONE_ID" >> /etc/profile echo $ALB_HOSTED_ZONE_ID
Bash
복사
# ALB의 CanonicalHostedZoneId를 변수 선언
aws route53 change-resource-record-sets \ --hosted-zone-id $HOSTED_ZONE_ID \ --change-batch '{ "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "'"${MyDomain}"'", "Type": "A", "AliasTarget": { "HostedZoneId": "'"${ALB_HOSTED_ZONE_ID}"'", "DNSName": "'"${ALB_DNS_NAME}"'", "EvaluateTargetHealth": false } } } ] }'
Bash
복사
# Route 53 도메인의 A 레코드에 ALB 연결
========================================= OUTPUT: { "ChangeInfo": { "Id": "/change/C0443949LCR1KLHBTBKW", "Status": "PENDING", "SubmittedAt": "2024-11-24T15:53:56.444000+00:00" } } :END
Bash
복사
각자의 도메인에 대한 Hosted Zone ID와 ALB 도메인 이름과 Hosted Zone ID를 변수로 선언합니다.

3.3. ConsoleMe 설정 업데이트

ConsoleMe 설정 파일 선택
ConsoleMe 설정 파일을 선택하는 우선 순위는 아래와 같으며 순차적으로 대상을 로드합니다.
1.
환경 변수 CONFIG_LOCATION에 지정된 경로
2.
현재 작업 디렉터리에 위치한 consoleme.yaml 파일
3.
~/.config/consoleme/config.yaml
4.
/etc/consoleme/config/config.yaml
5.
example_config/example_config_development.yaml
이번 실습에는 3번째 우선 순위의 경로인 ~/.config/consoleme/config.yaml에 구성하겠습니다.
ALB Auth를 위한 설정 파일
ALB Auth 설정 파일은 3개를 구성하고 사용합니다.
consoleme_config.yaml
consoleme_config_base.yaml
consoleme_secret.yaml
mkdir -p ~/.config/consoleme/
Bash
복사
# 디렉터리 생성
cat > ~/.config/consoleme/config.yaml << EOF application_admin: ${ADMIN_MAIL} auth: get_user_by_aws_alb_auth: true set_auth_cookie: true logout_redirect_url: "https://${COGNITO_DOMAIN}.auth.ap-northeast-2.amazoncognito.com/logout?response_type=code&client_id=${CLIENT_ID}&logout_uri=https://${MyDomain}" extra_auth_cookies: - AWSELBAuthSessionCookie-0 - AWSELBAuthSessionCookie-1 get_user_by_aws_alb_auth_settings: access_token_validation: metadata_url: https://cognito-idp.ap-northeast-2.amazonaws.com/${USER_POOL_ID}/.well-known/openid-configuration jwt_email_key: email jwt_groups_key: "cognito:groups" development: true url: http://127.0.0.1:8081 tornado: debug: false port: 8081 xsrf: true xsrf_cookie_kwargs: samesite: strict cloud_credential_authorization_mapping: role_tags: enabled: true authorized_groups_tags: - consoleme-authorized authorized_groups_cli_only_tags: - consoleme-owner-dl - consoleme-authorized-cli-only aws: issuer: CloudNet@ region: "ap-northeast-2" celery: active_region: ap-northeast-2 cli_auth: certificate_header: certificate_header required_headers: - RequiredMTLSHeader: RequiredMTLSHeaderValue groups: can_edit_config: - ${ADMIN_MAIL} can_admin_policies: - ${ADMIN_MAIL} jwt: email_key: email support_contact: ${ADMIN_MAIL} support_chat_url: https://www.example.com/slack/channel documentation_page: https://github.com/Netflix/consoleme/ logging_levels: asyncio: WARNING boto3: CRITICAL boto: CRITICAL botocore: CRITICAL elasticsearch.trace: ERROR elasticsearch: ERROR nose: CRITICAL parso.python.diff: WARNING s3transfer: CRITICAL spectator.HttpClient: WARNING spectator.Registry: WARNING urllib3: ERROR ses: support_reference: "Please contact us at ${ADMIN_MAIL} if you have any questions or concerns." arn: "arn:aws:ses:ap-northeast-2:${ACCOUNT_ID}:identity/no-reply@verificationemail.com" region: "ap-northeast-2" consoleme: name: ConsoleMe sender: no-reply@verificationemail.com challenge_url: enabled: true EOF
Bash
복사
# config.yaml 파일 생성
ConsoleMe Service 재시작
tree ~/.config/consoleme/
Bash
복사
# 생성된 설정 파일 확인
========================================= OUTPUT: /root/.config/consoleme/ ├── consoleme_config.yaml ├── consoleme_config_base.yaml └── consoleme_config_header_auth.yaml 1 directory, 3 files :END
Bash
복사
systemctl restart consoleme systemctl status consoleme
Bash
복사
# consoleme service 재시작
각자 도메인 주소로 접속
Cognito 도메인 주소로 리다이렉트 되며 로그인 페이지로 접근됩니다.
앞서 인증 없는 접근이 아닌 Coginto 로그인 페이지를 통해 인가된 대상만 접근이 가능합니다.
여기까지 ConsoleMe 설치에 대한 실습을 진행했습니다.
아래 페이지에서 이어서 ConsoleMe 테스트를 진행해 보겠습니다.