1. 기본 환경 구성
이번 실습은 IAM 사용자 계정을 통해 관리 콘솔에 접근하고 액세스 키를 활용해 awscli 도구를 사용합니다.
해당 작업을 수행하지 않았다면 아래 토글을 확장해 작업을 선행하고 본격적인 실습에 들어갑니다.
IAM 사용자 생성 및 액세스 키 생성
1.1. Terraform을 통한 기본 인프라 배포
Terraform을 통한 기본 인프라 배포에 앞서 SSH 키 페어, IAM User Access Key ID, IAM User Secret Access Key를 미리 확인하고 메모해 둡니다.
Terraform으로 기본 인프라 배포
cd cnasg_class_tf/Section14
Bash
복사
# 실습 코드 경로 진입
export TF_VAR_KeyName=[각자 ssh keypair]
export TF_VAR_NickName=[각자 닉네임]
export TF_VAR_MyIamUserAccessKeyID=[각자 iam 사용자의 access key id]
export TF_VAR_MyIamUserSecretAccessKey=[각자 iam 사용자의 secret access key]
export TF_VAR_SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32
Bash
복사
# Terraform 환경 변수 저장
terraform init
terraform plan
Bash
복사
# Terraform 배포
nohup sh -c "terraform apply -auto-approve" > create.log 2>&1 &
Bash
복사
Note:
Terraform 배포가 완료되면(약 5분 정도 대기) 정상적으로 자원 생성이 되었는지 확인을 합니다.(cat create.log)
실수로 Terraform 환경 변수를 설정하지 않은 상태에서 nohup으로 실행하면, terraform 에러가 발생해도 프로세스가 종료되지 않고 계속 점유될 수 있습니다.
이 경우 terraform 프로세스를 강제로 종료한 뒤, 환경 변수를 설정하고 다시 실행해야 합니다.
ps aux | grep -i terraform
kill -9 <terraform_PID>
Bash
복사
# terraform 프로세스 강제 종료
1.2. 기본 정보 확인
Terraform 배포가 완료 후 출력되는 Outputs 정보에서 lab_admin_ip의 퍼블릭 IP를 확인합니다.
대상 IP로 인스턴스에 SSH로 접속하고 아래 명령어를 통해 정보를 확인합니다.
LAB-ADMIN
기본 정보 확인
echo ${AWS_DEFAULT_REGION}
echo ${ACCOUNT_ID}
Bash
복사
# 변수 확인
aws sts get-caller-identity
Bash
복사
# caller id 확인
Note:
인스턴스가 생성되고 너무 빠르게 접속하면 aws 자격 증명이 완료되지 않을 수 있습니다.
그럴 경우에는 약간의 대기 후 다시 접속해 주세요.
FRONT-01과 BACK-01 접속
ssh root@192.168.11.100
Bash
복사
# [신규 터미널] LAB-ADMIN → FRONT-01 접속 (암호: cnasg1234!)
ssh root@192.168.12.100
Bash
복사
# [신규 터미널] LAB-ADMIN → BACK-01 접속 (암호: cnasg1234!)
FRONT-01
Kubernetes 정보 확인
kubectl get node -o wide
Bash
복사
# 노드 확인 (Control/Data Plane 구분)
kubectl get pod -o wide
Bash
복사
# 파드 확인 (도서관 포털 배포 확인)
kubectl get svc library-portal-svc
Bash
복사
# 서비스 확인 (NodePort로 30080이 열림)
BACK-01
Kubernetes 정보 확인
kubectl get node -o wide
Bash
복사
# 노드 확인 (Control/Data Plane 구분)
kubectl get pod -o wide
Bash
복사
# 파드 확인 (도서관 DB 배포 확인)
kubectl get svc library-db-svc
Bash
복사
# 서비스 확인 (NodePort로 30036이 열림)
kubectl exec -it deploy/library-db \
-- mysql -u libuser -plibpass1234 librarydb -e "SELECT * FROM books;"
Bash
복사
# DB 데이터 확인
LAB-ADMIN
웹 애플리케이션 확인
lynx -dump -width=200 http://192.168.11.100:30080
Bash
복사
# 웹 애플리케이션 파드로 접근 확인
LAB-ADMIN에서 FRONT-01의 30080 포트(NodePort)로 접근하면, Frontend 클러스터 내부의 도서관 포털 파드로 연결됩니다.
이 포털은 다시 Backend 클러스터의 30036 포트(MariaDB NodePort)로 접속해 도서 데이터를 가져오는 구조입니다.
2. Teleport 설치 및 초기 구성
이번 실습을 위해 Teleport를 설치하고, 초기 환경을 구성합니다.
2.1. Teleport Auth/Proxy 설치
LAB-ADMIN에 Teleport Auth와 Teleport Proxy를 설치합니다.
LAB-ADMIN
도메인 주소 구성 (nip.io)
PUBLIC_IP=$(curl -s ipinfo.io/ip)
echo $PUBLIC_IP
Bash
복사
# 퍼블릭 IP 확인 (nip.io 도메인 조립용)
DOMAIN="teleport-$(echo $PUBLIC_IP | tr '.' '-').nip.io"
echo $DOMAIN
Bash
복사
# nip.io 도메인 조립 (IP의 점을 하이픈으로 치환)
Teleport 클러스터 설치
curl https://cdn.teleport.dev/install.sh | bash -s 18.9.2 oss
Bash
복사
#Teleport 18.9.2 설치
teleport version
Bash
복사
# 설치 버전 확인
teleport configure \
--acme \
--acme-email=admin@${DOMAIN} \
--cluster-name=${DOMAIN} \
-o file
Bash
복사
# Teleport 설정 파일 생성 (ACME로 nip.io 도메인에 무료 인증서 자동 발급)
systemctl enable teleport
systemctl start teleport
Bash
복사
# Teleport 서비스 시작
systemctl status teleport
Bash
복사
nip.io는 별도 DNS 등록 없이 <IP>.nip.io 형태의 문자열을 그 IP로 자동 매칭해주는 무료 서비스입니다.
ACME(Let's Encrypt)가 이 도메인에 무료 SSL 인증서를 자동 발급하기 때문에, 실제 도메인 구매 없이도 HTTPS로 안전하게 Teleport에 접속할 수 있습니다.
2.2. 관리자 계정 구성 및 설치 검증
LAB-ADMIN
[TCTL] Teleport Roles 확인
tctl get roles --format=text
Bash
복사
# 기본적으로 존재하는 Teleport Roles
tctl get role/access | yq
Bash
복사
# [기본값] access Role 확인
tctl get role/editor | yq
Bash
복사
# [기본값] editor Role 확인
[TCTL] 관리자 계정(tele-admin) 생성
tctl users add tele-admin --roles=access,editor --logins=root
Bash
복사
# 관리자 계정 생성 (editor + access 역할 - 전체 권한)
명령을 실행하면 초대 링크(URL)가 출력됩니다.
이 링크를 브라우저로 열어 비밀번호(12자리 이상)와 OTP(2단계 인증)를 설정하면 계정 생성이 완료됩니다.
Teleport 클러스터로 접근해서 웹 페이지 구성을 확인합니다.
tctl status
Bash
복사
# Teleport 클러스터 상태 확인
2.3. 노드에 Teleport 설치 및 등록
LAB-ADMIN
[TCTL] 노드용 토큰 생성
tctl nodes add --roles=node --ttl=1h
Bash
복사
# 노드 등록을 위한 토큰 생성
출력되는 토큰 값을 메모해 두고, 아래 실습에서 활용합니다.
FRONT-01
FRONT-01 수동 설치 (최초 1대, 직접 시연)
curl https://cdn.teleport.dev/install.sh | bash -s 18.9.2 oss
Bash
복사
# Teleport 18.9.2 버전 설치
TOKEN=<<발급받은 토큰 입력>>
Bash
복사
# 노드 설정 생성 (Auth 서버 주소, labels 지정)
teleport node configure \
--token=${TOKEN} \
--auth-server=192.168.1.100:3025 \
--labels=env=frontend \
-o file
Bash
복사
systemctl enable --now teleport
systemctl status teleport
Bash
복사
# Teleport 활성화 및 상태 확인
LAB-ADMIN
[TCTL] 등록된 노드 확인
tctl get node --format text
Bash
복사
# 등록된 SSH 노드 확인
나머지 자동 설치 (나머지 3대 - 스크립트)
NODE_TOKEN=$(tctl nodes add --roles=node --ttl=1h 2>&1 | grep -oP '(?<=--token=)[a-f0-9]+' | head -1)
echo $NODE_TOKEN
Bash
복사
# 노드용 토큰 재발급 (나머지 3대용)
cat << SH > node-install.sh
#!/bin/bash
NODE_TOKEN="${NODE_TOKEN}"
AUTH_SERVER="192.168.1.100:3025"
NODE_PASSWORD="cnasg1234!"
declare -A NODES
NODES["192.168.11.101"]="front-02:env=frontend"
NODES["192.168.12.100"]="back-01:env=backend"
NODES["192.168.12.101"]="back-02:env=backend"
for IP in "\${!NODES[@]}"; do
NODENAME=\$(echo "\${NODES[\$IP]}" | cut -d: -f1)
LABEL=\$(echo "\${NODES[\$IP]}" | cut -d: -f2)
echo "=== \${NODENAME} (\${IP}) 설치 시작 ==="
sshpass -p "\${NODE_PASSWORD}" ssh -o StrictHostKeyChecking=no root@\${IP} bash -s << EOF
curl https://cdn.teleport.dev/install.sh | bash -s 18.9.2 oss
teleport node configure \\
--token=\${NODE_TOKEN} \\
--auth-server=\${AUTH_SERVER} \\
--labels=\${LABEL} \\
-o file
systemctl enable --now teleport
systemctl status teleport --no-pager
EOF
echo "=== \${NODENAME} 설치 완료 ==="
done
SH
Bash
복사
# node-install.sh 생성
chmod +x node-install.sh
./node-install.sh
Bash
복사
# 노드 등록 스크립트 실행
[TCTL] 등록된 노드 확인
tctl get node --format text
Bash
복사
# 등록된 SSH 노드 확인
https://{DOMAIN}에 접근해서 Teleport 클러스터에 등록된 SSH 노드를 확인하고 접근해 봅니다.
노드 보안 그룹에 SSH 포트 제거(TCP 22)
NODE_SG_ID=$(aws ec2 describe-security-groups \
--filters "Name=group-name,Values=cnasg-node-sec-group" \
--query "SecurityGroups[0].GroupId" \
--output text)
echo $NODE_SG_ID
Bash
복사
# 그룹 ID를 변수로 먼저 선언
aws ec2 revoke-security-group-ingress \
--group-id $NODE_SG_ID \
--protocol tcp \
--port 22 \
--cidr 192.168.0.0/16
Bash
복사
# 변수를 참조해서 22번 인바운드 규칙 삭제
aws ec2 describe-security-groups \
--group-ids $NODE_SG_ID \
--query "SecurityGroups[0].IpPermissions"
Bash
복사
# 보안 그룹에 규칙 삭제 확인
각 노드에 SSH로 접근한 것을 빠져나온 후, 다시 접속을 시도합니다.
ssh -o ConnectTimeout=5 root@192.168.11.100
Bash
복사
3. Teleport 기반 접근 통제
Teleport를 통해 다양한 리소스에 접근 통제를 구성합니다.
3.1. Teleport SSH 접근 통제
Teleport SSH 노드를 구성하고 다양한 접근 통제 기능을 확인합니다.
3.1.1. TSH 설치
OS 별로 TSH 설치 방법은 공식 문서를 통해 확인할 수 있습니다.
https://goteleport.com/docs/connect-your-client/teleport-clients/tsh/
사용자 PC - MAC OS
[TSH] 설치
curl -O https://cdn.teleport.dev/teleport-18.9.2.pkg
Bash
복사
# Teleport 패키지 다운로드
sudo installer -pkg teleport-18.9.2.pkg -target /
rm teleport-18.9.2.pkg
Bash
복사
# Teleport 패키지 설치
tsh version
Bash
복사
# tsh 버전 확인
사용자 PC - WSL2 Ubuntu OS
[TSH] 설치
curl https://cdn.teleport.dev/install.sh | bash -s 18.9.2 oss
Bash
복사
# Teleport 설치 스크립트 실행
tsh version
Bash
복사
# tsh 버전 확인
3.1.2. TSH로 Teleport 접근
사용자 PC - 공통
[TSH] 클러스터 접근 (tele-admin)
DOMAIN=<<Teleport Proxy 도메인 주소>>
Bash
복사
# tsh login (tele-admin)
tsh login --proxy=$DOMAIN:443 --user=tele-admin
Bash
복사
tsh status
Bash
복사
# tsh 상태 확인
tsh ls
Bash
복사
# tsh로 등록된 SSH 노드 확인
[TSH] SSH 노드 접근 (tele-admin)
tsh ssh root@FRONT-01
Bash
복사
# tsh로 SSH 노드에 접근
tsh ssh root@FRONT-02
Bash
복사
tsh ssh root@BACK-01
Bash
복사
tsh ssh root@BACK-02
Bash
복사
각 노드에 접속해서 간단한 명령을 입력한 후 빠져 나옵니다.
3.1.3. Audit Log, Session Recording, Active Sessions 확인
Teleport Web UI
웹에서 Audit Log 확인
•
Web UI → Audit → Audit Log → 이벤트(로그인, SSH 세션 시작/종료 등) 확인
웹에서 Session Recording 확인
•
Web UI → Audit → Session Recordings → SSH 세션 재생
LAB-ADMIN
CLI로 Audit Log 확인
ls /var/lib/teleport/log/
Bash
복사
# Teleport의 로그 경로 확인
cd /var/lib/teleport/log/<UUID>
Bash
복사
# 로그 파일 확인
ls
Bash
복사
cat *.log | tail -20 | jq
Bash
복사
cat *.log | jq -r '.event' | sort -u
Bash
복사
# event 필드만 추출
cat *.log | jq -c 'select(.event == "user.login")'
Bash
복사
# user.login만 필터링
cat *.log | jq -c \
'select(.event == "user.login") | {time, user, success, method}'
Bash
복사
# user.login 주요 내용만 필터링
cat *.log | jq -c \
'select(.event == "session.start" or .event == "session.end") | {time, event, user, login, server_hostname}'
Bash
복사
# session.start & end 주요 내용만 필터링
사용자 PC - 공통
[TSH] Session Recording 확인
tsh recordings ls
Bash
복사
# Session Recording 리스트 확인
tsh play <<Session Recording ID>>
Bash
복사
# Session Recording 플레이
Teleport Web UI
웹에서 Active Sessions 확인
tsh ssh로 노드 한 대에 접근한 상태에서 진행합니다.
•
Web UI → Audit → Active Sessions → 세션 확인 → Join → Observer / Peer
사용자 PC - 공통
[TSH] Active Sessions 확인
tsh sessions ls
Bash
복사
# Active Sessions 리스트 확인
tsh join <<Active Sessions ID>> --mode=observer
Bash
복사
# Active Session에 참여하기
tsh join <<Active Sessions ID>> --mode=peer
Bash
복사
Active Sessions 접근에서 빠져나올 때 CTRL+C를 누릅니다.
3.1.4. RBAC 확인
LAB-ADMIN
Frontend와 Backend Role 생성
cat << EOF > frontend-node-role.yaml
kind: role
version: v7
metadata:
name: frontend-node-role
spec:
allow:
logins: ['root']
node_labels:
'env': 'frontend'
EOF
Bash
복사
# frontend-node-role.yaml
cat << EOF > backend-node-role.yaml
kind: role
version: v7
metadata:
name: backend-node-role
spec:
allow:
logins: ['root']
node_labels:
'env': 'backend'
EOF
Bash
복사
# backend-node-role.yaml
tctl create -f frontend-node-role.yaml
tctl create -f backend-node-role.yaml
Bash
복사
# tctl로 role 생성
Teleport 사용자 생성 (frontend-user & backend-user)
tctl users add frontend-user --roles=frontend-node-role --logins=root
Bash
복사
# frontend-user 생성
tctl users add backend-user --roles=backend-node-role --logins=root
Bash
복사
# backend-user 생성
명령을 실행하면 초대 링크(URL)가 출력됩니다.
이 링크를 브라우저로 열어 비밀번호(12자리 이상)와 OTP(2단계 인증)를 설정하면 계정 생성이 완료됩니다.
[TSH] Teleport 클러스터 접근 (frontend-user & backend-user)
tsh logout
Bash
복사
# tsh logout
echo $DOMAIN
Bash
복사
# tsh login (tele-admin)
tsh login --proxy=$DOMAIN:443 --user=frontend-user
Bash
복사
tsh ls
Bash
복사
# tsh ssh 노드 확인
tsh ssh root@FRONT-01
Bash
복사
# tsh ssh 접근
tsh ssh root@BACK-01
Bash
복사
tsh status
Bash
복사
# tsh 상태 확인
backend-user도 마찬가지로 접근해 봅니다.
3.2. Teleport Database 접근 통제
Database 대상을 구성하고 접근 통제 기능을 확인합니다.
tsh logout 후 tele-admin으로 로그인한 상태에서 진행합니다.
3.2.1. db_service 등록
LAB-ADMIN
[TCTL] DB Token 생성
tctl tokens add --type=db --ttl=1h
Bash
복사
# DB 토큰 생성
BACK-01 (tsh ssh root@BACK-01)
Teleport DB 설정 구성
DB_TOKEN=<<DB Token ID>>
DOMAIN=<<Teleport Domain Name>>
Bash
복사
# Teleport db_service 별도 파일로 저장
teleport db configure create \
--output=stdout \
--token=$DB_TOKEN \
--proxy=${DOMAIN}:443 \
--name=library-db \
--protocol=mysql \
--uri=192.168.12.100:30036 \
--labels=env=backend \
| sed 's|data_dir: "/var/lib/teleport"|data_dir: "/var/lib/teleport-db"|' \
> /etc/teleport-db.yaml
cat /etc/teleport-db.yaml
Bash
복사
cat > /etc/systemd/system/teleport-db.service << EOF
[Unit]
Description=Teleport DB Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/teleport start --config=/etc/teleport-db.yaml
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
Bash
복사
# db_service 전용 systemd 서비스 파일 생성
systemctl daemon-reload
systemctl enable --now teleport-db.service
systemctl status teleport-db.service
Bash
복사
# Teleport db_service 시작
db_service는 ssh_service와 달리 proxy_server로 접속해야 하고, 같은 data_dir을 공유하면 충돌이 발생합니다.
완전히 분리된 프로세스와 설정 파일로 실행합니다.
3.2.2. MariaDB mTLS 설정
LAB-ADMIN
tctl auth sign --format=db --host=192.168.12.100 --out=/root/server --ttl=8760h
Bash
복사
# Teleport CA 기반 DB 인증서 생성 (유효기간 1년)
ls -al server*
Bash
복사
# 인증서 파일 확인
tsh login --proxy=${DOMAIN}:443 --user=tele-admin
Bash
복사
# tsh 로그인 (BACK-01로 파일 전송 목적)
tsh scp /root/server.cas root@BACK-01:/root/server.cas
tsh scp /root/server.crt root@BACK-01:/root/server.crt
tsh scp /root/server.key root@BACK-01:/root/server.key
Bash
복사
# 인증서 파일을 BACK-01로 전송 (tsh scp 사용)
BACK-01 (tsh ssh root@BACK-01)
ls -al server*
Bash
복사
# 인증서 파일 확인
curl -O https://raw.githubusercontent.com/cloudneta/ongja/refs/heads/main/setup-mariadb-tls.sh
cat setup-mariadb-tls.sh
Bash
복사
# mTLS 설정 스크립트 다운로드 및 실행
chmod +x setup-mariadb-tls.sh
Bash
복사
./setup-mariadb-tls.sh
Bash
복사
Teleport는 self-hosted DB에 mutual TLS(mTLS)로 접속합니다.
MariaDB가 Teleport 인증서를 신뢰하도록 설정하고, 사용자 계정도 비밀번호가 아닌 인증서(CN) 기반으로 전환해야 합니다.
3.2.3. RBAC - DB 접근 Role 생성
LAB-ADMIN
cat > db-role.yaml << EOF
kind: role
version: v7
metadata:
name: db-access-role
spec:
allow:
db_labels:
'env': 'backend'
db_names: ['*']
db_users: ['*']
EOF
Bash
복사
# db-access-role 정의
tctl create -f db-role.yaml
Bash
복사
# db-access-role 생성
tctl users update backend-user --set-roles=backend-node-role,db-access-role
Bash
복사
# backend-user와 tele-admin에 db-access-role 추가
tctl users update tele-admin --set-roles=access,editor,db-access-role
Bash
복사
사용자 PC - 공통
MariaDB 설치
brew install mariadb
Bash
복사
# [MAC OS] mariadb 설치
sudo apt install -y mariadb-client
Bash
복사
# [WSL2 Ubuntu OS] mariadb 설치
mariadb --version
Bash
복사
# [공통] 설치 확인
Teleport DB 접속 테스트 (backend-user)
tsh logout
Bash
복사
# tsh 로그아웃
tsh login --proxy=${DOMAIN}:443 --user=backend-user
Bash
복사
# tsh 로그인 (backend-user)
tsh db ls
Bash
복사
# tsh db 리스트 확인
tsh db login library-db --db-user=teleport --db-name=librarydb
Bash
복사
# DB 접속 정보 저장
tsh db connect library-db
Bash
복사
# DB 접속
SELECT * FROM books;
Bash
복사
# 도서 데이터 조회
UPDATE books SET status='대출가능' WHERE title='AWS 교과서';
SELECT * FROM books;
Bash
복사
# 항목의 상태 변경 및 도서 데이터 조회
frontend-user도 마찬가지로 DB 접근을 확인해 봅니다.
# tsh 로그아웃 (backend-user)
tsh logout
# tsh 로그인 (frontend-user)
tsh login --proxy=${DOMAIN}:443 --user=frontend-user
# DB 목록 확인 (library-db가 보이지 않아야 정상)
tsh db ls
Bash
복사
3.2.4. DB 접근 Audit Log 확인
LAB-ADMIN
cd /var/lib/teleport/log/<UUID>/
Bash
복사
# DB 이벤트만 필터링
cat *.log | jq -c 'select(.event | startswith("db."))'
Bash
복사
cat *.log | jq -c 'select(.event == "db.session.query") | {time, user, db_name, db_query}'
Bash
복사
# DB 세션에서 실행된 쿼리만 추출
3.3. Teleport Kubernetes 접근 통제
Kubernetes 클러스터를 Teleport에 구성하고 접근 통제 기능을 확인합니다.
tsh logout 후 tele-admin으로 로그인한 상태에서 진행합니다.
3.3.1. kube_service 등록
LAB-ADMIN
[TCTL] Kube Token 생성
KUBE_TOKEN=$(tctl tokens add --type=kube --ttl=1h 2>&1 | grep "The invite token:" | awk '{print $NF}')
echo $KUBE_TOKEN
echo $DOMAIN
Bash
복사
# kube_service용 토큰 발급 및 변수 선언
FRONT-01 (tsh ssh root@FRONT-01)
Teleport Kubernetes 설정 구성
KUBE_TOKEN=<<KUBE Token ID>>
DOMAIN=<<Teleport Domain Name>>
Bash
복사
# Teleport kubernetes_service 별도 파일로 저장
cat > /etc/teleport-kube.yaml << EOF
version: v3
teleport:
nodename: FRONT-01
data_dir: /var/lib/teleport-kube
join_params:
token_name: ${KUBE_TOKEN}
method: token
proxy_server: ${DOMAIN}:443
auth_service:
enabled: "no"
ssh_service:
enabled: "no"
proxy_service:
enabled: "no"
kubernetes_service:
enabled: "yes"
kubeconfig_file: /etc/rancher/k3s/k3s.yaml
labels:
env: frontend
EOF
Bash
복사
cat > /etc/systemd/system/teleport-kube.service << EOF
[Unit]
Description=Teleport Kube Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/teleport start --config=/etc/teleport-kube.yaml
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
Bash
복사
# kube_service 전용 systemd 서비스 파일 생성
systemctl daemon-reload
systemctl enable --now teleport-kube.service
systemctl status teleport-kube.service
Bash
복사
# Teleport kube_service 시작
LAB-ADMIN
BACK-01은 스크립트로 일괄 처리
cat << SH > /tmp/setup-kube-backend.sh
#!/bin/bash
KUBE_TOKEN="${KUBE_TOKEN}"
DOMAIN="${DOMAIN}"
cat > /etc/teleport-kube.yaml << EOF
version: v3
teleport:
nodename: BACK-01
data_dir: /var/lib/teleport-kube
join_params:
token_name: \${KUBE_TOKEN}
method: token
proxy_server: \${DOMAIN}:443
auth_service:
enabled: "no"
ssh_service:
enabled: "no"
proxy_service:
enabled: "no"
kubernetes_service:
enabled: "yes"
kubeconfig_file: /etc/rancher/k3s/k3s.yaml
labels:
env: backend
EOF
cat > /etc/systemd/system/teleport-kube.service << EOF
[Unit]
Description=Teleport Kube Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/teleport start --config=/etc/teleport-kube.yaml
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now teleport-kube.service
systemctl status teleport-kube.service --no-pager
SH
Bash
복사
# BACK-01용 설정 스크립트 생성
tsh scp /tmp/setup-kube-backend.sh root@BACK-01:/tmp/setup-kube-backend.sh
Bash
복사
# 스크립트 전송 및 실행
tsh ssh root@BACK-01 "chmod +x /tmp/setup-kube-backend.sh && /tmp/setup-kube-backend.sh"
Bash
복사
사용자 PC - 공통
[TSH] 등록된 Kubernetes 클러스터 확인
tsh kube ls
Bash
복사
# 두 클러스터 등록 확인
LAB-ADMIN
tctl get role/access | grep -A 10 'kubernetes_groups'
Bash
복사
# access Role에서 kubernetes 설정 확인
3.3.2. RBAC - Kubernetes 접근 Role 생성
LAB-ADMIN
cat > kube-role.yaml << EOF
kind: role
version: v7
metadata:
name: kube-access-role
spec:
allow:
kubernetes_labels:
'*': '*'
kubernetes_groups:
- system:masters
kubernetes_resources:
- kind: '*'
name: '*'
namespace: '*'
verbs: ['*']
EOF
Bash
복사
# kube-access-role 생성 (모든 클러스터, system:masters 그룹)
tctl create -f kube-role.yaml
Bash
복사
# kube-access-role 생성
tctl users update tele-admin --set-roles=editor,access,db-access-role,kube-access-role
Bash
복사
# tele-admin에 kube-access-role 추가
사용자 PC - 공통
tele-admin의 Update Role 반영
tsh logout
tsh login --proxy=${DOMAIN}:443 --user=tele-admin
tsh status
Bash
복사
# tsh logout, login, status
kubectl 설치
brew install kubectl
Bash
복사
# [MAC OS] kubectl 설치
sudo apt install -y kubectl
Bash
복사
# [WSL2 Ubuntu OS] kubectl 설치
kubectl version
Bash
복사
# [공통] 설치 확인
Teleport Kubernetes 접속 테스트 (tele-admin)
tsh kube ls
Bash
복사
# kubernetes 클러스터 등록 확인
tsh kube login k3s-frontend
tsh kube ls
Bash
복사
# [tsh] k3s-frontend 클러스터 로그인
kubectl get nodes
Bash
복사
# k3s-frontend에 노드 확인
kubectl get pod -A
Bash
복사
# k3s-frontend에 전체 파드 확인
tsh kube login k3s-backend
tsh kube ls
Bash
복사
# [tsh] k3s-backend 클러스터 로그인
kubectl get pod
Bash
복사
# k3s-backend에 default 네임스페이스 파드 확인
3.3.3. Kubernetes 접근 Audit Log 확인
LAB-ADMIN
cd /var/lib/teleport/log/<UUID>/
Bash
복사
# Kubernetes API 요청 이벤트 확인 (누가, 어느 클러스터에서, 어떤 API를…)
cat *.log | jq -c 'select(.event == "kube.request") | {time, user, kubernetes_cluster, verb, request_path, response_code}'
Bash
복사
[OPTIONAL] frontend-user와 backend-user의 RBAC 구성하기
3.4. Teleport Web App 접근 통제
Teleport에 Web Application을 등록하고 접근 통제 기능을 확인합니다.
tsh logout 후 tele-admin으로 로그인한 상태에서 진행합니다.
3.4.1. app_service 등록
LAB-ADMIN
[TCTL] APP Token 생성
APP_TOKEN=$(tctl tokens add --type=app --ttl=1h 2>&1 | grep "The invite token:" | awk '{print $NF}')
echo $APP_TOKEN
echo $DOMAIN
Bash
복사
# app_service용 토큰 발급 및 변수 선언
FRONT-01 (tsh ssh root@FRONT-01)
Teleport Web App 설정 구성
APP_TOKEN=<<APP Token ID>>
DOMAIN=<<Teleport Domain Name>>
Bash
복사
# Teleport app_service 별도 파일로 저장
cat > /etc/teleport-app.yaml << EOF
version: v3
teleport:
nodename: FRONT-01
data_dir: /var/lib/teleport-app
join_params:
token_name: ${APP_TOKEN}
method: token
proxy_server: ${DOMAIN}:443
auth_service:
enabled: "no"
ssh_service:
enabled: "no"
proxy_service:
enabled: "no"
app_service:
enabled: "yes"
apps:
- name: library-portal
uri: http://192.168.11.100:30080
labels:
env: frontend
EOF
Bash
복사
cat > /etc/systemd/system/teleport-app.service << EOF
[Unit]
Description=Teleport App Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/teleport start --config=/etc/teleport-app.yaml
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
Bash
복사
# app_service 전용 systemd 서비스 파일 생성
systemctl daemon-reload
systemctl enable --now teleport-app.service
systemctl status teleport-app.service
Bash
복사
# Teleport app_service 시작
사용자 PC - 공통
[TSH] Web App 확인
tsh apps ls
Bash
복사
# 등록된 Web App 확인
tsh apps ls --format yaml
Bash
복사
# 등록된 Web App YAML로 확인
tsh apps ls --format json | \
python3 -c "import sys,json; print(json.load(sys.stdin)[0]['spec']['public_addr'])"
Bash
복사
# 접근을 위한 Public Address만 출력
1.2항에서 LAB-ADMIN에서 lynx로만 텍스트로 볼 수 있었던 화면이, 이제 Teleport 인증을 거쳐 외부 브라우저에서 완전한 웹 UI로 접근됩니다.
Private 서브넷의 웹앱이 Ingress ALB 없이도 Teleport Proxy 하나로 안전하게 외부에 노출됩니다.
로그아웃: Teleport Web UI 우측 상단 계정 → 로그아웃 시 브라우저 세션까지 완전히 무효화됩니다. 이후 웹앱 접근 시 Teleport 로그인 화면으로 리다이렉트됩니다. (tsh logout은 CLI 세션만 종료하므로 브라우저 세션은 별개입니다.)
3.4.2. Web App 접근 Audit Log 확인
LAB-ADMIN
cd /var/lib/teleport/log/<UUID>/
Bash
복사
# Web App 접근 이벤트 확인
cat *.log | jq -c 'select(.event | startswith("app.")) | {time, user, event, app_name}'
Bash
복사
4. 실습 환경 삭제
등록된 OTP 계정 삭제
실습 중 OTP 앱(Google Authenticator, Authy 등)에 등록한 tele-admin, frontend-user, backend-user 계정을 삭제합니다.
Terraform 자원 삭제
nohup sh -c "terraform destroy -auto-approve" > delete.log 2>&1 &
Bash
복사
# terraform 자원 삭제
Note:
Terraform 자원 삭제가 완료되면(약 3분 정도 대기) 정상적으로 자원 삭제가 되었는지 확인을 합니다.(cat delete.log)
여기까지 섹션 14 실습 - 서버 접근 통제 - Teleport 를 마칩니다.
수고하셨습니다 :)



