refactor: 문서 개선 중

This commit is contained in:
donghyeon-ka
2026-09-21 14:30:55 +09:00
parent c93cdea150
commit 805a18f486
1497 changed files with 525837 additions and 59152 deletions
@@ -7,7 +7,7 @@ topicName: 실험대 환경 구성
project: virtualization
status: 게시 전
questionStatus: OPEN
sourceRevision: 9465582b5d1630eb4ae7c4e078021486919bf6b6
sourceRevision: import-head 9465582b5d1630eb4ae7c4e078021486919bf6b6 · uncommitted-working-tree snapshot
source:
- final/document.md#183-이-부에서-파생될-open-question-oq-1
- final/document.md#180-nftables-는-앞-체인의-accept-로-뒤-체인의-reject-를-막지-못한다
@@ -6,8 +6,10 @@ topic: lab-environment-build
topicName: 실험대 환경 구성
project: virtualization
status: 게시 전
questionStatus: OPEN
sourceRevision: 9465582b5d1630eb4ae7c4e078021486919bf6b6
questionStatus: RESOLVED
sourceRevision: import-head 9465582b5d1630eb4ae7c4e078021486919bf6b6 · uncommitted-working-tree snapshot
evidence:
- ../../../final/evidence/raw/lab-state-before-rebuild/58-authenticator-and-token.txt
source:
- final/document.md#204-재구축할-때-무엇이-남아-있나
- final/document.md#266-dns-01-은-언제-쓰는가-네-가지-경우
@@ -16,100 +18,75 @@ source:
# 이 실험대의 certbot 은 HTTP-01 로 받고 있는가 DNS-01 로 받고 있는가
어느 방식으로 받고 있는지 아직 읽지 못했다. §266 의 결론과 §190 은 DNS-01 을 가리키는데 원본 가이드 04 는 HTTP-01 로 적혀 있다. `authenticator` 한 값이면 갈리지만 호스트의 `sudo` 가 비밀번호를 요구해 비대화식으로 못 읽었다.
2026-09-17 renewal 설정을 직접 읽으면서 답이 나왔다. `authenticator = dns-cloudflare` 였다. 따라서 이 실험대의 certbot은 DNS-01로 등록되어 있다(observed). 이전에 HTTP-01과 DNS-01 중 어느 쪽인지 열어 둔 상태는 닫는다.
## 관계
- **인증서는 DNS-01 로 받는다 — 실험대 주소가 공개 인터넷에 없어 HTTP-01 이 성립하지 않는다**
결정이 적은 것이 의도인지 이 호스트의 실제 설정인지를 이 물음이 가른다.
- **DNS-01 으로 와일드카드 인증서를 받고 갱신이 서빙까지 닿게 한다**
그 절차가 `--dns-cloudflare` 로 받는 길을 적는다. 이 호스트가 그 길로 받았는지는 확인하지 않았다.
- **실험대를 철거하고 무엇이 남는지 확인한다**
그 절차의 「인증서를 지우지 않는다」가 이 물음의 답에 걸려 있다.
- **갱신은 매번 SUCCESS 였고 옛 인증서가 계속 나갔다 — 2305초와 1~2초**
갱신은 됐는데 서빙까지 안 간 사건이다. 이 물음이 캐는 것은 갱신 자체가 도는지다.
- **공개 터널을 쓰지 않고 tailnet 직결로 둔다 — 홉이 하나 늘면 재려던 계약이 오염된다**
공개 인터넷에서 이 호스트에 닿을 길을 두지 않기로 한 결정이고, HTTP-01 이 성립하지 않는 조건 결정이 만든다.
- **가이드대로 다시 쳐서 이 실험대가 같은 상태로 서는가**
그 물음이 재는 7단계 가운데 04 의 통과 조건이 이 답으로 확정된다.
- 인증서는 DNS-01 로 받는다 — 실험대 주소가 공개 인터넷에 없어 HTTP-01 이 성립하지 않는다
결정이 설계 의도만 적은 것이 아니라 현재 실험대의 등록 상태와도 일치한다는 것이 확인됐다.
- DNS-01 으로 와일드카드 인증서를 받고 갱신이 서빙까지 닿게 한다
renewal 설정의 `authenticator`와 자격증명 경로를 실제 출력으로 확인한 Setup이다.
- 실험대를 철거하고 무엇이 남는지 확인한다
검증 방식은 닫혔지만 현재 Cloudflare 자격증명이 재발급에 쓸 수 있는지는 별도 확인이 필요해 인증서 보존 판단에는 그 조건이 남는다.
- 갱신은 매번 SUCCESS 였고 옛 인증서가 계속 나갔다 — 2305초와 1~2초
이 질문은 발급·갱신 방식만 닫는다. 갱신된 파일을 nginx가 다시 읽는 문제는 그 Case의 범위다.
- 공개 터널을 쓰지 않고 tailnet 직결로 둔다 — 홉이 하나 늘면 재려던 계약이 오염된다
공개 인터넷에서 HTTP-01이 성립하지 않는 조건대로다.
- 가이드대로 다시 쳐서 이 실험대가 같은 상태로 서는가
7단계 중 04의 인증 방식 판정은 닫혔다. 재발급 자격증명과 dry-run 성공 여부는 별도 검증으로 남긴다.
## 사실
§266 이 문서 둘이 어긋나 있다고 직접 적었다. 그 절의 결론과 §190 은 DNS-01 을 가리킨다.
2026-09-17 `sudo sh -c` 안에서 `/etc/letsencrypt/renewal/*.conf`를 읽었다. 후속 원문에는 다음 세 줄이 남아 있다.
원본 가이드 `docs/guides/04-tls/README.md``certbot certonly --webroot` 로 적혀 있다. 전제도 공개 DNS 에 이름 셋이 이 호스트를 가리켜야 한다는 것이다.
- `authenticator = dns-cloudflare`
- `dns_cloudflare_credentials = /etc/letsencrypt/cloudflare.ini`
- `server = https://acme-v02.api.letsencrypt.org/directory`
`dig +short auth.hyeonworks.com``100.83.212.4` 를 낸다.
일반 셸에서 `sudo grep ... /etc/letsencrypt/renewal/*.conf`로 친 첫 시도는 zsh가 글로브를 sudo보다 먼저 펼치면서 `no matches found`로 실패했다. 그래서 `sudo sh -c` 안에서 글로브를 펼쳤다.
`100.64.0.0/10` 은 CGNAT(Carrier-Grade NAT, 통신사 공용 주소 변환)용 예약 대역이라 공개 인터넷에서 라우팅 자체가 안 된다. 방화벽을 여는 문제가 아니라 그 주소가 인터넷에 존재하지 않는다. 이것은 규격이고 이 실험대가 잰 값이 아니다.
같은 후속 원문에서 Cloudflare 자격증명 파일의 토큰 길이는 `0자`로 측정됐고 토큰 검증은 `Invalid request headers`로 실패했다. 따라서 DNS-01 등록확인됐지만 현재 자격증명이 유효하다고 확인된 것은 아니다.
`certbot plugins` 를 돌린 실측이 `dns-cloudflare` · `standalone` · `webroot` 세 줄을 냈으니 플러그인은 깔려 있다.
`auth.hyeonworks.com`은 tailnet 주소 `100.83.212.4`로 풀리고, 이 주소는 공개 인터넷에서 라우팅되지 않는 `100.64.0.0/10` 안이다. 이 조건 때문에 HTTP-01을 현재 진입 경로에 그대로 적용할 수 없다는 판단도 바뀌지 않는다.
§190 이 적은 발급 대상은 `-d hyeonworks.com -d '*.hyeonworks.com'` 이고 lineage 디렉터리`/etc/letsencrypt/live/hyeonworks.com/` 이다. 자격증명 파일은 `/etc/letsencrypt/cloudflare.ini` 이고 권한이 `600`다.
ACME 명세가 와일드카드를 DNS-01 로만 허용한다. 호스트 한 대에 파일을 놓는 것은 그 이름 하나를 통제한다는 증명이고, DNS 존의 TXT 레코드를 고칠 수 있다는 것은 도메인 전체를 통제한다는 증명이라 증명의 급이 다르다.
§204 가 이 항목을 「미측정」으로 적었다. 호스트의 `sudo` 가 비밀번호를 요구해 비대화식으로 읽지 못했다.
2026-09-17 현재 lineage는 `/etc/letsencrypt/live/auth.hyeonworks.com/`다. `/etc/letsencrypt/live/hyeonworks.com/`은 원본 가이드에 남은 known-wrong 경로였고, 그대로 `nginx -t`를 실행하면 certificate file not found로 실패했다.
## 가정
지금 서빙되는 인증서가 와일드카드라면 발급은 DNS-01 로 이뤄졌을 수밖에 없다. 다만 그 인증서가 실제로 와일드카드인지는 이 저장소에 출력으로 남아 있지 않다.
플러그인이 보인다는 것과 그것으로 받았다는 것을 같게 읽지 않는다. `certbot plugins` 는 설치된 것을 세지 무엇으로 발급했는지를 세지 않는다.
갱신이 돌고 있다는 것도 아직 확인이 아니다. §218 의 구축 완료 판정 기준이 `systemctl is-active nginx certbot-renew.timer``active active` 를 요구하지만, §190 은 `systemctl list-timers certbot-renew.timer` 의 실제 출력이 남아 있지 않다고 적는다.
갱신 설정이 발급 시점의 방식을 그대로 물려받았다고 전제한다. 발급 뒤에 누가 `renewal/*.conf` 를 손으로 고쳤다면 그 전제가 깨진다.
renewal 설정이 2026-09-17 관측 뒤에 수동으로 변경되지 않았다고 전제한다. 이후 설정을 바꾸면 이 기록의 “현재” 범위도 그 시점까지만 유효하다.
## 미지수
`/etc/letsencrypt/renewal/*.conf` `authenticator` 가 무엇인가.
이 질문의 핵심 미지수였던 `authenticator`는 해소됐다.
그 값이 `webroot``standalone` 이면 지금 갱신이 실제로 돌고 있는가. 검증이 성립하지 않는 주소에 HTTP-01 로 설정돼 있다면 갱신은 조용히 실패한다.
남은 미지수는 다른 판단에 속한다.
그 값이 `dns-cloudflare` 라면 `/etc/letsencrypt/cloudflare.ini` 든 토큰의 권한이 `존 하나 + DNS:Edit` 으로 좁혀져 있는가. §266 이 그 범위를 값으로 치르는 것이라고 적었는데, 이 호스트의 토큰이 실제로 그 범위인지는 SSOT 에 없다.
- `/etc/letsencrypt/cloudflare.ini`유효한 토큰을 다시 넣었는가.
- 그 토큰의 권한이 필요한 zone과 DNS 편집 범위로 좁혀져 있는가.
- 현재 `certbot renew --dry-run`이 성공하는가.
지금 서빙되는 인증서가 와일드카드인가, 그리고 lineage 이름이 무엇인가.
이 셋은 DNS-01인지 HTTP-01인지를 다시 여는 근거가 아니다. 재발급·갱신 가능성을 확인하는 후속 조건이다.
## 제약
호스트의 `sudo` 가 비밀번호를 요구해서 비대화식으로는 읽을 수 없고, 콘솔에서 쳐야 한다. 이것이 §204 가 미측정으로 남긴 까닭이다.
비밀 값은 증거에 남기지 않는다. 자격증명은 길이·존재 여부와 API 검증 결과까지만 기록한다.
비밀 값을 옮기지 않는다. `cloudflare.ini` 의 토큰은 길이와 존재 여부까지만 적고 값을 찍는 명령을 남기지 않는다.
Let's Encrypt 를 tailnet 에 초대할 방법이 없다. 검증 방식을 바꿔 가며 돌려 보는 실험으로 답을 대신할 수 없다.
발급 한도가 같은 이름 조합에 주당 중복 5장이다. 시험은 `--dry-run` 으로 먼저 한다.
`sudo`가 필요한 디렉터리의 글로브는 일반 사용자 셸에서 먼저 펼치지 않는다. 이 실험대에서는 그 방식이 실제로 실패했다.
## 선택지
### 1. 갱신 설정 파일을 콘솔에서 직접 읽는다
### 1. DNS-01 — 현재 관측과 일치
`authenticator` 한 값이 이 물음을 통째로 닫는다. 같은 콘솔 세션에서 쓸 수 있는 방식과 갱신 예행연습과 이름이 가리키는 주소까지 한 번에 찍어 같은 시각의 출력으로 묶는다. 값을 읽을 수 없는 경우는 파일이 없을 때뿐이고, 그때는 이 호스트가 인증서를 받은 적이 없다는 다른 답이다.
renewal 설정이 `dns-cloudflare`를 직접 가리킨다. 이 질문의 답이다.
### 2. 지금 서빙되는 인증서가 와일드카드인지부터 본다
### 2. HTTP-01 — 현재 관측과 불일치
`sudo` 없이도 밖에서 TLS 핸드셰이크만으로 도메인 목록을 볼 수 있다. 와일드카드로 나오면 발급이 DNS-01 이었다는 쪽으로 정황이 좁혀진다. 다만 좁혀질 뿐 `authenticator` 를 대신하지는 못한다. 발급은 와일드카드로 받고 갱신 설정만 다른 경우를 이 방법으로는 가르지 못한다.
### 3. 인증서를 지우고 다시 받아 본다 — 제외
다시 받아 보면 어느 방식이 성립하는지 바로 드러나지만, §204 가 「어느 쪽인지 모르는 채로는 지우지 않는다」로 그 순서를 막아 두었다. HTTP-01 로 설정돼 있으면 재발급이 안 되고, 그러면 재구축을 시작하자마자 검증 방식부터 손봐야 한다. 답을 얻으려고 답이 필요한 상태를 만드는 순서다.
원본 가이드 04에는 `--webroot` 경로가 남아 있었지만, 현재 renewal 설정이 그것을 사용한다는 증거는 없다. historical document branch로만 남긴다.
## 다음 검증
§204 와 §266 이 적은 네 줄을 호스트 콘솔에서 그대로 친다.
이 Question은 RESOLVED다. `authenticator`를 다시 읽는 것은 질문을 닫기 위한 검증이 아니라 설정 변경 감시다.
1. `sudo grep -H authenticator /etc/letsencrypt/renewal/*.conf` 으로 검증 방식을 읽는다.
2. `certbot plugins` 를 돌려 앞에 `*` 가 붙은 줄을 적는다.
3. `sudo certbot renew --dry-run` 으로 갱신이 실제로 되는지 본다.
4. `dig +short auth.hyeonworks.com` 으로 Let's Encrypt 가 올 수 있는 주소인지를 같은 시각에 함께 남긴다.
5. 지금 서빙되는 인증서가 와일드카드인지와 lineage 이름이 무엇인지를 `certbot certificates` 의 도메인 목록으로 적는다.
6. 출력 원문을 `final/evidence/raw/` 에 남기고 `meta/` 에 명령과 cwd 와 실행 시각과 종료 코드를 적는다. `cloudflare.ini` 의 토큰 값은 찍지 않는다.
재발급 가능성을 확인하려면 유효한 Cloudflare 자격증명을 준비한 뒤 `sudo certbot renew --dry-run`을 별도 검증한다. 그 결과가 실패하더라도 이 Question을 다시 `OPEN`으로 돌리지 않는다. 실패 원인은 자격증명·DNS 권한·ACME 경로 쪽의 새 문제로 분리한다.
닫는 조건 : `authenticator` 한 값과 `--dry-run` 결과가 나오면 닫는다.
`dns-cloudflare` 면 「인증서는 DNS-01 로 받는다」가 이 호스트의 현재 상태를 적은 것으로 확인되고, 철거 절차의 「인증서를 지우지 않는다」가 정책에서 선택으로 바뀐다. §204 가 적은 대로 그때는 백업이 헛수고이므로 지워도 되고 재구축 절차가 한 단계 짧아진다.
`webroot``standalone` 이면 그 결정이 적은 것은 의도이고 실제 설정은 다른 것이므로, §190 과 가이드 04 가운데 어느 쪽이 실재인지를 먼저 고친 뒤 그 기록을 다시 판정한다.
`--dry-run` 이 실패하면 갱신이 이미 멈춰 있다는 뜻이라 그 자체가 새 Case 다. 「갱신은 매번 SUCCESS 였고 옛 인증서가 계속 나갔다」가 갱신은 되는데 서빙까지 안 간 것을 다뤘다면, 이번 것은 갱신 자체가 안 되는 쪽이고 증상이 또 조용하다.
닫는 조건 : 2026-09-17 raw evidence에서 `authenticator = dns-cloudflare`가 직접 관측되어 충족됐다.
@@ -7,7 +7,7 @@ topicName: 실험대 환경 구성
project: virtualization
status: 게시 전
questionStatus: OPEN
sourceRevision: 9465582b5d1630eb4ae7c4e078021486919bf6b6
sourceRevision: import-head 9465582b5d1630eb4ae7c4e078021486919bf6b6 · uncommitted-working-tree snapshot
source:
- final/document.md#183-이-부에서-파생될-open-question-oq-3
- final/document.md#181-qcow2-가-담는-것과-담지-않는-것
@@ -7,7 +7,7 @@ topicName: 실험대 환경 구성
project: virtualization
status: 게시 전
questionStatus: OPEN
sourceRevision: 9465582b5d1630eb4ae7c4e078021486919bf6b6
sourceRevision: import-head 9465582b5d1630eb4ae7c4e078021486919bf6b6 · uncommitted-working-tree snapshot
source:
- final/document.md#183-이-부에서-파생될-open-question-oq-2
- final/document.md#181-qcow2-가-담는-것과-담지-않는-것