HAL 0.4.1: 서버 등록 TLS 수정·"이미 등록된 서버" 안내, HAL 배포가 HAL 서버의 Node Agent·HawkEye 를 함께 설치해 부트스트랩을 닫음
- hal/tls.mjs: 공개 주소 TLS 신뢰 확인(시스템 CA → 실패면 체인·공개키 핀), 신뢰 앵커(체인 자체 서명 / <data>/tls/hal-ca.pem), 10분 캐시, 핀 설치 명령(curl -k --pinnedpubkey … --hal-pin). 공개 경로 GET /agent/v1/hal-ca.pem · /agent/v1/tls, CLI tls-probe
- deploy/agent-install.sh: --hal-pin(핀으로 CA 받기)·--ca·--insecure, curl --cacert / Node NODE_EXTRA_CA_CERTS / register --ca / 유닛 Environment, 연결 실패 원인·조치 한 줄, 이미 등록된 서버 안내
- agent/halca.mjs + agent/index.mjs·config.mjs: caFile 런타임 적용(tls.setDefaultCACertificates), fetch 실패를 읽을 수 있는 한 줄로(종료 1), 이미 등록(종료 2, --force), HAL 거부(종료 3), heartbeat observability → hawkeye
- core.registerAgent: 같은 서버의 두 번째 토큰 409 server_already_registered / 쓴 토큰 409 token_used("이미 등록된 서버"), 거부 토큰 미소비, 재등록 허용(replace: 기존 Agent 해지, 감사 agent.replace), 마이그레이션 hal_0011_token_replace, API/CLI --replace --json(재인증), ops.js 재등록 확인·핀 안내
- deploy/hal-host-agent.sh(server-create --profile hal → server-token --json → agent-install loopback → server-approve), bootstrap-hal.sh 6/7 단계(--no-agent), CLI server-create·server-approve, SERVER_PROFILES.hal
- core.deploymentStatus/selfHealth.deployment, 배너 "부트스트랩 완료 · 기능 단위 서버 배포 대기: …" / "진행 중", 배포 릴리스 화면 문구, heartbeat canonicalModuleName(0.3.17 잔여 결함)
- 개발 지시 v0.4.1(Oz)·VERSION_HISTORY 0.4.1·README·docs/HAL-AGENT §6·RUNBOOK §11·AI 스킬, 도입 모듈 변경 없음(Webmaker 1.9.0·AriMail 1.1.0)
- test/hal-041.test.mjs RED → GREEN 7/7(실제 자체 서명 TLS 픽스처·별도 프로세스 CLI), 기존 배너·프로필·버전 테스트 갱신, 전체 32파일 통과, 로컬 E2E 보고서 2026-11-06
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
0f5e01a4cb
commit
2b31543a86
+13
-1
@@ -21,6 +21,8 @@ Dev-Order §5(아키텍처)·§28·§29·§32·§33·§34 의 백엔드 구현.
|
||||
| 경로 | 설명 |
|
||||
|---|---|
|
||||
| `GET install.sh` | 설치 스크립트(deploy/agent-install.sh) |
|
||||
| `GET hal-ca.pem` | [0.4.1] HAL 공개 주소가 사설 CA·자체 서명일 때의 신뢰 앵커 PEM(공개, 무서명). 시스템 CA 로 신뢰되면 404 `no_private_ca` |
|
||||
| `GET tls` | [0.4.1] 공개 주소 TLS 신뢰 상태(trusted·reason·pin·caAvailable, `?refresh=1`) |
|
||||
| `GET bootstrap-artifact?module=agent&version=` + `X-Registration-Token` | 등록 전 Agent 코드 내려받기(유효 토큰 확인, 소비하지 않음) |
|
||||
| `POST register {token, facts, version}` | 일회용 토큰(10분) → `{agentId, secret(1회), serverId, kind, siteId}` |
|
||||
| `POST heartbeat {version, metrics, modules, clockSkewMs, facts, sitesHosted}` | 지표 저장(90일+), 서버 last_seen·용량·모듈 실제 버전 갱신. 90초 무응답 → offline |
|
||||
@@ -51,7 +53,17 @@ scp -r dist/0.1.1 hostinger:/tmp/ariweb-dist
|
||||
# 대상 서버(ariweb.net 호스트, master, sudo):
|
||||
bash /tmp/ariweb-dist/… (artifact 안의 deploy/bootstrap-hal.sh) --dist /tmp/ariweb-dist --host hal.ariweb.net --cert /etc/letsencrypt/live/wh-wild-ariweb.net
|
||||
```
|
||||
부트스트랩은 HAL 설치·보관소·유닛·nginx·릴리스 등록(승인)·운영자 설정 토큰까지만 한다. 이어서 운영자 계정 생성 → 서버 생성·등록 토큰 → `agent-install.sh` → 서버 승인. 첫 Agent 승인 시 `bootstrap_state.completed_at` 이 기록되고 수동 설치가 잠긴다. 그 뒤 `portal`·`webmaker`·`arimail` 은 운영자 API `POST /ops/api/modules/<name>/deploy {version, serverIds}` 로 배포한다.
|
||||
[0.4.1] 부트스트랩은 HAL 설치·보관소·유닛·nginx·릴리스 등록(승인)에 이어 **이 서버의 Node Agent·HawkEye 를 함께 설치·등록·승인**해 부트스트랩을 닫는다(`deploy/hal-host-agent.sh`: `server-create --profile hal` → `server-token --json` → `agent-install.sh --hal http://127.0.0.1:8900 --role control`(loopback, DNS·인증서 무관) → `server-approve`). 그래서 설치 직후 운영자 콘솔은 "부트스트랩 미완료" 가 아니라 "부트스트랩 완료 · 기능 단위 서버 배포 대기: 고객 포털, Webmaker, AriMail, 백업" 을 보인다(`/api/health.deployment.pending`). Web·Mail·Backup·Portal 은 설치하지 않는다 — 역할별 통합 배포(새 서버)로 추가한다. 0.4.0 이하로 설치된 HAL 서버는 `cd /srv/ariweb/hal/current && bash deploy/hal-host-agent.sh` 를 한 번 실행한다(`--no-agent` 로 부트스트랩하면 이전처럼 첫 Agent 승인 때 닫힌다). 마지막에 운영자 설정 토큰을 낸다.
|
||||
|
||||
**사설 CA·자체 서명 인증서로 HAL 을 운영할 때(0.4.1)**: HAL 은 기동 때와 토큰 발급 때 자기 공개 주소에 접속해 시스템 CA 신뢰 여부를 확인한다(`hal/tls.mjs`, CLI `node hal/index.mjs tls-probe`). 신뢰되지 않으면 운영자 콘솔이 만드는 설치 명령에 서버 공개키 핀이 붙는다:
|
||||
```
|
||||
curl -fsSL -k --pinnedpubkey 'sha256//…' https://hal.local.test/agent/v1/install.sh | bash -s -- --hal https://hal.local.test --token … --hal-pin 'sha256//…'
|
||||
```
|
||||
`-k` 는 CA 검증만 끄고 `--pinnedpubkey` 는 서버 공개키가 핀과 다르면 자료를 받기 전에 끊는다. 스크립트는 같은 핀으로 `GET /agent/v1/hal-ca.pem`(체인 안의 자체 서명 인증서, 또는 HAL 서버의 `<data>/tls/hal-ca.pem` 이 있으면 그 파일)을 받아 `<app-dir>/data/hal-ca.pem` 에 두고, 이후 curl 은 `--cacert`, Node 는 `NODE_EXTRA_CA_CERTS` + `agent.json caFile`(Agent 가 기동 때 `tls.setDefaultCACertificates` 로 더함), 유닛은 `Environment=NODE_EXTRA_CA_CERTS=…` 로 같은 CA 를 쓴다. 운영자가 CA 파일을 직접 줄 때는 `--ca <pem>`. 루트를 체인에 싣지 않는 사설 CA 는 HAL 서버에 `<data>/tls/hal-ca.pem` 을 두면 된다.
|
||||
|
||||
**이미 등록된 서버(0.4.1)**: 같은 서버에 두 번째 토큰으로 등록하면 HAL 이 409 `server_already_registered`("이미 등록된 서버입니다(서버·Agent·등록 시각) — 다시 설치할 필요가 없습니다") 로 거부하고 토큰을 소비하지 않는다. 쓴 토큰을 다시 쓰면 409 `token_used` 에 같은 문구. 설치 스크립트는 `agent.json` 이 있으면 등록을 건너뛰고 "이미 등록된 서버" 를 안내한다. 서버를 다시 설치해 새 Agent 로 바꾸려면 운영자 콘솔 › 서버 › 등록 토큰에서 "재등록 허용"(재인증) 토큰을 발급한다 — 기존 Agent 는 해지된다(CLI `server-token --server <id> --replace`). Agent 쪽 연결 오류는 스택 대신 원인·조치 한 줄로 나온다(`등록 실패: HAL(…) 인증서를 확인할 수 없습니다(SELF_SIGNED_CERT_IN_CHAIN) — …`).
|
||||
|
||||
그 뒤 `portal`·`webmaker`·`arimail` 은 운영자 API `POST /ops/api/modules/<name>/deploy {version, serverIds}` 또는 역할별 통합 배포로 배포한다.
|
||||
|
||||
도입 모듈 배치: Agent facts 가 서버의 기존 유닛(`webmaker`, `arihakdang-mail`/`arimail`/`heart-mail`)과 WorkingDirectory 를 읽어 그 appDir(`/srv/webmaker`, `/srv/arihakdang-mail` …)의 `releases/<ver>` 에 풀고 `current` 를 바꾼다. Webmaker 는 원본 `remote-update.sh` 순서(데이터 백업 → 교체 → 재시작 → unit-check), AriMail 은 원본 `deploy.sh` 순서(DB 백업 → 교체 → db-migrate → 재시작 → health → haraka 재시작)를 Agent 가 수행한다.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user