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 테스트를 진행해 보겠습니다.