본문으로 건너뛰기

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이다.

포트프로토콜내용기본 암호화
6100TCPAgent → 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 에러.

원인 및 해결:

원인해결
.envNEXTAUTH_URLhttp://로 설정됨https://로 변경 후 서비스 재시작
FLOWKAT_API_SOCKET_URLhttp://로 설정됨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_URLstringhttp://localhost:3000.env NEXTAUTH_URL필수인증 콜백 URL. HTTPS 전환 시 https:// 도메인으로 변경 필수
USE_SECURE_COOKIESbooleanfalse.env USE_SECURE_COOKIES필수HTTPS 환경에서 secure 쿠키 활성화. true 설정 필수
AUTH_TRUST_HOSTbooleanfalse.env AUTH_TRUST_HOST핵심리버스 프록시 뒤에서 호스트 헤더 신뢰. 프록시 환경에서 true
CORS_ORIGINSstring-.env CORS_ORIGINS핵심CORS 허용 도메인. HTTPS 도메인으로 설정
FLOWKAT_API_SOCKET_URLstring-.env FLOWKAT_API_SOCKET_URL핵심WebSocket URL. Nginx 프록시 모드에서 HTTPS 도메인 설정
ssl_certificatepath-nginx.conf필수SSL 인증서 파일 경로

9. 관련 문서