노드 탐색과 암호화된 멀티홉 릴레이
AeroNyx 노드가 서명된 디스크립터로 서로를 탐색하고, 미러링된 Directory Chain을 보관하며, 계층화된 암호화 페이로드를 홉 단위로 전달하는 방식을 설명합니다. 실제 채팅은 기본적으로 중앙 릴레이를 사용하며, 2홉 어니언 경로는 옵트인입니다.
AeroNyx 노드는 서명되고 만료 기한이 있는 디스크립터를 통해 서로를 찾으며, 종단 간 암호화된 페이로드를 홉 단위로 전달할 수 있습니다. 이때 각 릴레이는 자기 암호화 계층만 벗깁니다. 현재 실제 사용자 채팅은 기본적으로 AeroNyx 중앙 릴레이(RelayWS)를 거칩니다. 노드를 통한 채팅 라우팅은 앱에서 사용자가 직접 켜는 옵트인 설정입니다.
현재 운영 중인 것
| 기능 | 상태 |
|---|---|
| 서명된 노드 탐색과 피어 가십 | 프로덕션 노드에서 운영 중 |
| Directory Chain(노드별로 서명된 디스크립터 이력, 노드 간 미러링) | 프로덕션 노드에서 운영 중 |
| 노드 간 2홉 어니언 릴레이 | 프로덕션 노드에서 운영 중. 앱에서는 옵트인이며 기본값은 꺼짐 |
| 어니언 릴레이를 통해 접근하는 익명 메일박스 | 프로덕션 노드에서 작동 중. 일반 채팅은 사용하지 않음. 앱에는 별도의 베타 메일박스 드롭이 있음 |
| 릴레이 홉이 3개인 경로 | 정책과 프로브가 노드 소스에 존재함. 앱은 사용하지 않음 |
게이트웨이 뒤에 있는 노드를 위한 https:// 호스트 이름 엔드포인트 | 현재 노드 릴리스에 포함 |
| 공개 API 포트의 신원 결합 TLS(도메인 이름과 인증 기관 불필요) | 프로덕션 노드에서 운영 중. 피어가 지원을 알리면 노드끼리 이를 사용함. 앱 지원은 개발 중 |
| 어니언 종단 노드에서 수신자의 릴레이 수신함으로의 핸드오프 | 프로덕션 노드에서 운영 중 |
운영자가 고정하는 시드(discovery.pinned_seeds) | 현재 노드 릴리스에 포함 |
| 기본 채팅 전송 방식 | AeroNyx가 운영하는 중앙 RelayWS 서비스 |
중앙화 경로와 탈중앙화 경로가 나란히 운영됩니다.
탐색의 작동 방식
각 노드는 자신의 Ed25519 신원 키로 서명한 디스크립터를 공개합니다. 디스크립터에는 노드 ID, 발급 및 만료 시각, 선택 사항인 공개 엔드포인트, 기능 플래그(예: 어니언 중간 릴레이 또는 채팅 릴레이), 대략적인 용량 힌트, 어니언 암호화에 사용하는 키가 포함됩니다. 노드는 만료되었거나 서명이 유효하지 않은 디스크립터를 거부합니다.
- 가십은 제한됩니다. 피어 교환은 속도가 제한되고 정책에 따라 통제되며, 메시지에는 크기 제한이 있습니다.
- 재시작 복구. 노드는 로컬 피어 캐시를 보관하며, 재시작 후에는 설정된 시드 엔드포인트로 대체합니다. 운영자는 시드를 고정할 수도 있습니다.
- 경로 선택. 사용 가능한 엔드포인트와 어니언 키를 갖춘 최신 디스크립터만 릴레이 후보로 고려됩니다.
디스크립터에 지정할 수 있는 엔드포인트
서명은 누가 디스크립터를 공개했는지를 증명할 뿐, 그 엔드포인트에 접속해도 안전하다는 것을 증명하지는 않습니다. 따라서 노드는 두 가지 형식의 엔드포인트만 허용합니다.
http또는https를 통한 공인 IP 주소. 루프백, 사설, 링크 로컬, CGNAT, 문서용, 멀티캐스트, 예약 대역은 거부됩니다.- 공개 DNS 이름을 사용하는
https://URL. 단일 레이블 이름,localhost, 그리고.local,.internal,.home.arpa같은 사설 접미사는 거부됩니다.
호스트 이름은 접속 시점에 공인 주소가 아닌 모든 주소를 버리는 리졸버를 통해 해석되므로, 이름이 노드 자신, 사설 네트워크 또는 클라우드 메타데이터 서비스를 가리키도록 할 수 없습니다. 피어 클라이언트는 프록시 설정도 무시하며 리디렉션을 절대 따르지 않습니다.
호스트 이름 형식은 클라우드 게이트웨이 뒤에 있는 TEE 노드처럼 자체 IP 주소가 없는 노드도 참여할 수 있도록 하기 위해 존재합니다.
고정 시드
운영자 스냅숏 없이 시작한 노드는 이미 가지고 있는 신원만 신뢰하므로, 결국 자기 자신만 신뢰하게 될 수 있습니다. 이런 경우를 위해 운영자는 특정 주소에서 기대하는 신원을 지정할 수 있습니다.
[discovery]
pinned_seeds = ["<64-hex node id>@<public ip>:<port>"]
- 고정된 신원은 그 신원에 고정된 신원 결합 TLS로 교환을 마친 뒤에야 처음으로 받아들여집니다.
- 고정된 신원의 이후 모든 디스크립터는 어떤 경로로 오든 고정된 주소를 유지하고 신원 결합 TLS를 알려야 합니다.
- 신뢰는 전파되지 않습니다. 시드의 응답에 들어 있는 다른 디스크립터는 계속 신뢰할 수 없는 후보로 남습니다.
- 제거된 고정 설정은 오래된 캐시나 백업에서 되살아날 수 없습니다.
Directory Chain
각 노드는 자기 디스크립터 이벤트에 대해 서명되고 해시로 연결된 이력도 보관하며, 이를 해당 노드의 Directory Chain이라고 합니다. 다른 노드는 그 이력을 미러링하고, 디스크립터 객체를 가져오고, 특정 디스크립터에 대한 포함 증명을 요청할 수 있습니다. 운영자가 고정한 피어는 자신이 본 이력에 대해 관찰 체크포인트에 서명할 수 있습니다.
전역 원장도, 단일 코디네이터도 없습니다. 각 노드가 자기 이력에 서명하고, 다른 노드가 이를 미러링하고 확인합니다.
신원 결합 TLS
HTTPS로 노드에 접속하려면 보통 도메인 이름과 인증 기관이 발급한 인증서가 필요한데, 대부분의 AeroNyx 노드는 IP 주소로만 접근할 수 있습니다. 그래서 노드는 자신의 Ed25519 신원으로 자기 HTTPS 엔드포인트를 증명합니다.
- 작동 방식. 노드는 일반적인 ECDSA P-256 TLS 키와 자체 서명 인증서를 만듭니다. 주체 대체 이름(subject alternative name) 하나에 바인딩
aeronyx-tls-binding:v1:<node id>:<expiry>:<signature>가 들어 있으며, 이 서명은 인증서 자체의 공개 키, 노드 ID, 만료 시각에 대한 도메인 분리 다이제스트에 노드 신원 키로 만든 것입니다. TLS 1.3 핸드셰이크는 노드가 인증서 키를 가지고 있음을 증명합니다. 신원 키가 핸드셰이크에 서명하는 일은 없습니다. - 클라이언트가 확인하는 것. 검증자는 자신이 접속하려던 노드의 인증서만 받아들입니다. 구체적으로 바인딩이 정확히 하나 있어야 하고, 기대한 노드 ID여야 하며, 만료되지 않아야 하고, 남은 유효 기간이 최대 31일이어야 하며, 이 인증서의 키에 대한 서명이 유효해야 합니다. 인증 기관이 발급한 인증서는 이 확인을 충족하지 못합니다.
- 같은 포트. 공개 API 포트(
8422/TCP)는 둘 다 제공합니다. TLS 핸드셰이크로 시작하는 연결에는 TLS로 응답하고, 그 외에는 예전처럼 일반 HTTP로 응답합니다. 기본값은 켜짐입니다(discovery.public_api_identity_tls). - 노드 간. 서명된 디스크립터가 프로토콜 기능
anpf1-ibt1을 알리는 노드는 신원 결합 TLS를 제공합니다. 이 기능을 확인한 피어는 그 노드의 신원에 고정된 TLS로 접속해야 하며 일반 HTTP로 되돌아가지 않습니다. 이 기능은 디스크립터 서명의 적용 대상이므로, 네트워크 공격자가 이를 제거해 다운그레이드를 강제할 수 없습니다. 여러 신원이 같은 엔드포인트를 주장하면 TLS 주소가 만들어지지 않고 요청은 안전한 쪽으로 실패합니다. 이 기능이 없는 이전 노드와 DNS 이름을 쓰는 게이트웨이 엔드포인트는 기존 동작을 유지합니다. - 참조. 소스와 고정된 테스트 벡터: aeronyx-node-tls.
그 결과 노드 간 어니언 홉의 경로 정보, 가십, 디렉터리 동기화, 위트니스 트래픽을 네트워크 구간에서 읽을 수 없게 됩니다. 이 방식으로 노드에 접속하는 앱 지원은 개발 중입니다.
멀티홉 릴레이의 작동 방식
- 발신자는 각 릴레이가 공개한 어니언 키를 사용해 페이로드를 홉마다 하나씩 암호화 계층으로 감쌉니다.
- 각 릴레이는 이전 홉의 서명, 타임스탬프, 재전송 상태를 확인하고, 자기 계층을 벗긴 뒤 남은 불투명한 블롭을 전달합니다. 안쪽 계층은 절대 보지 않습니다.
- 최종(종단) 노드는 메시지를 수신자의 릴레이 수신함(기본값은 중앙 릴레이)으로 핸드오프하고, 릴레이가 받아들인 뒤에만 서명된 수신 확인을 반환합니다. 수신 확인은 경로 ID, 페이로드에 대한 커밋먼트, 종단 노드의 신원, 전달 시각을 하나로 묶습니다. 이것이 증명하는 것은 메시지가 릴레이의 보관 상태로 받아들여졌다는 사실이지, 수신자가 읽었다는 사실이 아닙니다. 핸드오프를 끈 노드는 메시지를 자체 저장소에 보관하고 같은 종류의 수신 확인에 서명하므로, 수신 확인만으로는 두 경우를 구별할 수 없습니다.
각 당사자에게 보이는 것
| 당사자 | 보이는 것 | 보이지 않는 것 |
|---|---|---|
| 진입 노드 | 발신자의 네트워크 주소, 봉인된 계층, 다음 홉 | 메시지의 수신 대상과 내용 |
| 종단 노드 | 발신자와 수신자의 키, 암호문 | 발신자의 네트워크 주소와 내용 |
| 중앙 릴레이(핸드오프를 받음) | 모든 전송에서 보이는 정보: 발신자와 수신자의 키, 타임스탬프, 크기 | 발신자의 네트워크 주소와 내용 |
어떤 단일 노드도 사용자의 네트워크 주소와 메시지를 보내는 상대를 연결하지 못합니다. 종단 노드와 중앙 릴레이는 둘 다 누가 누구에게 보냈는지 봅니다.
프로토콜은 검증된 릴레이 홉을 최대 3개까지 허용합니다. 앱의 프라이버시 경로는 2개를 사용합니다. 릴레이의 남용 제한은 블라인드 릴레이 남용 방지에 설명되어 있습니다.
앱의 채팅
- 기본값: 메시지는 중앙 RelayWS 서비스를 거칩니다. 메시지 내용은 종단 간 암호화되지만, 서비스가 전달 메타데이터를 처리합니다. 채팅 릴레이 클라이언트 연동을 참고하세요.
- 프라이버시 경로(옵트인, 기본값 꺼짐): 이 설정이 켜져 있고 경로가 준비되어 있으면, 앱은 일대일 메시지를 먼저 2홉 어니언 경로로 보냅니다. 어떤 어니언 경로도 메시지를 받지 않으면, 앱은 메시지를 기기에 보관하며 해당 메시지에 대해 사용자가 승인하지 않는 한 표준 릴레이를 사용하지 않습니다.
- 익명 메일박스(베타): 프라이버시 네트워크에 연결되어 있는 동안에만 작동하는 별도의 드롭입니다. 일반 대화는 이를 사용하지 않습니다.
익명 메일박스 풀 크기
메일박스 풀 결과는 예전에는 항목과 관계없이 163,130바이트짜리 고정 이미지 하나였으므로, 짧은 메시지도 약 160 KiB의 응답이 필요했습니다. 서명된 프로토콜 기능 anpf1-ampc1로 협상하는 풀 버전 2는 봉인된 항목을 다섯 가지 크기 클래스(4,204, 16,492, 65,644 또는 131,180바이트, 또는 코덱 최대값) 중 가장 작은 것에 맞춰 패딩합니다. 4,096바이트 항목은 이제 4,518바이트로 전송됩니다.
TEE 노드
프로덕션 노드 하나가 Phala Cloud 신뢰 실행 환경(Intel TDX 기반 dstack) 안에서 실행됩니다. 이 노드는 익명 메일박스와 어니언 릴레이 역할만 합니다. VPN은 비활성화되어 있고, MemChain은 꺼져 있으며, 신원 키는 dstack 키 서비스에서 가져옵니다. 게이트웨이의 TLS 호스트 이름을 통해서만 접근할 수 있으며, 호스트 이름 엔드포인트가 추가된 이유가 바로 이것입니다. 앱은 현재 이 노드의 TEE 증명(attestation)을 검증하지 않습니다.
실시간 상태
집계된 네트워크 상태는 다음에서 공개됩니다.
GET https://api.aeronyx.network/api/privacy_network/vpn/public/network-stats/
릴레이 및 탐색 집계는 data.protocol_status 아래에 표시되며, 예를 들면 peer_store.blind_relay와 peer_store.peer_quorum이 있습니다. 읽을 때 두 가지에 유의하세요.
- 노드 단위 집계에는 최근 120초 이내에 하트비트가 있는 노드만 계산되므로, 오프라인 노드는
protocol_status.reported_nodes같은 개수에서 제외됩니다.network.total_nodes와network.vpn_nodes는 여전히 온라인 여부와 관계없이 등록된 활성 노드를 셉니다. - 합성 프로브 카운터(
probe_*,two_hop_probe_*)는 경로 상태를 측정합니다. 사용자 트래픽이 아닙니다.
공개 응답에는 개수, 상태 구간, 타임스탬프만 포함됩니다. 노드 ID, 엔드포인트, 경로 ID, 페이로드, 수신자, 클라이언트 IP 주소, DNS 데이터, 소셜 그래프 엣지는 절대 포함되지 않습니다. 네트워크 통계와 프라이버시 경계를 참고하세요.
<!-- faq:start -->자주 묻는 질문
내 AeroNyx 채팅 메시지는 탈중앙화 노드를 거치나요?
기본적으로는 그렇지 않습니다. 메시지는 중앙 RelayWS 서비스를 거칩니다. 앱에서 프라이버시 경로를 켤 수 있으며, 그러면 경로가 준비되어 있을 때 일대일 메시지를 노드를 경유하는 2홉 어니언 경로로 보냅니다. 어떤 경로도 메시지를 받지 않으면, 앱은 경로를 사용할 수 있게 되거나 사용자가 해당 메시지를 표준 릴레이로 보내도록 승인할 때까지 메시지를 보관합니다.
릴레이 노드가 전달하는 메시지를 읽을 수 있나요?
아니요. 릴레이는 자기 암호화 계층만 벗기고 불투명한 블롭을 전달합니다. 또한 메시지 내용은 대화 참여자 간에 종단 간 암호화됩니다.
Directory Chain이란 무엇인가요?
Directory Chain은 각 노드가 자기 디스크립터에 대해 보관하는, 서명되고 해시로 연결된 이력입니다. 다른 노드가 이를 미러링하며 포함 증명을 요청할 수 있습니다. 전역 코디네이터는 없습니다.
게이트웨이 뒤에 있는 노드는 어떻게 네트워크에 참여하나요?
https:// 호스트 이름을 엔드포인트로 공개할 수 있습니다. 다른 노드는 접속 시점에 그 이름을 해석하고 공인 주소만 사용하므로, 이름을 사설 또는 내부 대상으로 돌릴 수 없습니다.
공개 통계 페이지에 온라인 노드보다 등록된 노드가 더 많이 표시되는 이유는 무엇인가요?
network.total_nodes와 network.vpn_nodes는 온라인 여부와 관계없이 등록된 활성 노드를 셉니다. network.online_vpn_nodes와 비교하세요. 프로토콜 및 전달 집계에는 하트비트가 최신인 노드만 포함됩니다.
HTTPS를 위해 노드에 도메인 이름이나 인증 기관이 필요한가요?
아니요. 노드는 자신의 신원 키로 HTTPS 엔드포인트를 증명할 수 있습니다. TLS 인증서에는 인증서 키에 대한 노드 신원의 서명이 들어 있고, 노드 ID를 아는 클라이언트나 피어가 이를 검증할 수 있습니다. 게이트웨이 뒤에 있는 노드는 대신 https:// 호스트 이름을 계속 사용할 수 있습니다.
서명된 전달 수신 확인은 무엇을 증명하나요?
종단 노드가 메시지를 릴레이의 보관 상태, 실제로는 수신자의 릴레이 수신함에 받아들였다는 것을 증명합니다. 수신자가 메시지를 보았거나 읽었다는 것은 증명하지 않습니다. 그 용도에는 채팅 프로토콜의 전달 확인과 읽음 확인을 사용하세요.
<!-- faq:end -->