시크릿 & 보안
Tow는 보안 우선 원칙으로 설계되었습니다. 이 페이지는 배포를 안전하게 유지하는 방법을 다룹니다.
SSH 인증
Tow는 세 가지 SSH 인증 방식을 지원합니다:
SSH 키 (기본값)
defaults:
ssh_key_path: ~/.ssh/deploy.pem
# Per-environment override
environments:
prod:
ssh_key_path: ~/.ssh/prod-deploy.pem
모범 사례:
- 개인 SSH 키가 아닌 전용 배포 키를 사용하세요
- 제한적인 권한을 설정하세요:
chmod 600 ~/.ssh/deploy.pem - 키를 정기적으로 교체하세요
- 환경마다 다른 키를 사용하세요
SSH 에이전트
modules:
api-server:
ssh:
auth: agent # Uses SSH_AUTH_SOCK
다음과 같은 경우에 적합합니다:
- 키가 에이전트에 주입되는 CI/CD 파이프라인
- 키 관리에
ssh-add를 사용하는 개발자 - 하드웨어 보안 키(YubiKey 등)를 사용하는 시스템
비밀번호 인증
modules:
api-server:
ssh:
auth: password
password: ${DEPLOY_PASSWORD} # Always use env vars!
경고: 비밀번호 인증은 가장 안전하지 않은 옵션입니다. 키 기반 인증을 사용할 수 없을 때만 사용하세요.
tow.yaml에 비밀번호를 하드코딩하지 마세요.
시크릿 관리
규칙 #1: 시크릿을 절대 커밋하지 않는다
Tow는 시크릿을 버전 관리 밖에 두기 위한 여러 메커니즘을 제공합니다:
환경 변수
environments:
prod:
servers:
- number: 1
host: ${PROD_SERVER_IP}
modules:
api-server:
ssh:
password: ${DEPLOY_PASSWORD}
variables:
DB_PASSWORD: ${DB_PASSWORD}
로컬 오버라이드 (tow.local.yaml)
# tow.local.yaml — always in .gitignore
defaults:
ssh_key_path: ~/.ssh/my-personal-key.pem
environments:
dev:
servers:
- number: 1
host: 192.168.1.100
애플리케이션 설정 시크릿
애플리케이션 설정 파일(예: application.yml, redis.conf)에는 데이터베이스 비밀번호나 API 키 같은 시크릿이 흔히 포함됩니다. Tow는 배포 중에 설정 파일 안의 ${VAR} 환경 변수를 자동으로 확장합니다:
# config/prod/application.yml (safe to commit — no real secrets)
spring:
datasource:
url: jdbc:mysql://${DB_HOST}:3306/mydb
password: ${DB_PASSWORD}
redis:
password: ${REDIS_PASSWORD}
external-api:
key: ${API_SECRET_KEY}
배포 시점에 Tow는 환경 변수를 읽어서 서버에 업로드하기 전에 치환합니다. 실제 시크릿은 git에 절대 남지 않습니다.
# Set secrets as environment variables
export DB_PASSWORD="my-secret-password"
export REDIS_PASSWORD="redis-secret"
export API_SECRET_KEY="sk-xxxxx"
# Deploy — secrets are injected into config files automatically
tow deploy -e prod -m api-server
참고: 환경에
${VAR}가 설정되어 있지 않으면 빈 문자열로 치환됩니다. Tow는 모든 변수가 설정되어 있는지 검증하지 않습니다 — 이는 사용자의 책임입니다.
.gitignore 기본값
Tow의 기본 .gitignore는 다음을 제외합니다:
*.pem
*.key
credentials.*
tow.local.yaml
호스트 키 검증
기본적으로 Tow는 ~/.ssh/known_hosts를 사용해서 서버 신원을 검증합니다:
# Normal mode — verifies host keys
tow deploy -e prod -m api-server
# Insecure mode — skips verification (not recommended for production)
tow deploy -e prod -m api-server --insecure
권장 사항: 항상 최신 상태의
known_hosts파일을 유지하세요. 새 서버에는ssh-keyscan your-server >> ~/.ssh/known_hosts를 실행하세요.
프로덕션 확인 프롬프트
Tow는 프로덕션과 유사한 환경(prod, production, live)에 배포할 때 자동으로 확인을 요청합니다:
⚠ WARNING: You are about to deploy api-server in PROD
Type 'yes' to confirm:
CI/CD 파이프라인에서는 -y / --yes 플래그로 건너뛸 수 있습니다:
tow deploy -e prod -m api-server -y
tow auto -e prod -m api-server --auto-rollback -y
이는 tow deploy 오타로 인한 실수 배포를 방지합니다.
브랜치 정책
잘못된 브랜치에서의 실수 배포를 방지합니다:
단순 모드
environments:
prod:
branch: main # Only allow deploys from 'main' branch
고급 모드
environments:
prod:
branch_policy:
allowed:
- main
- release/*
- hotfix/*
commands:
- deploy
- auto
- start
- restart
- rollback
이는 피처 브랜치를 프로덕션에 배포하는 것과 같은 시나리오를 방지합니다.
배포 락
Tow는 원자적 락 파일을 사용해서 동시 배포를 방지합니다:
Developer A: tow deploy -e prod → acquires lock → deploys → releases lock
Developer B: tow deploy -e prod → "Deploy locked by alice@machine since 14:30" → blocked
이는 두 명의 개발자가 동시에 배포해서 상태가 불일치하게 되는 경쟁 조건을 방지합니다.
배포가 중단되어 락이 해제되지 않았다면:
tow unlock -e prod -m api-server
모듈별 SSH 설정
모듈마다 다른 자격 증명을 사용할 수 있습니다:
modules:
api-server:
ssh:
user: app-deploy
key_path: ~/.ssh/app-key.pem
kafka:
ssh:
user: kafka-admin
port: 2222
key_path: ~/.ssh/infra-key.pem
이는 최소 권한 원칙을 지원합니다 — 각 서비스는 필요한 자격 증명만 사용합니다.
네트워크 보안 권장 사항
방화벽 규칙
- SSH 접근을 배포 머신으로만 제한하세요
- 프로덕션 환경에는 배스천/점프 호스트를 사용하세요
- 애플리케이션에 필요한 포트를 제외한 모든 포트를 닫으세요
SSH 강화
대상 서버에서:
# /etc/ssh/sshd_config
PasswordAuthentication no # Disable password auth
PermitRootLogin no # Disable root login
AllowUsers ec2-user deploy-user # Whitelist users
MaxAuthTries 3 # Limit auth attempts
CI/CD 연동
CI/CD 파이프라인에서 Tow를 사용할 때:
# GitHub Actions example
- name: Deploy to production
env:
PROD_SERVER_1: ${{ secrets.PROD_SERVER_1 }}
DEPLOY_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: |
echo "$DEPLOY_KEY" > /tmp/deploy.pem
chmod 600 /tmp/deploy.pem
tow deploy -e prod -m api-server -c tow.yaml
rm /tmp/deploy.pem
보안 체크리스트
- SSH 키가
600권한을 가지고 있다 -
tow.local.yaml이.gitignore에 포함되어 있다 -
tow.yaml에 하드코딩된 시크릿이 없다 - 프로덕션이
branch또는branch_policy제한을 사용한다 - 프로덕션에서
--insecure플래그를 사용하지 않는다 - 환경마다 다른 SSH 키를 사용한다
- 배포 사용자가 필요한 최소 권한만 가지고 있다
- 모든 서버에 대해
~/.ssh/known_hosts가 유지 관리된다 - CI/CD 시크릿이 플랫폼의 시크릿 매니저에 저장되어 있다