Skip to content

infra: api 도메인에 HTTPS 를 붙이는 절차를 남긴다 - #330

Open
sevineleven wants to merge 1 commit into
devfrom
infra/232-https-api-domain
Open

infra: api 도메인에 HTTPS 를 붙이는 절차를 남긴다#330
sevineleven wants to merge 1 commit into
devfrom
infra/232-https-api-domain

Conversation

@sevineleven

Copy link
Copy Markdown
Contributor

Situation

운영 API 가 평문 HTTP 로 인터넷에 열려 있다. 실측으로 확인했다.

http://18.181.168.227:8080/api/v1/categories  → 401 (0.15초)   ← 서비스 중이다
https://…:8080                                 → 실패          ← TLS 없음

401 이 온다는 건 서버가 거기서 실제로 응답한다는 뜻이다. 그 위로 access 토큰(Bearer)과 Basic 자격증명이 평문으로 오간다. 같은 네트워크에 있는 누구든 토큰을 주워 남의 계정으로 API 를 부를 수 있다.

#280 이 "요청 헤더로 남의 데이터를 못 건드린다" 를 닫았는데, 그 토큰이 도청 가능하면 반쪽이다.

Task

TLS 종료를 앞단에 두고 앱 포트를 인터넷에서 걷어낸다. 다만 순서를 뒤집으면 서비스가 끊긴다 — 지금 앱이 EC2 의 8080 을 직접 부른다.

Action

이 PR 은 문서와 설정 파일만 담는다. 실제 전환은 EC2·AWS 콘솔·프론트 재빌드가 함께 움직여야 한다.

Caddy 를 택했다

nginx + certbot 은 cron·타이머·재적재 훅을 따로 세워야 하고, 그중 하나만 어긋나면 만료일에 서비스가 통째로 죽는다. Caddy 는 발급·갱신을 스스로 하고 실패해도 옛 인증서로 계속 서비스한다. 움직이는 부품이 적다.

앱을 offway-core:8080 으로 부른다 — 같은 도커 네트워크의 컨테이너 이름이라 호스트 포트를 거치지 않는다. 나중에 앱을 127.0.0.1 에만 바인딩해도 이 경로는 그대로 산다.

순서를 표로 못박았다

# 할 일 이 시점의 서비스
1 DNS api A → 18.181.168.227 8080 으로 정상
2 SG 인바운드 80·443 추가 8080 으로 정상
3 Caddy 기동 8080·443 둘 다 응답
4 프론트가 API_BASE_URL 재빌드·배포 443 으로 옮겨감
5 SG 에서 8080 제거 443 으로만
6 deploy.yml 로컬 바인딩 443 으로만

1·2 는 완료했다. 4 를 건너뛰고 5 로 가면 옛 앱을 쓰는 사용자가 전부 끊긴다.

함정 두 개를 런북에 적었다

  • caddy-data 볼륨 없이 띄우면 안 된다. 컨테이너를 갈아끼울 때마다 재발급인데 Let's Encrypt 는 도메인당 주 5회다. 막히면 일주일을 기다린다
  • 80 을 0.0.0.0/0 으로 열어야 한다. HTTP-01 검증이 그 포트로 오고, 검증 IP 가 보장되지 않아 좁히면 실패한다. 갱신 때마다 필요하다

deploy.yml 은 건드리지 않았다

로컬 바인딩(-p 127.0.0.1:8080:8080) 전환은 프록시가 서기 전에 머지되면 서비스가 죽는 변경이다. 6단계에서 따로 올린다.

Result

3단계부터를 붙여넣기로 진행할 수 있다. 전환이 끝나면 평문 경로가 사라진다.

인증서 갱신 실패는 이 구성의 유일한 조용한 위험이다 — Caddy 가 실패해도 옛 인증서로 계속 서비스해서, 만료일에 한꺼번에 죽는다. 지금은 tls 에 적은 주소로 오는 Let's Encrypt 만료 임박 메일이 1차 방어다. 배포 스모크에 남은 기간 확인을 붙이는 것은 6단계에서 함께 정한다 — 그때 deploy.yml 이 이미 그 도메인을 부르게 되기 때문이다.


연관 이슈

- 운영 API 가 평문으로 열려 있다. http://18.181.168.227:8080 이 그대로 401 을
  응답하는 것을 확인했다 — access 토큰과 Basic 자격증명이 평문으로 인터넷을 지난다.
  #280 이 "헤더로 남의 데이터를 못 건드린다" 를 닫았는데 그 토큰이 도청 가능하면 반쪽이다
- Caddy 를 택했다. nginx + certbot 은 cron·타이머·재적재 훅을 따로 세워야 하고 그중
  하나만 어긋나면 만료일에 서비스가 죽는다. Caddy 는 발급·갱신을 스스로 하고 실패해도
  옛 인증서로 계속 서비스한다
- **순서가 뒤집히면 서비스가 끊긴다.** 지금 앱이 EC2 의 8080 을 직접 부르므로,
  8080 을 먼저 닫거나 앱을 먼저 로컬 바인딩으로 바꾸면 그 순간 죽는다. 런북이 어느
  시점에도 서비스가 살아 있는 순서를 표로 못박았다 — 프론트 재빌드 배포가 퍼진 뒤에야
  8080 을 닫는다
- 인증서 볼륨(caddy-data)을 강조했다. 없이 띄우면 컨테이너를 갈아끼울 때마다 재발급인데
  Let's Encrypt 는 도메인당 주 5회라 곧 막히고, 막히면 일주일을 기다려야 한다
- 80 도 함께 여는 이유를 적었다. HTTP-01 검증이 그 포트로 오고 갱신 때마다 필요하다
- deploy.yml 의 로컬 바인딩 전환은 이 PR 에 넣지 않는다. 프록시가 서기 전에 머지되면
  서비스가 죽는 변경이라 6단계에서 따로 올린다
@sevineleven sevineleven added the infra 인프라·배포·시크릿 label Aug 25, 2026
@sevineleven sevineleven self-assigned this Aug 25, 2026
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 18 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 25a7f7f3-03d4-4c97-be52-a25342cd976f

📥 Commits

Reviewing files that changed from the base of the PR and between c60b2ca and 6175e51.

📒 Files selected for processing (2)
  • scripts/Caddyfile
  • scripts/setup-https.md

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

infra 인프라·배포·시크릿

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant