refactor: organize infra/ into compute/network/security/data/platform
This commit is contained in:
165
infra/security/teleport.md
Normal file
165
infra/security/teleport.md
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
title: Teleport (접근 관리)
|
||||
updated: 2026-03-27
|
||||
tags: [infra, teleport, k3s, security]
|
||||
---
|
||||
|
||||
## 개요
|
||||
|
||||
Gravitational Teleport — SSH/K8s/웹앱 접근 관리 플랫폼.
|
||||
|
||||
## 배포 정보
|
||||
|
||||
K3s 클러스터(kr3 컨텍스트)에 Helm으로 설치 (2026-03-26)
|
||||
|
||||
| 항목 | 값 |
|
||||
|------|-----|
|
||||
| Namespace | teleport |
|
||||
| Chart | teleport/teleport-cluster 18.7.3 |
|
||||
| App | Teleport 18.7.3 |
|
||||
| Mode | standalone, multiplex |
|
||||
| Proxy | LoadBalancer 192.168.9.52:443 |
|
||||
| Auth | ClusterIP 3025/3026 |
|
||||
| TLS | wildcard-inouter-tls (cert-manager) |
|
||||
| Storage | Longhorn 5Gi |
|
||||
| 클러스터명 | teleport.inouter.com |
|
||||
| DNS | teleport.inouter.com → 52.79.45.166 (Cloudflare, proxied: false) |
|
||||
|
||||
## 외부 접근 경로
|
||||
|
||||
```
|
||||
teleport.inouter.com (52.79.45.166)
|
||||
→ relay4wd:443
|
||||
→ iptables REDIRECT :8443
|
||||
→ APISIX stream_route (teleport)
|
||||
→ 192.168.9.52:443 (MetalLB)
|
||||
→ Teleport proxy Pod
|
||||
```
|
||||
|
||||
## 사용자
|
||||
|
||||
| User | Roles |
|
||||
|------|-------|
|
||||
| admin | editor, access, auditor |
|
||||
|
||||
## 인증
|
||||
|
||||
| 항목 | 값 |
|
||||
|------|-----|
|
||||
| 인증 방식 | local (패스워드 + MFA) |
|
||||
| MFA | OTP + WebAuthn (secondFactors) |
|
||||
| Passwordless | 활성화 (`authentication.passwordless: true`, `webauthn.rp_id: teleport.inouter.com`) |
|
||||
| MFA 비활성화 | 불가 — 한번 등록하면 `off`로 변경 시 auth 기동 실패 |
|
||||
| CLI 로그인 (패스워드) | `tsh login --proxy=teleport.inouter.com --user=admin --auth=local` (OTP 입력) |
|
||||
| CLI 로그인 (패스키) | `tsh login --proxy=teleport.inouter.com --auth=passwordless` (FIDO2 키 필요) |
|
||||
| Touch ID/패스키 | brew tsh 미지원, Teleport Connect 앱도 불안정 — **웹 UI 사용 권장** |
|
||||
| admin logins | teleport, root (`tctl users update admin --set-logins=teleport,root`) |
|
||||
|
||||
## Agentless OpenSSH 설정
|
||||
|
||||
기존 sshd를 Teleport agent 없이 연동하는 방식.
|
||||
|
||||
### 핵심 주의사항
|
||||
|
||||
> **Teleport는 OpenSSH agentless용으로 별도의 `openssh` CA를 사용한다.**
|
||||
> `tctl auth export --type=user`로 나오는 CA가 아니라,
|
||||
> `cert_authority` 리소스에서 `type=openssh`인 CA를 sshd에 등록해야 한다.
|
||||
|
||||
### OpenSSH CA 추출
|
||||
|
||||
```bash
|
||||
# openssh CA 추출 (TrustedUserCAKeys에 넣을 키)
|
||||
tctl get cert_authority --format=json | python3 -c "
|
||||
import json, sys, base64
|
||||
data = json.load(sys.stdin)
|
||||
for ca in data:
|
||||
kind = ca.get('spec', {}).get('type', 'unknown')
|
||||
if kind == 'openssh':
|
||||
keys = ca.get('spec', {}).get('active_keys', {}).get('ssh', [])
|
||||
for k in keys:
|
||||
pub = base64.b64decode(k.get('public_key', '')).decode()
|
||||
print(pub.strip())
|
||||
"
|
||||
```
|
||||
|
||||
현재 openssh CA:
|
||||
```
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPPCY1YoqnuOej43Y3THmgWZToWdjhF0g2R9/LzTNDqx
|
||||
fingerprint: SHA256:IKtA0dnz80YkkUrP9t3mnTsolSWIobDNflUK5fgXlCM
|
||||
```
|
||||
|
||||
### 호스트 인증서 발급
|
||||
|
||||
```bash
|
||||
# 호스트 인증서 생성 (principals에 호스트명, IP, UUID 모두 포함)
|
||||
tctl auth sign \
|
||||
--host=<hostname>,<FQDN>,<node-name>,localhost,127.0.0.1,::1 \
|
||||
--format=openssh \
|
||||
--out=myhost \
|
||||
--ttl=87600h
|
||||
# 결과: myhost (private key), myhost-cert.pub (host certificate)
|
||||
```
|
||||
|
||||
### sshd_config 필수 설정
|
||||
|
||||
```
|
||||
TrustedUserCAKeys /etc/ssh/teleport-user-ca.pub # openssh CA 공개키
|
||||
HostKey /etc/ssh/myhost # 호스트 비밀키
|
||||
HostCertificate /etc/ssh/myhost-cert.pub # 호스트 인증서
|
||||
```
|
||||
|
||||
### 노드 등록
|
||||
|
||||
```bash
|
||||
# tctl로 agentless 노드 등록
|
||||
cat > node.yaml << 'EOF'
|
||||
kind: node
|
||||
version: v2
|
||||
sub_kind: openssh
|
||||
metadata:
|
||||
name: <unique-name>
|
||||
labels:
|
||||
env: prod
|
||||
spec:
|
||||
addr: <host>:<port>
|
||||
hostname: <display-name>
|
||||
EOF
|
||||
tctl create -f node.yaml
|
||||
```
|
||||
|
||||
### 서버 요구사항
|
||||
|
||||
- sshd 계정이 locked 상태면 안 됨 (`usermod -p '*' <username>`)
|
||||
- HostKey/HostCertificate 파일 권한: private key 600, cert.pub 644
|
||||
- sshd가 `-h` 플래그로 호스트키를 지정하는 이미지는 HostCertificate가 무시될 수 있음
|
||||
|
||||
### 테스트 환경 (K8s)
|
||||
|
||||
test 네임스페이스에 debian:bookworm-slim 기반 sshd Pod 배포하여 검증 완료 (2026-03-26).
|
||||
|
||||
## 관리 명령
|
||||
|
||||
```bash
|
||||
# 사용자 목록
|
||||
kubectl exec -n teleport deploy/teleport-cluster-auth -- tctl users ls
|
||||
|
||||
# 패스워드 리셋
|
||||
kubectl exec -n teleport deploy/teleport-cluster-auth -- tctl users reset <username>
|
||||
|
||||
# 유저 logins 설정
|
||||
tctl users update <username> --set-logins=<login1>,<login2>
|
||||
|
||||
# Helm 설정
|
||||
helm get values teleport-cluster -n teleport
|
||||
|
||||
# SSH 접속
|
||||
tsh ssh <login>@<hostname>
|
||||
|
||||
# 등록된 노드 목록
|
||||
tsh ls
|
||||
```
|
||||
|
||||
## 관련 문서
|
||||
|
||||
- [[apisix]] — relay4wd stream_route로 Teleport 포워딩
|
||||
- [[sshpiper]] — SSH 리버스 프록시 (별도 서비스)
|
||||
Reference in New Issue
Block a user