HTTPS/SSL 설정 가이드
FlowKat는 UI Server(포트 8080, Docker 외부 6300)를 통해 웹 인터페이스를 제공한다. 기본 배포는 HTTP이므로, 프로덕션 환경에서는 외부 Nginx 리버스 프록시를 통한 SSL Termination 방식을 권장한다.
1. 개요
HTTPS 적용 시나리오
| 시나리오 | 적합 환경 | 특징 |
|---|---|---|
| Nginx 리버스 프록시 (권장) | 인터넷 노출 프로덕션 | SSL Termination, Let's Encrypt 자동 갱신, FlowKat 컨테이너 변경 없음 |
| 외부 로드밸런서 | AWS ALB, NLB, 클라우드 환경 | 로드밸런서에서 SSL 처리, FlowKat는 내부 HTTP 유지 |
| 자체 서명 인증서 | 사내 폐쇄망, 에어갭 환경 | PKI 인프라 불필요, 브라우저 경고 발생 |
포트 매핑 (Nginx 리버스 프록시 기준)
인터넷 443(HTTPS)
→ 호스트 Nginx (SSL Termination)
→ 호스트:6300 (Docker ui-server:8080, Next.js)
→ docker-network:6600 (dashboard-server)
→ docker-network:6188 (api-server)
→ docker-network:8090 (tx-mining-api)
- FlowKat Docker 컨테이너 내부 통신은 모두 HTTP(평문)로 유지된다.
- SSL은 Nginx 계층에서만 처리한다.
2. Nginx 리버스 프록시 방식 (권장)
2.1 사전 요구사항
- 호스트 서버에 Nginx 설치 (컨테이너 외부, 직접 설치)
- 공인 도메인 및 DNS A 레코드 설정 완료
- 포트 80, 443 방화벽 오픈
# Ubuntu/Debian
sudo apt install -y nginx certbot python3-certbot-nginx
# RHEL/Rocky
sudo dnf install -y nginx certbot python3-certbot-nginx
2.2 Nginx 설정 파일
/etc/nginx/conf.d/flowkat.conf를 생성한다.
# FlowKat HTTPS 리버스 프록시
# HTTP → HTTPS 리디렉션
server {
listen 80;
listen [::]:80;
server_name flowkat.example.com;
# Let's Encrypt ACME 챌린지 (인증서 발급/갱신용)
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS 메인 블록
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name flowkat.example.com;
# SSL 인증서 (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/flowkat.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/flowkat.example.com/privkey.pem;
# SSL 보안 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# HSTS (브라우저에 HTTPS 강제, 1년)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 보안 헤더
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 클라이언트 설정
client_max_body_size 50M;
# NextAuth JWT 쿠키 버퍼 (accessSetting 46+ URL 포함으로 쿠키가 큼)
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
# Upstream: FlowKat UI Server (Docker 외부 포트 6300)
upstream flowkat_ui {
server 127.0.0.1:6300;
keepalive 32;
}
# WebSocket connection upgrade 매핑
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# FlowKat UI Server 프록시
location / {
proxy_pass http://flowkat_ui;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 타임아웃 (실시간 모니터링 연결 유지)
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
# 타임아웃 (일반 요청)
proxy_connect_timeout 60s;
}
# 헬스체크
location /health {
access_log off;
proxy_pass http://flowkat_ui/health;
}
}
2.3 설정 검증 및 적용
# 문법 검사
sudo nginx -t
# 설정 리로드
sudo systemctl reload nginx
2.4 Let's Encrypt 인증서 발급
# 최초 발급
sudo certbot --nginx -d flowkat.example.com
# 이메일 등록 및 이용약관 동의 후 자동 발급
# Nginx 설정이 자동으로 업데이트됨
2.5 인증서 자동 갱신
Let's Encrypt 인증서는 90일 유효하다. certbot은 cron/systemd로 자동 갱신한다.
# 자동 갱신 테스트
sudo certbot renew --dry-run
# crontab 등록 (없는 경우 수동 추가)
sudo crontab -e
# 추가: 매일 새벽 2시 갱신 시도
# 0 2 * * * certbot renew --quiet && systemctl reload nginx
3. .env 환경변수 설정 (HTTPS 적용 시 필수)
HTTPS 환경에서 FlowKat 동작을 위해 .env 파일을 수정한다.
# 프로덕션 .env 파일 수정
vi /path/to/flowkat/deploy/.env
변경할 환경변수:
# 인증 콜백 URL: 실제 도메인으로 변경 (HTTPS 필수)
NEXTAUTH_URL=https://flowkat.example.com
# HTTPS 환경에서 secure 쿠키 활성화 (필수)
USE_SECURE_COOKIES=true
# 리버스 프록시 뒤에서 호스트 신뢰
AUTH_TRUST_HOST=true
# CORS 허용 도메인
CORS_ORIGINS=https://flowkat.example.com
# WebSocket URL (Nginx 프록시 모드)
FLOWKAT_API_SOCKET_URL=https://flowkat.example.com
환경변수 적용:
# FlowKat 서비스 재시작
sh stop-all.sh
sh start-all.sh
4. 자체 서명 인증서 방식 (폐쇄망/에어갭)
공인 CA 인증서를 사용할 수 없는 사내망 환경에서는 자체 서명 인증서를 사용한다.
4.1 인증서 생성
# 인증서 저장 디렉토리 생성
sudo mkdir -p /etc/nginx/ssl/flowkat
# 자체 서명 인증서 생성 (10년 유효)
sudo openssl req -x509 -nodes -days 3650 \
-newkey rsa:2048 \
-keyout /etc/nginx/ssl/flowkat/server.key \
-out /etc/nginx/ssl/flowkat/server.crt \
-subj "/C=KR/ST=Seoul/L=Seoul/O=YourCompany/CN=flowkat.internal" \
-addext "subjectAltName=IP:192.168.1.100,DNS:flowkat.internal"
브라우저에서 "신뢰할 수 없는 인증서" 경고가 표시된다. 기업 내부 CA를 보유한 경우 해당 CA로 서명하면 경고 없이 사용 가능하다.
4.2 Nginx 설정 (자체 서명 인증서 적용)
섹션 2.2의 설정에서 ssl_certificate 경로만 교체한다.
ssl_certificate /etc/nginx/ssl/flowkat/server.crt;
ssl_certificate_key /etc/nginx/ssl/flowkat/server.key;
4.3 브라우저에 인증서 등록 (선택)
팀 내 브라우저에서 경고를 없애려면 server.crt를 운영체제/브라우저 신뢰 저장소에 등록한다.
# Ubuntu 시스템 신뢰 저장소 등록
sudo cp /etc/nginx/ssl/flowkat/server.crt /usr/local/share/ca-certificates/flowkat.crt
sudo update-ca-certificates
5. Docker Compose SSL 설정
FlowKat Docker 컨테이너 자체에 SSL을 적용하는 방식이다. 권장하지 않으며, 운영 복잡도가 높아진다. Nginx 리버스 프록시 방식을 먼저 검토한다.
5.1 인증서 볼륨 마운트
# docker-compose.yml (ssl 적용 예시)
services:
ui-server:
image: registry.flowkat.dev/flowkat/ui-server:${FLOWKAT_VERSION}
ports:
- "6300:8080"
- "6443:8443" # HTTPS 포트 추가
volumes:
- ./volumes/ui-server/uploads:/app/flowkat/uploads
- ./ssl/certs:/etc/nginx/ssl:ro # 인증서 읽기 전용 마운트
environment:
- SSL_CERT_PATH=/etc/nginx/ssl/server.crt
- SSL_KEY_PATH=/etc/nginx/ssl/server.key
5.2 인증서 파일 배치
# 인증서 디렉토리 생성
mkdir -p ./ssl/certs
# 인증서 복사
cp /etc/nginx/ssl/flowkat/server.crt ./ssl/certs/server.crt
cp /etc/nginx/ssl/flowkat/server.key ./ssl/certs/server.key
chmod 644 ./ssl/certs/server.crt
chmod 600 ./ssl/certs/server.key
5.3 환경변수 (.env)
# Docker 내부 SSL 활성화 시 추가
USE_SECURE_COOKIES=true
NEXTAUTH_URL=https://flowkat.example.com:6443
6. 에이전트-서버 간 통신 보안
6.1 Collect Server TCP 6100 포트
FlowKat Agent는 Collect Server의 TCP 6100 포트로 성능 데이터를 전송한다. 이 채널은 기본적으로 평문 TCP이다.
| 포트 | 프로토콜 | 내용 | 기본 암호화 |
|---|---|---|---|
| 6100 | TCP | Agent → Collect Server 데이터 전송 | 없음 |
에이전트 데이터는 메트릭 수치(응답 시간, TPS 등)로 구성되며 민감한 비즈니스 데이터를 직접 포함하지 않는다. 단, 규정상 전송 암호화가 필요한 경우 아래 방법을 적용한다.
6.2 에이전트 통신 보안 방법
방법 1: VPN 터널링 (권장)
에이전트가 설치된 서버와 Collect Server 사이에 VPN(WireGuard, OpenVPN 등)을 구성하면 TCP 6100 트래픽이 VPN 터널 내에서 암호화된다. FlowKat 코드 변경 없이 적용 가능하다.
# WireGuard 예시 (에이전트 서버 측)
# /etc/wireguard/wg0.conf 설정 후
sudo wg-quick up wg0
방법 2: SSH 터널
소규모 환경이나 임시 구성에서 사용한다.
# Collect Server IP: 10.0.0.1
# 에이전트 서버에서 SSH 포워딩
ssh -L 6100:localhost:6100 user@collect-server-host -N -f
방법 3: 네트워크 수준 분리
에이전트 서버와 Collect Server를 동일 사내 LAN에 두고 외부 접근을 방화벽으로 차단한다. 대부분의 온프레미스 배포에서 이 방식으로 충분하다.
7. 트러블슈팅
7.1 인증서 만료
# 인증서 만료일 확인
sudo openssl x509 -enddate -noout -in /etc/letsencrypt/live/flowkat.example.com/fullchain.pem
# 수동 갱신
sudo certbot renew --force-renewal
sudo systemctl reload nginx
7.2 Mixed Content (혼합 콘텐츠)
증상: HTTPS 페이지에서 HTTP 리소스 로드 차단, 브라우저 콘솔에 Mixed Content 에러.
원인 및 해결:
| 원인 | 해결 |
|---|---|
.env의 NEXTAUTH_URL이 http://로 설정됨 | https://로 변경 후 서비스 재시작 |
FLOWKAT_API_SOCKET_URL이 http://로 설정됨 | https://로 변경 |
USE_SECURE_COOKIES=false 상태 | true로 변경 |
Nginx의 X-Forwarded-Proto 헤더 누락 | nginx.conf에 proxy_set_header X-Forwarded-Proto $scheme; 확인 |
7.3 CORS 오류
증상: 브라우저 콘솔에 CORS policy: No 'Access-Control-Allow-Origin' 에러.
# .env에서 CORS_ORIGINS 확인
grep CORS_ORIGINS .env
# 도메인이 정확히 일치해야 함 (trailing slash 주의)
CORS_ORIGINS=https://flowkat.example.com
복수 도메인 허용:
CORS_ORIGINS=https://flowkat.example.com,https://flowkat2.example.com
7.4 NextAuth 인증 실패
증상: 로그인 후 /api/auth/callback 에러, 세션 생성 실패.
# NEXTAUTH_URL이 실제 접속 URL과 일치하는지 확인
grep NEXTAUTH_URL .env
# ui-server 로그 확인
docker logs -f ui-server 2>&1 | grep -i "nextauth\|auth\|error"
7.5 WebSocket 연결 실패
증상: 실시간 모니터링 데이터가 표시되지 않음, 브라우저 DevTools Network 탭에서 WebSocket 연결 상태 101 미수신.
Nginx WebSocket 설정 확인:
# 다음 헤더가 모두 설정되어 있어야 함
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
$connection_upgrade 변수가 정의되어 있는지 확인:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
7.6 502 Bad Gateway
증상: Nginx에서 502 응답.
# FlowKat UI Server 상태 확인
docker ps | grep ui-server
curl -I http://localhost:6300
# Nginx 에러 로그 확인
sudo tail -f /var/log/nginx/error.log
FlowKat 서비스가 정상이라면 proxy_buffer 크기 문제일 수 있다. nginx.conf에 다음이 설정되어 있는지 확인한다:
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
8. HTTPS 관련 핵심 파라미터
| 파라미터 | 타입 | 기본값 | conf 키 | 중요도 | 설명 |
|---|---|---|---|---|---|
NEXTAUTH_URL | string | http://localhost:3000 | .env NEXTAUTH_URL | 필수 | 인증 콜백 URL. HTTPS 전환 시 https:// 도메인으로 변경 필수 |
USE_SECURE_COOKIES | boolean | false | .env USE_SECURE_COOKIES | 필수 | HTTPS 환경에서 secure 쿠키 활성화. true 설정 필수 |
AUTH_TRUST_HOST | boolean | false | .env AUTH_TRUST_HOST | 핵심 | 리버스 프록시 뒤에서 호스트 헤더 신뢰. 프록시 환경에서 true |
CORS_ORIGINS | string | - | .env CORS_ORIGINS | 핵심 | CORS 허용 도메인. HTTPS 도메인으로 설정 |
FLOWKAT_API_SOCKET_URL | string | - | .env FLOWKAT_API_SOCKET_URL | 핵심 | WebSocket URL. Nginx 프록시 모드에서 HTTPS 도메인 설정 |
ssl_certificate | path | - | nginx.conf | 필수 | SSL 인증서 파일 경로 |
9. 관련 문서
- 대시보드/API 서버 설정: 15.dashboard-server.md
- Docker Compose 환경변수: 16.docker-compose.md
- 네트워크/포트 매핑: 17.network-ports.md
- 배포 체크리스트: 33.deploy-checklist.md