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