리버스 프록시로 Quack 보안 설정하기
리버스 프록시로 Quack 보안 설정하기
Quack 서버는 기본적으로 plain HTTP만 다루고, 기본 설정으로 localhost에만 바인딩돼요. 로컬을 넘어서는 어떤 배포에서든 권장 패턴은 다른 HTTP 기반 데이터베이스/애플리케이션 서버와 동일해요. 검증된 HTTP 리버스 프록시를 앞에 두고, 프록시가 TLS를 종료하게 하면 돼요. 이 가이드에서 그 설정 방법을 단계별로 살펴볼게요.
출처: 문서
본문
Quack 클라이언트는 이와 잘 협력해요. 로컬이 아닌 URI에 대해서는 기본적으로 HTTPS를 가정하죠. 그래서 제대로 프록시를 앞에 둔 서버는 클라이언트 쪽에서도 별다른 설정 없이 "그냥 동작"해요.
이 가이드는 유용할 것 같은 순서대로 세 가지 설정을 다룹니다.
- Caddy를 이용한 로컬 TLS 테스트 설정 — 여러분의 머신에서 전체 HTTPS 경로를 실습할 수 있어요.
- 프로덕션에서의 nginx + Let's Encrypt.
- 프로덕션에서의 Caddy + Let's Encrypt.
두 프로덕션 설정은 서로 바꿔 쓸 수 있어요. 운영 스택에 맞는 것을 고르면 됩니다.
Caddy를 이용한 로컬 테스트 설정
Caddy를 사용해 여러분의 머신에서 전체 HTTPS 경로를 실습할 수 있어요. Caddy는 로컬 CA에서 localhost용 인증서를 자체 발급하고, 그 CA 루트를 시스템 신뢰 저장소에 설치하므로 DuckDB의 HTTPS 클라이언트가 추가 설정 없이 인증서를 신뢰하게 됩니다.
1. Caddy 실행
이 Caddyfile을 저장하세요.
localhost:8443 {
reverse_proxy 127.0.0.1:9494 {
flush_interval -1
}
request_body {
max_size 256MB
}
}
그다음 Caddy를 시작합니다.
brew install caddy # macOS, 다른 플랫폼은 https://caddyserver.com/docs/install 참고
caddy run --config Caddyfile
첫 실행 시 Caddy의 로컬 CA를 시스템 신뢰 저장소에 설치하기 위해 권한 상승을 요청할 거예요. 그 이후로 Caddy가 localhost에 대해 발급한 인증서는 시스템 전체에서 신뢰됩니다.
2. Quack을 시작하고 프록시를 통해 연결
한 DuckDB 세션에서 서버를 시작합니다 (인증 토큰이 출력돼요).
CALL quack_serve('quack:localhost');
클라이언트 세션에서는 :8443의 Caddy를 통해 연결해요. 로컬 URI는 기본적으로 plain HTTP를 쓰므로, SSL을 명시적으로 켜야 합니다.
ATTACH 'quack:localhost:8443' AS quack (
TOKEN '⟨authentication_token-from-quack_serve⟩',
DISABLE_SSL false
);
FROM quack.query('SELECT 42');
왕복이 성공하면 여러분의 트래픽은 TLS로 Caddy에 나갔다가, 종료된 뒤 plain HTTP로 :9494의 Quack에 전달된 거예요.
Nginx + Let's Encrypt
가장 흔한 선택이 될 것 같아요. 루프백 인터페이스에서 수신하는 Quack 서버를 위한 최소한의 사이트 설정은 다음과 같습니다.
# /etc/nginx/sites-enabled/quack.example.com
server {
listen 443 ssl http2;
server_name quack.example.com;
ssl_certificate /etc/letsencrypt/live/quack.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/quack.example.com/privkey.pem;
# Quack RPC 바디는 클 수 있어요: PREPARE는 SQL을, APPEND는 삽입된
# DataChunk를 실어 나릅니다. nginx 기본값 1 MiB면 INSERT 도중 실패해요.
client_max_body_size 256M;
# 오래 실행되는 쿼리는 FETCH 사이를 몇 분씩 걸려 와이어 위에
# 머무를 수 있어요. nginx 기본 60초보다 타임아웃을 올려 주세요.
proxy_read_timeout 600s;
proxy_send_timeout 600s;
location / {
proxy_pass http://127.0.0.1:9494;
# 업스트림에 대한 keep-alive. Quack은 서버 쪽
# `quack_connection_id` 상태를 유지하기 위해 지속 연결에 의존해요.
proxy_http_version 1.1;
proxy_set_header Connection "";
# Quack은 반복되는 FETCH 응답으로 결과를 스트리밍해요.
# nginx의 버퍼링은 스트리밍을 무력화하고 메모리를 부풀려요.
proxy_buffering off;
}
}
Quack 쪽에서는 localhost에 바인딩된 서버를 시작합니다 (기본값이에요).
CALL quack_serve('quack:localhost');
certbot --nginx -d quack.example.com으로 인증서를 발급하세요.
클라이언트는 HTTPS로 자동 연결됩니다.
ATTACH 'quack:quack.example.com' AS quack; -- HTTPS 자동 선택
Caddy + Let's Encrypt
Caddy는 Let's Encrypt에서 인증서를 자동 프로비저닝하며 설정이 거의 필요 없어요. 공개 지향 Quack 프록시의 완전한 설정은 다음과 같습니다.
# /etc/caddy/Caddyfile
quack.example.com {
reverse_proxy 127.0.0.1:9494 {
# nginx `proxy_buffering off`와 동일한 역할. Quack의 스트리밍된
# FETCH 응답이 Caddy에 버퍼링되지 않고 즉시 통과하도록 필수예요.
flush_interval -1
}
# nginx `client_max_body_size`와 동일. PREPARE / APPEND 바디는
# 기본 요청 본문 상한보다 훨씬 클 수 있어요.
request_body {
max_size 256MB
}
}
Caddy가 인증서 발급과 갱신을 자동으로 처리해요. certbot 단계가 필요 없답니다.
Quack 쪽에서는 localhost에 바인딩된 서버를 시작합니다 (기본값).
CALL quack_serve('quack:localhost');
클라이언트는 HTTPS로 자동 연결됩니다.
ATTACH 'quack:quack.example.com' AS quack; -- HTTPS 자동 선택
더 알아보기 (Learn more)
- Quack 서버가 왜 이렇게 기본 설정을 갖는지에 대한 배경은
quack/security문서를 참고해 주세요.