현재 테스트 중입니다: 완료되면 GitHub 코드를 오픈할 예정입니다.

접속 수립 · 인증

피어 간 연결은 cluster_raft_self로 명시한 Raft 전용 주소에서 수립됩니다. TCP/TLS와 challenge- response 인증까지는 클라이언트 포트와 같지만, 인증 직후에는 Raft 전용 peer hello가 추가됩니다.

  1. TCP 접속 — 항상 부르는(dial) 쪽이 요청자가 됩니다
  2. 서버가 TLS를 켰다면 TLS 핸드셰이크
  3. 인증 핸드셰이크 1회 — 규격(challenge·digest·응답)은 클라이언트 포트와 바이트 단위로 동일합니다
  4. 고정 peer hello를 요청→응답 순서로 교환하고 identity와 wire version을 exact 검증
  5. 이후 길이-프리픽스 RPC 교환

peer hello

인증 성공 직후 아래 64바이트 고정 header와 두 UTF-8 가변 필드를 교환합니다. postcard와 OpenRaft 타입에 의존하지 않는 영구 envelope이며, 이 검증이 끝나기 전에는 RPC tag 1..4, 16을 허용하지 않습니다.

필드크기값/규칙
magic8ASCII TCKRAFT1
cluster_wire_versionu16 BE현재 1, exact match
flagsu16 BE현재 0, 다른 값 거부
source_node_idu64 BE보내는 process의 active NodeId
target_node_idu64 BE연결 대상의 active NodeId
source_incarnationu128 BE보내는 process의 고유 incarnation
target_incarnationu128 BE연결 대상의 고유 incarnation
cluster_id_lenu16 BE1..128
server_version_lenu16 BE1..64
cluster_id가변같은 fencing domain인지 exact 검증
server_version가변관측용; 값이 달라도 이것만으로 거부하지 않음

전체 hello는 최대 256바이트입니다. dial 쪽이 먼저 보내고 accept 쪽이 source/target NodeId와 incarnation을 반대로 둔 같은 구조로 답합니다. magic, wire version, flags, cluster ID, source/target NodeId와 incarnation 중 하나라도 기대값과 다르면 즉시 연결을 닫습니다. SERVER_VERSION은 로그와 metric용일 뿐 호환 판단에는 사용하지 않습니다.

CLUSTER_WIRE_VERSION은 framing byte뿐 아니라 Grant/Expire/token/membership/snapshot의 복제 의미가 달라질 때도 올립니다. 서로 다른 wire version을 섞은 rolling upgrade는 지원하지 않으며, 호환되지 않는 변경은 lease drain 뒤 새 cluster_id로 배포합니다.

흐름

부르는 노드 (dial)
받는 노드
TCP 접속 (cluster_raft_self)
서버가 TLS를 켰다면 TLS 핸드셰이크
challenge (SHA-256 ␣ nonce)
digest — cluster_tokens의 첫 번째 토큰으로 계산
검증은 cluster_tokens 목록 전체로
peer hello — wire 1 · cluster/NodeId/incarnation
peer hello — source/target을 반대로 응답
이후 길이-프리픽스 Raft RPC 교환
요청응답합의 RPC (Raft)

클라이언트 포트와 다른 점

항목클라이언트 포트Raft 포트
검증 토큰 집합client_tokenscluster_tokens
보내는 쪽 토큰클라이언트가 설정한 토큰cluster_tokens첫 번째 토큰
인증 이후\n 종결 프레임peer hello 뒤 길이-프리픽스 RPC
  • cluster_tokens는 비어 있지 않아야 하며 핸드셰이크에서 항상 검증합니다. 토큰 변경은 동일한 CLUSTER_WIRE_VERSION과 replicated semantics를 유지한 상태에서 새 NodeId learner 교체 절차로 수행합니다 (설정 (환경변수)).
  • TLS가 켜져 있으면 Raft 포트도 같은 인증서를 씁니다. 피어를 부르는 쪽은 상대 인증서를 tls_ca(없으면 시스템 신뢰 저장소)로 검증하며, tls_skip_verify는 테스트 전용입니다.
  • 인증 실패 시 E auth_failed 후 연결이 닫힙니다. peer hello의 mismatch·부분 전송·timeout도 응답 stream을 재사용하지 않고 닫습니다.