5.7 KiB
kind, slug, title, topic, topicName, project, status, decisionStatus, sourceRevision, source
| kind | slug | title | topic | topicName | project | status | decisionStatus | sourceRevision | source | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| PROJECT_DECISION | no-public-tunnel-because-a-third-hop-pollutes-the-measurement | 공개 터널을 쓰지 않고 tailnet 직결로 둔다 — 홉이 하나 늘면 재려던 계약이 오염된다 | lab-entry-path-and-measurement-integrity | 실험대의 진입 경로 | virtualization | 게시 전 | ADOPTED | import-head 9465582b5d1630eb4ae7c4e078021486919bf6b6 · uncommitted-working-tree snapshot |
|
공개 터널을 쓰지 않고 tailnet 직결로 둔다 — 홉이 하나 늘면 재려던 계약이 오염된다
Cloudflare named tunnel 을 앞에 붙이면 브라우저에서 파드까지가 3홉이 되고, 이 실험대가 재려는 것이 정확히 2홉의 forwarded 헤더 계약이라 측정이 오염된다. 그래서 tailnet 직결로 두고 터널 설정 파일은 채택하지 않은 선택지로 남긴다.
근거
§305 가 deploy/ 아래의 tunnel/cloudflared-config.yml 을 두고 채택하지 않았다고 적으면서 기각 이유를 전후 홉 그림으로 남겼다. 기각한 파일을 지우지 않는 방침은 §300 부터 §302 에 따로 있다. 저장소에 있으나 적용되지 않는 설정이 여럿인데, 그것들이 죽은 코드가 아니라 의도적으로 남겨 둔 참조 자산이라고 전체 지도와 함께 적는다.
- L7 이 두 겹인 이유와, 진입점 하나를 이중화하려 할 때 끝나지 않는 재귀 이 결정이 지키려는 2홉이 무엇이고 그 둘의 역할이 왜 다른지를 그 글이 설명한다.
- 신뢰 경계에서는 forwarded 헤더를 덧붙이지 않고 덮어쓴다 앞에 한 겹이 더 붙으면 경계가 Cloudflare 엣지로 옮겨 가 그 기준을 거기서 다시 세워야 한다.
- 인증서는 DNS-01 로 받는다 — 실험대 주소가 공개 인터넷에 없어 HTTP-01 이 성립하지 않는다 이 결정이 청구한 비용 하나를 그 결정이 받는다.
- 엣지 nginx 를 호스트에서 게스트 VM 으로 옮긴다 — 성능이 아니라 더러워지는 층의 격리 같은 2홉을 지킨 채 엣지의 위치만 바꾼 결정이라 홉 수를 건드리지 않는다.
- 이 실험대의 certbot 은 HTTP-01 로 받고 있는가 DNS-01 로 받고 있는가
이 물음은 2026-09-17
dns-cloudflare관측으로 닫혔다. 남은 것은 현재 Cloudflare 자격증명이 실제 재발급에 쓸 수 있는지다.
결정문
공개 터널을 쓰지 않고 tailnet 직결로 둔다. 기각한 설정 파일 tunnel/cloudflared-config.yml 은 지우지 않고 채택하지 않은 선택지로 남긴다.
조건이 바뀌어 공개 접근이 필요해지면(예를 들어 다른 회선으로 이전) 그 파일을 그대로 쓴다.
판단 이유
Cloudflare named tunnel 은 아웃바운드 연결만 쓰므로 포트포워딩 없이 공개 HTTPS 이름을 얻는다. 공유기를 건드릴 수 없는 환경에서는 매력적인 선택지이고, §305 는 그 설정의 함정 둘까지 적어 두었다. service: 에 127.0.0.1 을 쓰면 cloudflared 컨테이너 자신을 가리키므로 Compose 서비스 DNS 이름을 써야 하고, 마지막 catch-all 이 없으면 오류가 난다.
기각 근거는 홉 수다. 터널을 쓰면 브라우저가 Cloudflare 엣지와 nginx 와 Traefik 을 지나 파드에 닿아 3홉이 된다. 지금은 브라우저가 nginx 와 Traefik 만 지나 파드에 닿는 2홉이다. Cloudflare 엣지가 TLS 를 끊고 다시 맺으면서 HTTP 를 읽는 홉이 하나 늘고 CF-Connecting-IP 같은 자체 헤더가 섞인다. 이 실험대가 측정하려는 것이 정확히 nginx → Traefik 2홉의 forwarded 헤더 계약이므로, 앞에 한 겹이 더 붙으면 측정이 오염된다.
터널이 무엇을 해 주는지가 아니라 그것이 이 실험대의 측정 대상에 무엇을 하는지를 보고 정했다.
영향
진입 경로가 2홉으로 고정된다. 밖에서 들어오는 요청을 처음 받는 프록시가 하나뿐이라 신뢰 경계가 한 곳이고, forwarded 헤더를 누가 쓰는지가 갈리지 않는다.
감수한 비용은 진입 주소다. dig 가 내놓는 100.83.212.4 는 100.64.0.0/10 안에 있고 그 대역이 CGNAT 용으로 예약돼 있어 공개 인터넷에서 라우팅되지 않는다.
그 대가가 두 곳에서 청구됐다.
인증서 발급 : HTTP-01 로 받을 수 없어 DNS-01 로 갔다
재구축 : DNS-01 등록은 확인됐지만 Cloudflare 자격증명 유효성과 dry-run 성공을 확인하기 전에는 /etc/letsencrypt/ 를 보존한다
기각한 파일을 지우지 않는 방침에도 근거가 셋 있다.
① 저장소의 목적이 비교다 : 선택지를 나란히 두고 트레이드오프를 적는 것 자체가 산출물이라, 하나만 남기면 왜 이것을 골랐는지를 뒷받침할 근거가 없어진다
② 죽은 코드가 아니라 테스트되는 코드다 : scripts/verify-public-tunnel-config.sh 가 붙어 있어 실행되지 않을 뿐 깨지면 드러난다
③ 실험대 전용 설정은 lab/ 아래로 분리했다 : 일반 배포 설정과 섞이지 않는다
재지 않은 것도 있다. 터널을 붙인 상태와 지금을 같은 방법으로 잰 비교는 이 저장소에 없다. 기각의 근거는 홉 수와 섞이는 헤더이지 두 구성을 재서 견준 값이 아니다. 인증 방식은 2026-09-17 dns-cloudflare 로 확인됐다. 다만 같은 후속 원문에서 Cloudflare 토큰 길이는 0자로 측정돼 재발급 가능성까지 확인된 것은 아니다.