참고: 이 문서는 원래 2003년에 jrandom이 작성한 것입니다. 최신 상태로 유지하려고 노력하지만, 일부 정보는 구식이거나 불완전할 수 있습니다. 전송 및 암호화 섹션은 2025-01 기준으로 최신입니다.
소개
I2P는 확장 가능하고 자체 조직화되며 복원력이 있는 패킷 교환 익명 네트워크 계층으로, 그 위에서 익명성이나 보안을 중시하는 다양한 애플리케이션들이 운영될 수 있습니다. 이러한 각 애플리케이션은 자유 경로 믹스넷의 적절한 구현에 대해 걱정할 필요 없이 자체적인 익명성, 지연시간, 처리량 절충안을 만들 수 있으며, 이미 I2P 위에서 실행되고 있는 더 큰 익명성 사용자 집합과 자신들의 활동을 혼합할 수 있습니다.
이미 사용 가능한 애플리케이션들은 일반적인 인터넷 활동의 전체 범위를 제공합니다 — 익명 웹 브라우징, 웹 호스팅, 채팅, 파일 공유, 이메일, 블로깅 및 콘텐츠 신디케이션은 물론 개발 중인 여러 다른 애플리케이션들도 포함됩니다.
- 웹 브라우징: 프록시 사용을 지원하는 기존 브라우저 사용.
- 채팅: IRC 및 기타 프로토콜
- 파일 공유: I2PSnark 및 기타 애플리케이션
- 이메일: susimail 및 기타 애플리케이션
- 블로그: 로컬 웹 서버 또는 사용 가능한 플러그인 사용
Freenet 이나 GNUnet 과 같은 콘텐츠 배포 네트워크 내에서 호스팅되는 웹사이트와 달리, I2P에서 호스팅되는 서비스들은 완전히 상호작용이 가능합니다. 전통적인 웹 스타일의 검색 엔진, 게시판, 댓글을 달 수 있는 블로그, 데이터베이스 기반 사이트, 그리고 로컬에 설치하지 않고도 Freenet과 같은 정적 시스템을 조회할 수 있는 브리지들이 있습니다.
이 모든 익명성 지원 애플리케이션들과 함께 I2P는 메시지 지향 미들웨어의 역할을 담당합니다 — 애플리케이션들이 암호화 식별자(“destination”)로 데이터를 전송하겠다고 요청하면, I2P가 이를 안전하고 익명으로 전달되도록 처리합니다. I2P는 또한 I2P의 익명 best-effort 메시지들이 신뢰할 수 있고 순서가 보장된 스트림으로 전송될 수 있도록 하는 간단한 streaming 라이브러리를 번들로 제공하며, 네트워크의 높은 대역폭 지연 곱에 맞게 조정된 TCP 기반 혼잡 제어 알고리즘을 투명하게 제공합니다. 기존 애플리케이션들을 네트워크에 연결하기 위한 몇 가지 간단한 SOCKS 프록시들이 제공되어 왔지만, 거의 모든 애플리케이션이 익명 환경에서 민감한 정보에 해당하는 것들을 일상적으로 노출하기 때문에 그 가치는 제한적이었습니다. 유일한 안전한 방법은 애플리케이션을 완전히 감사하여 적절한 동작을 보장하는 것이며, 이를 지원하기 위해 우리는 네트워크를 최대한 활용할 수 있는 다양한 언어의 API 시리즈를 제공합니다.
I2P는 학술적, 상업적, 또는 정부적 연구 프로젝트가 아니라, 익명성이 필요한 사람들에게 충분한 수준의 익명성을 제공하기 위해 필요한 모든 것을 수행하는 것을 목표로 하는 엔지니어링 노력입니다. 2003년 초부터 한 명의 전임 개발자와 전 세계의 헌신적인 파트타임 기여자 그룹과 함께 활발한 개발이 진행되고 있습니다. I2P에서 수행되는 모든 작업은 오픈 소스이며 웹사이트 에서 자유롭게 이용할 수 있습니다. 코드의 대부분은 퍼블릭 도메인으로 완전히 공개되지만, BSD 스타일 라이선스 하에 일부 암호화 루틴을 사용합니다. I2P를 작업하는 사람들은 사람들이 클라이언트 애플리케이션을 어떤 라이선스로 배포하는지 통제하지 않으며, 여러 GPL 애플리케이션들(I2PTunnel , susimail , I2PSnark , I2P-Bote, I2Phex 등)을 이용할 수 있습니다. I2P의 자금은 전적으로 기부로 충당되며, 많은 개발자들이 익명이기 때문에 현재 어떤 관할권에서도 세금 혜택을 받지 않습니다.
작동
개요
I2P의 작동을 이해하려면 몇 가지 핵심 개념을 이해하는 것이 필수적입니다. 첫째, I2P는 네트워크에 참여하는 소프트웨어(router)와 개별 애플리케이션과 연결된 익명 엔드포인트(destinations)를 엄격하게 분리합니다. 누군가가 I2P를 실행하고 있다는 사실은 보통 비밀이 아닙니다. 숨겨지는 것은 사용자가 무엇을 하고 있는지(있다면), 그리고 특정 destination이 어떤 router에 연결되어 있는지에 대한 정보입니다. 최종 사용자는 일반적으로 자신의 router에 여러 개의 로컬 destinations을 가지게 됩니다. 예를 들어, 하나는 IRC 서버로의 프록시, 다른 하나는 사용자의 익명 웹서버(“I2P Site”) 지원, 또 다른 하나는 I2Phex 인스턴스용, 그리고 토렌트용 등입니다.
이해해야 할 또 다른 중요한 개념은 “tunnel"입니다. tunnel은 명시적으로 선택된 router 목록을 통과하는 방향성 있는 경로입니다. 계층화된 암호화가 사용되므로 각 router는 단일 계층만 복호화할 수 있습니다. 복호화된 정보에는 다음 router의 IP와 함께 전달될 암호화된 정보가 포함됩니다. 각 tunnel에는 시작점(첫 번째 router, “gateway"라고도 함)과 끝점이 있습니다. 메시지는 한 방향으로만 전송될 수 있습니다. 메시지를 되돌려 보내려면 또 다른 tunnel이 필요합니다.
두 가지 유형의 tunnel이 존재합니다: “outbound” tunnel은 tunnel 생성자로부터 메시지를 보내고, “inbound” tunnel은 tunnel 생성자에게 메시지를 가져옵니다. 이 두 tunnel을 결합하면 사용자들이 서로 메시지를 주고받을 수 있습니다. 발신자(위 이미지의 “Alice”)는 outbound tunnel을 설정하고, 수신자(위 이미지의 “Bob”)는 inbound tunnel을 생성합니다. inbound tunnel의 게이트웨이는 다른 사용자로부터 메시지를 받을 수 있으며 이를 엔드포인트(“Bob”)까지 전송합니다. outbound tunnel의 엔드포인트는 메시지를 inbound tunnel의 게이트웨이로 전송해야 합니다. 이를 위해 발신자(“Alice”)는 암호화된 메시지에 지시사항을 추가합니다. outbound tunnel의 엔드포인트가 메시지를 복호화하면, 올바른 inbound 게이트웨이(“Bob"으로의 게이트웨이)로 메시지를 전달하라는 지시사항을 받게 됩니다.
이해해야 할 세 번째 핵심 개념은 I2P의 “network database” (또는 “netDb”)입니다. 이는 네트워크 메타데이터를 공유하는 데 사용되는 한 쌍의 알고리즘입니다. 전달되는 메타데이터의 두 가지 유형은 **“routerInfo”**와 **“leaseSets”**입니다. routerInfo는 특정 router에 연결하기 위해 필요한 데이터(공개키, 전송 주소 등)를 router들에게 제공하고, leaseSet은 특정 목적지에 연결하기 위해 필요한 정보를 router들에게 제공합니다. leaseSet은 여러 개의 “lease"를 포함합니다. 이러한 각 lease는 tunnel 게이트웨이를 지정하여 특정 목적지에 도달할 수 있게 합니다. lease에 포함된 전체 정보는 다음과 같습니다:
- 특정 목적지에 도달할 수 있게 해주는 tunnel의 인바운드 게이트웨이.
- tunnel이 만료되는 시간.
- 메시지를 암호화할 수 있는 공개 키 쌍 (tunnel을 통해 전송하여 목적지에 도달하기 위해).
router들은 자신의 routerInfo를 netDb에 직접 전송하는 반면, leaseSet들은 아웃바운드 tunnel을 통해 전송됩니다 (leaseSet들은 router와 해당 leaseSet들 간의 연관성을 피하기 위해 익명으로 전송되어야 합니다).
위의 개념들을 결합하여 네트워크에서 성공적인 연결을 구축할 수 있습니다.
자신의 인바운드 및 아웃바운드 tunnel을 구축하기 위해, Alice는 netDb에서 조회를 수행하여 routerInfo를 수집합니다. 이런 방식으로, 그녀는 자신의 tunnel에서 홉으로 사용할 수 있는 피어 목록을 수집합니다. 그런 다음 첫 번째 홉에 빌드 메시지를 보내 tunnel 구축을 요청하고, 해당 router가 tunnel이 구축될 때까지 구축 메시지를 계속 전달하도록 요청할 수 있습니다.
Alice가 Bob에게 메시지를 보내려고 할 때, 먼저 netDb에서 Bob의 leaseSet을 조회하여 그의 현재 인바운드 tunnel 게이트웨이를 찾습니다. 그런 다음 자신의 아웃바운드 tunnel 중 하나를 선택하고, 아웃바운드 tunnel의 엔드포인트가 Bob의 인바운드 tunnel 게이트웨이 중 하나로 메시지를 전달하도록 지시와 함께 메시지를 전송합니다. 아웃바운드 tunnel 엔드포인트가 이러한 지시를 받으면 요청된 대로 메시지를 전달하고, Bob의 인바운드 tunnel 게이트웨이가 이를 받으면 tunnel을 통해 Bob의 router로 전달됩니다. Alice가 Bob이 메시지에 답장할 수 있기를 원한다면, 메시지 자체의 일부로 자신의 목적지를 명시적으로 전송해야 합니다. 이는 streaming 라이브러리에서 수행되는 것처럼 상위 계층을 도입함으로써 가능합니다. Alice는 또한 자신의 최신 LeaseSet을 메시지와 함께 번들로 전송하여 Bob이 답장하려고 할 때 netDb 조회를 할 필요가 없도록 함으로써 응답 시간을 단축할 수 있지만, 이는 선택사항입니다.
tunnel 자체가 네트워크 내부의 피어들로부터 무단 공개를 방지하기 위한 계층 암호화를 갖고 있고(전송 계층 자체도 네트워크 외부 피어들로부터 무단 공개를 방지하기 위해 암호화를 사용하듯이), 아웃바운드 tunnel 종단점과 인바운드 tunnel 게이트웨이로부터 메시지를 숨기기 위해 추가적인 종단 간 암호화 계층을 더하는 것이 필요합니다. 이 “garlic encryption “을 통해 Alice의 router는 여러 메시지를 하나의 “garlic 메시지"로 감쌀 수 있으며, 특정 공개 키로 암호화하여 중간 피어들이 garlic 안에 얼마나 많은 메시지가 있는지, 그 메시지들이 무엇을 말하는지, 또는 개별 clove들이 어디로 향하는지 알 수 없게 합니다. Alice와 Bob 간의 일반적인 종단 간 통신에서, garlic은 Bob의 leaseSet에 게시된 공개 키로 암호화되어, Bob 자신의 router에게 공개 키를 노출하지 않고도 메시지를 암호화할 수 있게 합니다.
염두에 둘 또 다른 중요한 사실은 I2P가 전적으로 메시지 기반이며 일부 메시지가 전송 과정에서 손실될 수 있다는 것입니다. I2P를 사용하는 애플리케이션은 메시지 지향 인터페이스를 사용하고 자체적으로 혼잡 제어 및 신뢰성 요구사항을 처리할 수 있지만, 대부분의 경우 제공되는 streaming 라이브러리를 재사용하여 I2P를 스트림 기반 네트워크로 보는 것이 최선입니다.
Tunnel
인바운드 tunnel과 아웃바운드 tunnel은 모두 비슷한 원리로 작동합니다. tunnel gateway는 여러 tunnel 메시지를 축적한 후, 최종적으로 이를 tunnel 전송을 위한 형태로 전처리합니다. 다음으로, gateway는 전처리된 데이터를 암호화하고 첫 번째 홉으로 전달합니다. 해당 피어와 후속 tunnel 참여자들은 중복이 아닌지 확인한 후 다음 피어로 전달하기 전에 암호화 계층을 추가합니다. 결국 메시지는 엔드포인트에 도착하며, 여기서 메시지들이 다시 분리되어 요청된 대로 전달됩니다. 차이점은 tunnel 생성자가 하는 역할에서 발생합니다 — 인바운드 tunnel의 경우, 생성자는 엔드포인트이며 추가된 모든 계층을 단순히 복호화합니다. 반면 아웃바운드 tunnel의 경우, 생성자는 gateway이며 모든 계층을 미리 복호화하여 홉별 암호화의 모든 계층이 추가된 후 메시지가 tunnel 엔드포인트에 평문으로 도착하도록 합니다.
메시지를 전달할 특정 피어의 선택과 그들의 특정 순서는 I2P의 익명성과 성능 특성을 이해하는 데 중요합니다. network database(아래 참조)는 쿼리할 피어와 항목을 저장할 피어를 선택하는 자체 기준이 있지만, tunnel 생성자는 단일 tunnel에서 네트워크의 모든 피어를 임의의 순서로(심지어 여러 번이라도) 사용할 수 있습니다. 완벽한 지연 시간과 용량 데이터가 전역적으로 알려져 있다면, 선택과 순서는 클라이언트의 특정 요구사항과 그들의 위협 모델에 따라 결정될 것입니다. 안타깝게도 지연 시간과 용량 데이터를 익명으로 수집하는 것은 간단하지 않으며, 이러한 정보를 제공하기 위해 신뢰할 수 없는 피어에 의존하는 것은 그 자체로 심각한 익명성 문제를 야기합니다.
익명성 관점에서 가장 간단한 기법은 전체 네트워크에서 피어를 무작위로 선택하고, 무작위로 정렬한 다음 그 순서대로 영원히 사용하는 것입니다. 성능 관점에서 가장 간단한 기법은 필요한 여유 용량을 가진 가장 빠른 피어를 선택하고, 투명한 장애 조치를 처리하기 위해 여러 피어에 부하를 분산하며, 용량 정보가 변경될 때마다 tunnel을 재구성하는 것입니다. 전자는 취약하고 비효율적이며, 후자는 접근 불가능한 정보를 요구하고 불충분한 익명성을 제공합니다. I2P는 대신 익명성을 고려한 측정 코드와 결합된 다양한 피어 선택 전략을 제공하여 피어들을 프로필별로 조직화하는 작업을 진행하고 있습니다.
기본적으로 I2P는 상호작용하는 피어들의 간접적 행동을 측정하여 지속적으로 프로파일링합니다. 예를 들어, 피어가 netDb 조회에 1.3초 만에 응답할 때, 그 왕복 지연시간은 요청과 응답이 통과한 두 tunnel(인바운드 및 아웃바운드)에 관련된 모든 router들의 프로파일과 조회된 피어의 프로파일에 기록됩니다. 전송 계층 지연시간이나 혼잡과 같은 직접 측정은 프로파일의 일부로 사용되지 않습니다. 이는 조작이 가능하고 측정하는 router와 연관될 수 있어 간단한 공격에 노출될 수 있기 때문입니다. 이러한 프로파일을 수집하면서 각각에 대해 일련의 계산이 실행되어 성능을 요약합니다 — 지연시간, 많은 활동을 처리할 수 있는 용량, 현재 과부하 상태인지 여부, 그리고 네트워크에 얼마나 잘 통합되어 있는지를 측정합니다. 이러한 계산들은 활성 피어들에 대해 비교되어 router들을 네 개의 계층으로 분류합니다 — 빠르고 고용량, 고용량, 실패하지 않음, 그리고 실패. 이러한 계층의 임계값은 동적으로 결정되며, 현재는 상당히 간단한 알고리즘을 사용하지만 대안들이 존재합니다.
이 프로필 데이터를 사용하여, 가장 단순하고 합리적인 피어 선택 전략은 최상위 계층(빠르고 높은 용량)에서 피어를 무작위로 선택하는 것이며, 현재 클라이언트 터널에서 이 방식이 배포되어 있습니다. 탐색적 터널(netDb 및 터널 관리에 사용)은 “실패하지 않는” 계층(더 나은 계층의 router도 포함)에서 피어를 무작위로 선택하여, 피어가 router를 더 광범위하게 샘플링할 수 있게 하고, 실제로는 무작위화된 언덕 오르기 를 통해 피어 선택을 최적화합니다. 하지만 이러한 전략들만으로는 전임자 및 netDb 수집 공격을 통해 router의 최상위 계층에 있는 피어에 관한 정보가 유출됩니다. 따라서 부하를 균등하게 분산시키지는 못하지만 특정 부류의 공격자들이 가하는 공격을 해결할 수 있는 여러 대안이 존재합니다.
무작위 키를 선택하고 해당 키로부터의 XOR 거리에 따라 피어들을 정렬함으로써, predecessor 공격과 harvesting 공격에서 유출되는 정보가 피어들의 실패율과 계층의 이탈률에 따라 감소됩니다. netDb harvesting 공격을 처리하는 또 다른 간단한 전략은 inbound tunnel gateway들을 고정하되 터널 내 더 깊은 곳의 피어들을 무작위화하는 것입니다. 클라이언트가 연락하는 적대자에 대한 predecessor 공격을 처리하기 위해서는 outbound tunnel 엔드포인트들도 고정된 상태로 유지됩니다. 가장 노출된 지점에서 고정할 피어의 선택은 당연히 지속 시간에 제한이 있어야 하는데, 모든 피어들은 결국 실패하기 때문에 다른 router들의 측정된 평균 실패 간격 시간을 모방하여 반응적으로 조정하거나 능동적으로 회피할 수 있습니다. 이 두 전략은 고정된 노출 피어와 터널 자체 내에서 XOR 기반 정렬을 사용하여 결합될 수 있습니다. 더 엄격한 전략은 잠재적 터널의 정확한 피어들과 순서를 고정하여, 모든 피어들이 매번 같은 방식으로 참여하는 데 동의할 경우에만 개별 피어들을 사용하는 것입니다. 이는 각 피어의 predecessor와 successor가 항상 동일한 XOR 기반 정렬과 다르며, XOR은 단지 그들의 순서가 변경되지 않도록 보장할 뿐입니다.
앞서 언급했듯이, I2P는 현재(릴리스 0.8) XOR 기반 순서 지정과 함께 위의 계층형 랜덤 전략을 포함하고 있습니다. tunnel 운영, 관리 및 피어 선택에 관련된 메커니즘에 대한 더 자세한 논의는 tunnel spec 에서 찾을 수 있습니다.
네트워크 데이터베이스 (netDb)
앞서 언급했듯이, I2P의 netDb는 네트워크의 메타데이터를 공유하는 역할을 합니다. 이에 대한 자세한 내용은 네트워크 데이터베이스 페이지에서 확인할 수 있으며, 기본적인 설명은 아래에서 제공됩니다.
모든 I2P router에는 로컬 netDb가 포함되어 있지만, 모든 router가 DHT에 참여하거나 leaseSet 조회에 응답하는 것은 아닙니다. DHT에 참여하고 leaseSet 조회에 응답하는 router들을 ‘floodfill’이라고 합니다. Router는 수동으로 floodfill로 구성될 수도 있고, 충분한 용량을 갖추고 안정적인 운영을 위한 다른 기준을 충족할 경우 자동으로 floodfill이 될 수도 있습니다.
다른 I2P router들은 간단한 ‘store’와 ’lookup’ 쿼리를 floodfill에 보내어 데이터를 저장하고 조회합니다. floodfill router가 ‘store’ 쿼리를 받으면, Kademlia 알고리즘 을 사용하여 다른 floodfill router들에게 정보를 전파합니다. ’lookup’ 쿼리는 중요한 보안 문제를 피하기 위해 현재 다르게 작동합니다. lookup이 수행될 때, floodfill router는 다른 피어에게 lookup을 전달하지 않고, 요청된 데이터가 있는 경우 항상 자체적으로 응답합니다.
네트워크 데이터베이스에는 두 가지 유형의 정보가 저장됩니다.
- RouterInfo는 특정 I2P router에 대한 정보와 연결 방법을 저장합니다
- LeaseSet은 특정 목적지(예: I2P 웹사이트, 이메일 서버…)에 대한 정보를 저장합니다
이 모든 정보는 게시하는 당사자가 서명하고, 정보를 사용하거나 저장하는 모든 I2P router가 검증합니다. 또한 데이터에는 타이밍 정보가 포함되어 오래된 항목의 저장과 가능한 공격을 방지합니다. 이것이 I2P가 정확한 시간을 유지하기 위한 필요한 코드를 번들로 포함하고, 때때로 일부 SNTP 서버들(pool.ntp.org 라운드 로빈이 기본값)에 쿼리하며, 전송 계층에서 router들 간의 시간 편차를 감지하는 이유입니다.
몇 가지 추가적인 주의사항도 중요합니다.
미공개 및 암호화된 leaseSet: 특정 사람들만이 목적지에 도달할 수 있도록 하고 싶을 수 있습니다. 이는 netDb에 목적지를 공개하지 않음으로써 가능합니다. 하지만 다른 수단을 통해 목적지를 전송해야 합니다. 이는 ‘암호화된 leaseSet’에 의해 지원됩니다. 이러한 leaseSet은 복호화 키에 접근할 수 있는 사람들만이 해독할 수 있습니다.
부트스트래핑: netDb를 부트스트랩하는 것은 꽤 간단합니다. router가 도달 가능한 피어의 단일 routerInfo를 수신하게 되면, 해당 router에게 네트워크의 다른 router들에 대한 참조를 요청할 수 있습니다. 현재 많은 사용자들이 이 정보를 사용할 수 있도록 웹사이트에 자신의 routerInfo 파일을 게시하고 있습니다. I2P는 자동으로 이러한 웹사이트 중 하나에 연결하여 routerInfo 파일을 수집하고 부트스트랩을 수행합니다. I2P는 이 부트스트랩 과정을 “리시딩(reseeding)“이라고 부릅니다.
조회 확장성: I2P 네트워크에서의 조회는 재귀적이 아닌 반복적입니다. floodfill에서 조회가 실패하면, 다음으로 가장 가까운 floodfill로 조회가 반복됩니다. floodfill은 다른 floodfill에게 재귀적으로 데이터를 요청하지 않습니다. 반복적 조회는 대규모 DHT 네트워크로 확장 가능합니다.
전송 프로토콜
router 간 통신은 외부 적대자에 대해 기밀성과 무결성을 제공하면서, 연락된 router가 주어진 메시지를 받아야 할 올바른 대상임을 인증해야 합니다. router가 다른 router와 어떻게 통신하는지에 대한 세부사항은 중요하지 않습니다. 이러한 기본 필수사항들을 제공하기 위해 서로 다른 시점에 세 가지 별도의 프로토콜이 사용되었습니다.
I2P는 현재 TCP 기반의 NTCP2 와 UDP 기반의 SSU2 두 가지 전송 프로토콜을 지원합니다. 이들은 이전 버전의 프로토콜인 NTCP 와 SSU 를 대체했으며, 기존 프로토콜들은 이제 더 이상 사용되지 않습니다. 두 프로토콜 모두 IPv4와 IPv6를 지원합니다. TCP와 UDP 전송을 모두 지원함으로써, I2P는 제한적인 검열 체제에서 트래픽을 차단하려는 방화벽을 포함하여 대부분의 방화벽을 효과적으로 우회할 수 있습니다. NTCP2와 SSU2는 현대적인 암호화 표준을 사용하고, 트래픽 식별 저항성을 개선하며, 효율성과 보안을 향상시키고, NAT 통과를 더욱 견고하게 만들도록 설계되었습니다. Router들은 지원하는 각 전송 프로토콜과 IP 주소를 netDb에 게시합니다. 공개 IPv4 및 IPv6 네트워크에 접근할 수 있는 router들은 일반적으로 NTCP2/SSU2와 IPv4/IPv6의 각 조합에 대해 하나씩, 총 네 개의 주소를 게시합니다.
SSU2 는 SSU의 목표를 지원하고 확장합니다. SSU2는 Wireguard 및 QUIC과 같은 다른 현대적인 UDP 기반 프로토콜과 많은 유사점을 가지고 있습니다. UDP를 통한 네트워크 메시지의 안정적인 전송 외에도, SSU2는 peer-to-peer, 협력적 IP 주소 감지, 방화벽 감지 및 NAT traversal을 위한 전문적인 기능을 제공합니다. SSU spec 에 설명된 바와 같이:
이 프로토콜의 목표는 제3자가 쉽게 식별할 수 있는 데이터의 노출을 최소화하면서 안전하고, 인증된, 준신뢰성 있는 비순차적 메시지 전달을 제공하는 것입니다. 고도의 통신뿐만 아니라 TCP 친화적인 혼잡 제어를 지원해야 하며 PMTU 탐지를 포함할 수 있습니다. 가정 사용자에게 충분한 속도로 대용량 데이터를 효율적으로 이동할 수 있어야 합니다. 또한 대부분의 NAT나 방화벽과 같은 네트워크 장애물을 해결하기 위한 기술을 지원해야 합니다.
NTCP2 는 NTCP의 목표를 지원하고 확장합니다. 현대적인 암호화 표준을 사용하여 TCP를 통한 네트워크 메시지의 효율적이고 완전히 암호화된 전송과 트래픽 식별에 대한 저항성을 제공합니다.
I2P는 여러 전송 방식을 동시에 지원합니다. 아웃바운드 연결을 위한 특정 전송 방식은 “입찰(bids)“로 선택됩니다. 각 전송 방식이 연결에 대해 입찰하고, 이러한 입찰의 상대적 가치가 우선순위를 결정합니다. 전송 방식들은 피어에 대한 연결이 이미 설정되어 있는지 여부에 따라 다른 입찰로 응답할 수 있습니다.
bid (우선순위) 값은 구현에 따라 다르며 트래픽 조건, 연결 수, 기타 요소에 따라 달라질 수 있습니다. Router는 또한 각 전송 방식과 주소에 대한 전송 “비용"으로 netDb에 인바운드 연결에 대한 전송 선호도를 게시합니다.
암호화
I2P는 암호화, 인증, 검증을 위해 여러 프로토콜 계층에서 암호학을 사용합니다. 주요 프로토콜 계층은 다음과 같습니다: 전송, tunnel 구축 메시지, tunnel 계층 암호화, 네트워크 데이터베이스 메시지, 그리고 종단 간(garlic) 메시지. I2P의 원래 설계는 당시 안전하다고 여겨졌던 작은 암호학적 기본 요소 집합을 사용했습니다. 여기에는 ElGamal 비대칭 암호화, DSA-SHA1 서명, AES256/CBC 대칭 암호화, 그리고 SHA-256 해시가 포함되었습니다. 사용 가능한 컴퓨팅 파워가 증가하고 암호학 연구가 수년에 걸쳐 크게 발전함에 따라, I2P는 기본 요소와 프로토콜을 업그레이드해야 했습니다. 따라서 우리는 “암호화 유형"과 “서명 유형"의 개념을 추가하고, 이러한 식별자를 포함하고 지원을 나타내도록 프로토콜을 확장했습니다. 이를 통해 하위 호환성을 깨뜨리거나 네트워크 업데이트를 위한 “플래그 데이"를 요구하지 않고도 현대적인 암호학에 대한 네트워크 지원을 주기적으로 업데이트하고 확장하며, 새로운 기본 요소를 위한 네트워크의 미래 대비를 할 수 있습니다. 일부 서명 및 암호화 유형은 실험적 사용을 위해 예약되어 있습니다.
현재 대부분의 프로토콜 계층에서 사용되는 기본 암호화 요소는 X25519 키 교환, EdDSA 서명, ChaCha20/Poly1305 인증된 대칭 암호화, SHA-256 해시입니다. AES256은 여전히 tunnel 계층 암호화에 사용됩니다. 이러한 현대적인 프로토콜들은 네트워크 통신의 대부분에서 사용됩니다. ElGamal, ECDSA, DSA-SHA1을 포함한 기존의 암호화 요소들은 구형 router와의 통신 시 하위 호환성을 위해 대부분의 구현에서 계속 지원됩니다. 일부 오래된 프로토콜들은 더 이상 사용되지 않거나 완전히 제거되었습니다. 가까운 미래에 우리는 강력한 보안 표준을 유지하기 위해 양자 이후(PQ) 또는 하이브리드-PQ 암호화 및 서명으로의 마이그레이션에 대한 연구를 시작할 예정입니다.
이러한 암호화 기본 요소들이 결합되어 다양한 적대자들에 대한 I2P의 계층적 방어를 제공합니다. 가장 낮은 수준에서는 router 간 통신이 전송 계층 보안으로 보호됩니다. 전송을 통해 전달되는 Tunnel 메시지들은 자체적인 계층 암호화를 가지고 있습니다. 다양한 기타 메시지들은 역시 암호화된 “garlic message” 내에서 전달됩니다.
Garlic 메시지
Garlic 메시지는 “양파” 계층 암호화의 확장으로, 단일 메시지의 내용이 여러 개의 “클로브(정향)“를 포함할 수 있게 합니다 — 각각의 전달 지시사항과 함께 완전히 형성된 메시지들입니다. 메시지는 정보에 접근해서는 안 되는 피어를 통해 평문으로 전달될 때마다 garlic 메시지로 감싸집니다 — 예를 들어, router가 다른 router에게 tunnel 참여를 요청하고자 할 때, 요청을 garlic 안에 감싸고, 그 garlic을 수신 router의 공개 키로 암호화한 다음 tunnel을 통해 전달합니다. 또 다른 예는 클라이언트가 목적지로 메시지를 보내고자 할 때입니다 — 송신자의 router는 해당 데이터 메시지를 (다른 메시지들과 함께) garlic으로 감싸고, 그 garlic을 수신자의 leaseSet에 게시된 공개 키로 암호화한 다음 적절한 tunnel들을 통해 전달합니다.
암호화 계층 내부의 각 clove에 첨부된 “지시사항"에는 clove가 로컬로, 원격 router로, 또는 원격 router의 원격 tunnel로 전달되도록 요청하는 기능이 포함되어 있습니다. 이러한 지시사항에는 특정 시간이나 조건이 충족될 때까지 전달을 지연하도록 요청할 수 있는 필드가 있지만, 비자명한 지연 이 배포될 때까지는 이를 준수하지 않습니다. tunnel을 구축하지 않고도 garlic 메시지를 임의의 홉 수만큼 명시적으로 라우팅하거나, tunnel의 다음 홉으로 전달하기 전에 여러 홉을 거쳐 garlic 메시지로 래핑하여 전달함으로써 tunnel 메시지를 재라우팅하는 것도 가능하지만, 이러한 기술들은 현재 기존 구현에서는 사용되지 않습니다.
세션 태그
신뢰할 수 없고 순서가 없는 메시지 기반 시스템인 I2P는 비대칭 및 대칭 암호화 알고리즘의 간단한 조합을 사용하여 garlic 메시지에 데이터 기밀성과 무결성을 제공합니다. 원래 조합은 ElGamal/AES+SessionTags라고 불렸지만, 이는 2048bit ElGamal, AES256, SHA256 및 32바이트 nonce의 간단한 사용을 설명하기에는 지나치게 장황한 방법입니다. 이 프로토콜은 여전히 지원되지만, 네트워크의 대부분은 새로운 프로토콜인 ECIES-X25519-AEAD-Ratchet로 마이그레이션했습니다. 이 프로토콜은 X25519, ChaCha20/Poly1305, 그리고 동기화된 PRNG를 결합하여 32바이트 nonce를 생성합니다. 두 프로토콜 모두 아래에서 간략히 설명됩니다.
ElGamal/AES+SessionTags
router가 다른 router에게 garlic 메시지를 처음 암호화하려고 할 때, AES256 세션 키의 키잉 자료를 ElGamal로 암호화하고 암호화된 ElGamal 블록 뒤에 AES256/CBC 암호화된 페이로드를 추가합니다. 암호화된 페이로드 외에도 AES 암호화 섹션에는 페이로드 길이, 암호화되지 않은 페이로드의 SHA256 해시, 그리고 여러 “세션 태그"들(32바이트 랜덤 논스)이 포함됩니다. 송신자가 다음에 다른 router에게 garlic 메시지를 암호화하려고 할 때는 새로운 세션 키를 ElGamal로 암호화하는 대신 이전에 전달된 세션 태그 중 하나를 선택하고 해당 세션 태그와 함께 사용된 세션 키를 사용하여 이전과 같이 페이로드를 AES 암호화하되, 세션 태그 자체를 앞에 붙입니다. router가 garlic 암호화된 메시지를 수신하면 처음 32바이트가 사용 가능한 세션 태그와 일치하는지 확인합니다 — 일치하면 단순히 AES로 메시지를 복호화하지만, 일치하지 않으면 첫 번째 블록을 ElGamal로 복호화합니다.
각 세션 태그는 한 번만 사용할 수 있어서 내부 적대자가 서로 다른 메시지들을 같은 router들 간의 통신으로 불필요하게 연관짓는 것을 방지합니다. ElGamal/AES+SessionTag 암호화 메시지의 발신자는 언제 얼마나 많은 태그를 전달할지 선택하며, 수신자에게 일련의 메시지들을 처리할 충분한 태그들을 미리 비축해둡니다. Garlic 메시지는 작은 추가 메시지를 clove로 묶어서(“delivery status message”) 성공적인 태그 전달을 감지할 수 있습니다 — garlic 메시지가 의도된 수신자에게 도착하여 성공적으로 복호화되면, 이 작은 delivery status 메시지는 노출된 clove 중 하나가 되어 수신자가 해당 clove를 원래 발신자에게 다시 보내도록 하는 지시사항을 담고 있습니다(물론 inbound tunnel을 통해). 원래 발신자가 이 delivery status 메시지를 받으면, garlic 메시지에 묶여있던 세션 태그들이 성공적으로 전달되었음을 알게 됩니다.
Session tag 자체는 매우 짧은 수명을 가지며, 사용되지 않으면 폐기됩니다. 또한 각 키에 대해 저장되는 수량이 제한되어 있고, 키 자체의 수도 제한되어 있습니다 — 너무 많이 도착하면 새로운 메시지나 오래된 메시지가 삭제될 수 있습니다. 송신자는 session tag를 사용하는 메시지가 제대로 전달되고 있는지 추적하며, 충분한 통신이 이루어지지 않으면 이전에 제대로 전달되었다고 가정했던 메시지들을 삭제하고 완전한 비용이 많이 드는 ElGamal 암호화로 되돌아갈 수 있습니다.
ECIES-X25519-AEAD-Ratchet
ElGamal/AES+SessionTags는 여러 면에서 상당한 오버헤드가 필요했습니다. ElGamal이 상당히 느리기 때문에 CPU 사용량이 높았습니다. 대량의 session tag들을 미리 전달해야 했고 ElGamal 공개 키가 매우 크기 때문에 대역폭이 과도하게 사용되었습니다. 대량의 session tag들을 저장해야 하는 요구사항으로 인해 메모리 사용량이 높았습니다. session tag 전달 손실로 인해 신뢰성이 저해되었습니다.
ECIES-X25519-AEAD-Ratchet은 이러한 문제들을 해결하기 위해 설계되었습니다. X25519는 키 교환에 사용됩니다. ChaCha20/Poly1305는 인증된 대칭 암호화에 사용됩니다. 암호화 키는 “이중 래칫” 방식으로 주기적으로 회전됩니다. 세션 태그는 32바이트에서 8바이트로 줄어들었고 PRNG로 생성됩니다. 이 프로토콜은 Signal과 WhatsApp에서 사용되는 signal 프로토콜과 많은 유사점을 가지고 있습니다. 이 프로토콜은 CPU, RAM, 대역폭에서 상당히 낮은 오버헤드를 제공합니다.
세션 태그는 세션 태그와 세션 키를 생성하기 위해 세션의 양 끝에서 실행되는 결정론적 동기화된 PRNG에서 생성됩니다. PRNG는 SHA-256 HMAC을 사용하는 HKDF이며, X25519 DH 결과로부터 시드됩니다. 세션 태그는 사전에 전송되지 않으며, 메시지와 함께만 포함됩니다. 수신자는 세션 태그로 인덱싱된 제한된 수의 세션 키를 저장합니다. 발신자는 사전에 전송되지 않기 때문에 어떤 세션 태그나 키도 저장할 필요가 없으며, 필요 시 생성될 수 있습니다. 발신자와 수신자 간에 이 PRNG를 대략적으로 동기화하여 유지함으로써 (수신자가 다음 예를 들어 50개의 태그 윈도우를 사전 계산) 주기적으로 많은 수의 태그를 번들링하는 오버헤드가 제거됩니다.
미래
I2P의 프로토콜은 휴대폰을 포함한 대부분의 플랫폼에서 효율적이며, 대부분의 위협 모델에 대해 안전합니다. 그러나 강력한 국가 후원 적대자에 직면한 사용자들의 요구를 충족하고, 지속적인 암호학적 발전과 계속 증가하는 컴퓨팅 파워의 위협에 대응하기 위해서는 추가적인 개선이 필요한 여러 영역이 있습니다. 제한된 경로와 가변 지연이라는 두 가지 가능한 기능이 2003년 jrandom에 의해 제안되었습니다. 더 이상 이러한 기능들을 구현할 계획은 없지만, 아래에서 설명하겠습니다.
제한된 라우트 운영
I2P는 기능적인 패킷 교환 네트워크 위에서 실행되도록 설계된 오버레이 네트워크로, 종단간 원칙을 활용하여 익명성과 보안을 제공합니다. 인터넷이 더 이상 종단간 원칙을 완전히 수용하지 않지만(NAT 사용으로 인해), I2P는 네트워크의 상당 부분이 접근 가능해야 합니다 — 제한된 경로를 사용하여 실행되는 일부 피어들이 가장자리에 있을 수 있지만, I2P는 대부분의 피어들이 접근 불가능한 퇴화된 경우에 대한 적절한 라우팅 알고리즘을 포함하지 않습니다. 그러나 그러한 알고리즘을 사용하는 네트워크 위에서는 작동할 것입니다.
제한된 라우트 운영에서는 직접 연결 가능한 피어에 제한이 있으며, 제한된 라우트가 어떻게 처리되는지에 따라 여러 가지 기능적 및 익명성 측면의 영향이 있습니다. 가장 기본적인 수준에서 제한된 라우트는 피어가 인바운드 연결을 허용하지 않는 NAT 또는 방화벽 뒤에 있을 때 존재합니다. 이는 분산 홀 펀칭을 전송 계층에 통합하여 대부분 해결되었으며, 이를 통해 대부분의 NAT 및 방화벽 뒤에 있는 사람들이 별도의 설정 없이도 예상치 못한 연결을 받을 수 있게 되었습니다. 그러나 이것이 네트워크 내의 router들에게 피어의 IP 주소 노출을 제한하지는 않습니다. 이들은 공개된 introducer를 통해 해당 피어에게 간단히 소개받을 수 있기 때문입니다.
제한된 경로의 기능적 처리를 넘어서, IP 주소 노출을 제한하는 데 사용할 수 있는 두 가지 수준의 제한된 작동이 있습니다 — 통신을 위한 router별 터널 사용과 ‘클라이언트 router’ 제공입니다. 전자의 경우, router들은 새로운 터널 풀을 구축하거나 탐색 풀을 재사용할 수 있으며, 그 중 일부의 인바운드 게이트웨이를 전송 주소 대신 routerInfo의 일부로 게시합니다. 피어가 해당 router와 연결하고 싶을 때, netDb에서 해당 터널 게이트웨이를 보고 게시된 터널 중 하나를 통해 관련 메시지를 단순히 전송합니다. 제한된 경로 뒤의 피어가 응답하려는 경우, 직접적으로(피어에게 IP를 노출할 의향이 있다면) 또는 아웃바운드 터널을 통해 간접적으로 응답할 수 있습니다. 피어가 직접 연결된 router들이 해당 router에 도달하려고 할 때(예를 들어, 터널 메시지를 전달하기 위해), 단순히 게시된 터널 게이트웨이보다 직접 연결을 우선시합니다. ‘클라이언트 router’의 개념은 어떤 router 주소도 게시하지 않음으로써 제한된 경로를 단순히 확장합니다. 이러한 router는 netDb에 자신의 routerInfo를 게시할 필요도 없으며, 단순히 연결하는 피어들에게 자체 서명된 routerInfo를 제공하기만 하면 됩니다(router의 공개 키를 전달하는 데 필요함).
제한된 경로 뒤에 있는 사용자들에게는 트레이드오프가 있습니다. 이들은 다른 사람들의 tunnel에 덜 빈번하게 참여하게 되고, 연결된 router들이 그렇지 않았다면 노출되지 않았을 트래픽 패턴을 추론할 수 있게 됩니다. 반면에, 그러한 노출의 비용이 IP가 사용 가능해지는 비용보다 낮다면, 그럴 만한 가치가 있을 수 있습니다. 물론 이는 제한된 경로 뒤에 있는 router가 연결하는 피어들이 적대적이지 않다고 가정합니다 — 네트워크가 충분히 커서 연결을 위해 적대적인 피어를 사용할 확률이 충분히 작거나, 신뢰할 수 있는 (그리고 아마도 임시적인) 피어들을 대신 사용하는 경우입니다.
제한된 경로는 복잡하며, 전반적인 목표는 대부분 포기되었습니다. 관련된 여러 개선사항들이 이러한 경로의 필요성을 크게 줄였습니다. 이제 방화벽 포트를 자동으로 열기 위해 UPnP를 지원합니다. IPv4와 IPv6을 모두 지원합니다. SSU2는 주소 감지, 방화벽 상태 결정, 협력적 NAT hole punching을 개선했습니다. SSU2, NTCP2, 주소 호환성 검사는 tunnel이 구축되기 전에 tunnel hop들이 연결될 수 있도록 보장합니다. GeoIP와 국가 식별 기능을 통해 제한적인 방화벽이 있는 국가의 피어들을 피할 수 있습니다. 그러한 방화벽 뒤에 있는 “숨겨진” router들에 대한 지원도 개선되었습니다. 일부 구현체들은 Yggdrasil과 같은 오버레이 네트워크의 피어들에 대한 연결도 지원합니다.
가변 지연시간
I2P의 초기 노력의 대부분이 낮은 지연 시간 통신에 집중되었음에도 불구하고, I2P는 처음부터 가변 지연 시간 서비스를 염두에 두고 설계되었습니다. 가장 기본적인 수준에서, I2P 위에서 실행되는 애플리케이션은 여전히 그들의 트래픽 패턴을 낮은 지연 시간 트래픽과 혼합하면서 중간 및 높은 지연 시간 통신의 익명성을 제공할 수 있습니다. 그러나 내부적으로 I2P는 garlic encryption을 통해 자체적인 중간 및 높은 지연 시간 통신을 제공할 수 있습니다 — 메시지가 특정 지연 후에, 특정 시간에, 특정 수의 메시지가 전달된 후에, 또는 다른 믹스 전략에 따라 전송되어야 함을 지정하는 방식으로 말입니다. 계층화된 암호화를 통해, 클로브(clove)가 지연 요청을 노출한 router만이 해당 메시지가 높은 지연 시간을 요구한다는 것을 알 수 있어, 트래픽이 낮은 지연 시간 트래픽과 더욱 잘 혼합될 수 있습니다. 전송 전제 조건이 충족되면, 클로브(그 자체가 아마도 garlic 메시지일 것)를 보유하고 있던 router는 단순히 요청된 대로 이를 전달합니다 — router로, tunnel로, 또는 가장 가능성 높게는 원격 클라이언트 목적지로 말입니다.
가변 지연 서비스의 목표는 이를 지원하기 위한 저장-전송 메커니즘에 상당한 자원이 필요합니다. 이러한 메커니즘은 i2p-bote와 같은 다양한 메시징 애플리케이션에서 지원할 수 있고 실제로 지원되고 있습니다. 네트워크 수준에서는 Freenet과 같은 대안 네트워크가 이러한 서비스를 제공합니다. 우리는 I2P router 수준에서 이 목표를 추구하지 않기로 결정했습니다.
유사한 시스템
I2P의 아키텍처는 메시지 지향 미들웨어의 개념, DHT의 토폴로지, 자유 라우팅 mixnet의 익명성과 암호화, 그리고 패킷 교환 네트워킹의 적응성을 기반으로 구축됩니다. 하지만 그 가치는 새로운 개념이나 알고리즘에서 나오는 것이 아니라, 기존 시스템과 논문들의 연구 결과를 조합한 신중한 엔지니어링에서 나옵니다. 기술적 및 기능적 비교를 위해 검토할 가치가 있는 몇 가지 유사한 노력들이 있지만, 특히 두 가지를 여기서 언급하겠습니다 — Tor와 Freenet입니다.
네트워크 비교 페이지 도 참조하세요. 이러한 설명은 jrandom이 2003년에 작성한 것으로 현재는 정확하지 않을 수 있습니다.
Tor
처음 보기에 Tor와 I2P는 기능적이고 익명성 관련해서 많은 유사점을 가지고 있습니다. I2P의 개발은 우리가 Tor의 초기 단계 노력을 인식하기 전에 시작되었지만, 원래 onion routing과 ZKS 노력의 많은 교훈들이 I2P의 설계에 통합되었습니다. 디렉토리 서버를 사용하는 본질적으로 신뢰할 수 있는 중앙집중식 시스템을 구축하는 대신, I2P는 각 피어가 사용 가능한 리소스를 가장 잘 활용하는 방법을 결정하기 위해 다른 router들을 프로파일링하는 책임을 지는 자체 조직화 네트워크 데이터베이스를 가지고 있습니다. 또 다른 주요 차이점은 I2P와 Tor 모두 계층화되고 순서가 지정된 경로(tunnel과 circuit/stream)를 사용하지만, I2P는 근본적으로 패킷 교환 네트워크인 반면 Tor는 근본적으로 회선 교환 네트워크라는 것입니다. 이로 인해 I2P는 혼잡이나 기타 네트워크 장애를 투명하게 우회하고, 중복 경로를 운영하며, 사용 가능한 리소스에 걸쳐 데이터 로드 밸런싱을 할 수 있습니다. Tor는 통합된 outproxy 발견 및 선택을 제공함으로써 유용한 outproxy 기능을 제공하는 반면, I2P는 그러한 애플리케이션 계층 결정을 I2P 위에서 실행되는 애플리케이션에게 맡깁니다. 실제로 I2P는 TCP와 유사한 스트리밍 라이브러리 자체를 애플리케이션 계층으로 외부화하여, 개발자들이 다양한 전략을 실험하고 도메인 특정 지식을 활용하여 더 나은 성능을 제공할 수 있도록 합니다.
익명성 관점에서 보면, 핵심 네트워크들을 비교했을 때 많은 유사점이 있습니다. 그러나 몇 가지 주요 차이점이 있습니다. 내부 공격자나 대부분의 외부 공격자를 다룰 때, I2P의 단방향 tunnel은 단순히 플로우 자체만 보더라도 Tor의 양방향 회로가 노출하는 것보다 절반의 트래픽 데이터만 노출합니다. HTTP 요청과 응답은 Tor에서는 같은 경로를 따르지만, I2P에서는 요청을 구성하는 패킷들은 하나 이상의 아웃바운드 tunnel을 통해 나가고, 응답을 구성하는 패킷들은 하나 이상의 서로 다른 인바운드 tunnel을 통해 돌아옵니다. I2P의 피어 선택 및 순서 지정 전략이 전임자 공격(predecessor attack)을 충분히 해결해야 하지만, 양방향 tunnel로의 전환이 필요하다면, 단순히 같은 router들을 따라 인바운드와 아웃바운드 tunnel을 구축할 수 있습니다.
Tor의 망원경식 터널 생성 사용에서 또 다른 익명성 문제가 발생하는데, 회로의 셀이 적대자의 노드를 통과할 때 간단한 패킷 카운팅과 타이밍 측정으로 적대자가 회로 내에서 어디에 위치하는지에 대한 통계적 정보가 노출됩니다. I2P는 단일 메시지로 단방향 터널 생성을 사용하여 이러한 데이터가 노출되지 않도록 합니다. 터널 내 위치를 보호하는 것은 중요한데, 그렇지 않으면 적대자가 일련의 강력한 predecessor, intersection, 그리고 트래픽 확인 공격을 수행할 수 있기 때문입니다.
전반적으로 Tor와 I2P는 각각의 초점에서 서로를 보완합니다 — Tor는 고속 익명 인터넷 outproxy 제공에 중점을 두는 반면, I2P는 그 자체로 탈중앙화된 복원력 있는 네트워크 제공에 중점을 둡니다. 이론적으로는 두 시스템 모두 두 가지 목적을 달성하는 데 사용될 수 있지만, 제한된 개발 자원을 고려할 때 각각 고유한 장단점을 가지고 있습니다. I2P 개발자들은 I2P의 설계를 활용하기 위해 Tor를 수정하는 데 필요한 단계들을 고려해왔지만, 자원 부족 상황에서 Tor의 실용성에 대한 우려는 I2P의 패킷 스위칭 아키텍처가 희소한 자원을 더 효과적으로 활용할 수 있을 것임을 시사합니다.
Freenet
Freenet은 I2P 설계 초기 단계에서 큰 역할을 했습니다. 네트워크 내에 완전히 포함된 활발한 가명 커뮤니티의 실행 가능성을 입증하고, outproxy에 내재된 위험을 피할 수 있음을 보여주었습니다. I2P의 첫 번째 씨앗은 Freenet을 위한 대체 통신 계층으로 시작되었으며, 확장 가능하고 익명성이 보장되며 안전한 지점 간 통신의 복잡성을 검열 저항적인 분산 데이터 저장소의 복잡성으로부터 분리하려는 시도였습니다. 그러나 시간이 지나면서 Freenet 알고리즘에 내재된 익명성과 확장성 문제들로 인해 I2P는 Freenet의 구성 요소가 아닌 범용 익명 통신 계층 제공에만 엄격히 집중해야 한다는 것이 명확해졌습니다. 수년에 걸쳐 Freenet 개발자들은 기존 설계의 약점을 인식하게 되었고, 실질적인 익명성을 제공하기 위해서는 “premix” 계층이 필요할 것이라고 제안하기에 이르렀습니다. 다시 말해, Freenet은 I2P나 Tor와 같은 mixnet 위에서 실행되어야 하며, “클라이언트 노드"가 mixnet을 통해 “서버 노드"에 데이터를 요청하고 게시하면, 서버 노드가 Freenet의 휴리스틱 분산 데이터 저장 알고리즘에 따라 데이터를 가져오고 저장하는 방식이 필요합니다.
Freenet의 기능은 I2P의 기능과 매우 상호 보완적입니다. Freenet은 중간 및 높은 지연 시간 시스템을 운영하기 위한 많은 도구를 기본적으로 제공하는 반면, I2P는 적절한 익명성을 제공하기에 적합한 저지연 mix 네트워크를 기본적으로 제공합니다. 엔지니어링, 익명성, 보안 및 자원 할당 관점에서 mixnet을 검열 저항성 분산 데이터 저장소와 분리하는 논리는 여전히 자명해 보이므로, 향후 Freenet 팀이 I2P나 Tor와 같은 기존 mixnet을 단순히 재사용하거나 (필요에 따라 개선을 돕는) 방향이 아니더라도 그러한 방향으로 노력을 추진하기를 바랍니다.
부록 A: 애플리케이션 레이어
I2P 자체는 실제로 많은 일을 하지 않습니다 — 단순히 원격 목적지로 메시지를 보내고 로컬 목적지를 대상으로 하는 메시지를 받을 뿐입니다 — 흥미로운 작업의 대부분은 그 위의 계층에서 이루어집니다. 그 자체로 I2P는 익명이고 안전한 IP 계층으로 볼 수 있으며, 번들로 제공되는 streaming library 는 그 위에서 익명이고 안전한 TCP 계층을 구현한 것입니다. 그 외에도 I2PTunnel 은 I2P 네트워크로 들어가거나 나가기 위한 일반적인 TCP 프록시 시스템을 제공하며, 다양한 네트워크 애플리케이션이 최종 사용자를 위한 추가 기능을 제공합니다.
스트리밍 라이브러리
I2P streaming 라이브러리는 일반적인 스트리밍 인터페이스(TCP 소켓을 모방)로 볼 수 있으며, 구현체는 I2P의 높은 지연시간을 고려하여 여러 최적화가 적용된 sliding window protocol 을 지원합니다. 개별 스트림은 최대 패킷 크기 및 기타 옵션을 조정할 수 있지만, 압축된 4KB의 기본값은 손실된 메시지 재전송의 대역폭 비용과 여러 메시지의 지연시간 사이의 합리적인 절충안으로 보입니다.
또한, 후속 메시지의 상대적으로 높은 비용을 고려하여, streaming library의 메시지 스케줄링 및 전달 프로토콜은 전달되는 개별 메시지가 가능한 한 많은 정보를 포함할 수 있도록 최적화되었습니다. 예를 들어, streaming library를 통해 프록시된 작은 HTTP 트랜잭션은 단일 라운드 트립으로 완료될 수 있습니다 — 첫 번째 메시지는 SYN, FIN 및 작은 페이로드(일반적으로 HTTP 요청이 맞음)를 묶고, 응답은 SYN, FIN, ACK 및 작은 페이로드(많은 HTTP 응답이 맞음)를 묶습니다. SYN/FIN/ACK가 수신되었음을 HTTP 서버에 알리기 위해 추가 ACK를 전송해야 하지만, 로컬 HTTP 프록시는 전체 응답을 즉시 브라우저에 전달할 수 있습니다.
그러나 전반적으로 스트리밍 라이브러리는 슬라이딩 윈도우, 혼잡 제어 알고리즘(슬로우 스타트와 혼잡 회피 모두), 그리고 일반적인 패킷 동작(ACK, SYN, FIN, RST 등)을 포함하여 TCP의 추상화와 많은 유사점을 가지고 있습니다.
네이밍 라이브러리 및 주소록
자세한 정보는 명명 및 주소록 페이지를 참조하세요.
개발자: mihi, Ragnarok
I2P 내에서의 네이밍은 가능성의 전 스펙트럼에 걸친 지지자들과 함께 처음부터 자주 논의되어온 주제입니다. 그러나 보안 통신과 탈중앙화 운영에 대한 I2P의 본질적인 요구사항을 고려할 때, 전통적인 DNS 방식의 네이밍 시스템은 명백히 적합하지 않으며, “다수결” 투표 시스템도 마찬가지입니다. 대신, I2P는 일반적인 네이밍 라이브러리와 로컬 이름-destination 매핑에서 작동하도록 설계된 기본 구현, 그리고 “Address Book"이라고 불리는 선택적 애드온 애플리케이션을 함께 제공합니다. address book은 신뢰의 네트워크 기반의 보안, 분산, 인간이 읽을 수 있는 네이밍 시스템으로, 모든 인간이 읽을 수 있는 이름이 전역적으로 고유해야 한다는 요구사항을 포기하고 로컬 고유성만을 요구함으로써 이를 달성합니다. I2P의 모든 메시지는 destination으로 암호화 주소가 지정되지만, 서로 다른 사람들은 서로 다른 destination을 참조하는 “Alice"에 대한 로컬 address book 항목을 가질 수 있습니다. 사람들은 여전히 신뢰의 네트워크에서 지정된 피어들의 게시된 address book을 가져오거나, 제3자를 통해 제공된 항목을 추가하거나, (일부 사람들이 선착순 등록 시스템을 사용하여 일련의 게시된 address book을 조직하는 경우) 이러한 address book을 네임 서버로 취급하여 전통적인 DNS를 모방하는 방식으로 새로운 이름을 발견할 수 있습니다.
하지만 I2P는 DNS와 유사한 서비스 사용을 권장하지 않습니다. 사이트 탈취로 인한 피해가 엄청날 수 있고, 안전하지 않은 destination은 가치가 없기 때문입니다. DNSsec 자체도 여전히 등록기관과 인증 기관에 의존하는 반면, I2P에서는 destination으로 보내는 요청이 해당 destination의 공개 키로 암호화되어 가로채이거나 응답이 위조될 수 없으며, destination 자체가 단지 한 쌍의 공개 키와 인증서일 뿐입니다. 반면 DNS 방식 시스템은 조회 경로상의 모든 네임 서버가 간단한 서비스 거부 공격과 스푸핑 공격을 수행할 수 있게 합니다. 중앙화된 인증 기관이 서명한 응답을 인증하는 인증서를 추가하면 악의적인 네임서버 문제의 대부분을 해결할 수 있지만, 재생 공격과 악의적인 인증 기관 공격의 여지는 여전히 남아있을 것입니다.
투표 방식 명명은 특히 익명 시스템에서 Sybil 공격의 효과성을 고려할 때 위험합니다. 공격자가 임의로 많은 수의 피어를 생성하고 각각으로 “투표"하여 특정 이름을 탈취할 수 있기 때문입니다. 작업 증명 방법을 사용하여 신원을 무료가 아니게 만들 수 있지만, 네트워크가 성장함에 따라 온라인 투표를 위해 모든 사람에게 연락하는 데 필요한 부하는 불가능하며, 전체 네트워크를 조회하지 않으면 서로 다른 답변 집합에 도달할 수 있습니다.
그러나 인터넷과 마찬가지로, I2P는 네이밍 시스템의 설계와 운영을 (IP와 유사한) 통신 계층에서 분리하고 있습니다. 번들된 네이밍 라이브러리는 대안 네이밍 시스템들이 연결될 수 있는 간단한 서비스 제공자 인터페이스를 포함하고 있어, 최종 사용자들이 선호하는 네이밍 트레이드오프의 종류를 선택할 수 있도록 합니다.
I2PTunnel
개발자: mihi
I2PTunnel은 아마도 I2P의 가장 인기 있고 다재다능한 클라이언트 애플리케이션으로, I2P 네트워크 안팎으로의 일반적인 프록시 기능을 제공합니다. I2PTunnel은 네 개의 별도 프록시 애플리케이션으로 볼 수 있습니다 — 인바운드 TCP 연결을 수신하여 지정된 I2P destination으로 전달하는 “client”, HTTP 프록시처럼 작동하며 요청을 적절한 I2P destination으로 전달하는 “httpclient”(“eepproxy"라고도 함, 필요한 경우 네이밍 서비스 조회 후), destination에서 인바운드 I2P 스트리밍 연결을 수신하여 지정된 TCP 호스트+포트로 전달하는 “server”, 그리고 HTTP 요청과 응답을 파싱하여 더 안전한 작동을 가능하게 하는 “server"를 확장한 “httpserver"입니다. 추가적인 “socksclient” 애플리케이션이 있지만, 앞서 언급한 이유로 그 사용은 권장되지 않습니다.
I2P 자체는 outproxy 네트워크가 아닙니다. 데이터를 mix로 전달하고 mix에서 외부로 전달하는 mix net에 내재된 익명성과 보안 우려로 인해 I2P의 설계는 외부 리소스를 요구하지 않고 사용자의 요구를 충족할 수 있는 익명 네트워크를 제공하는 데 집중되어 있습니다. 그러나 I2PTunnel “httpclient” 애플리케이션은 outproxy를 위한 연결점을 제공합니다. 요청된 호스트명이 “.i2p"로 끝나지 않으면, 사용자가 제공한 outproxy 세트에서 임의의 목적지를 선택하여 요청을 전달합니다. 이러한 목적지는 단순히 outproxy 실행을 명시적으로 선택한 자원봉사자들이 운영하는 I2PTunnel “server” 인스턴스입니다. 기본적으로 누구도 outproxy가 아니며, outproxy를 실행한다고 해서 다른 사람들에게 자동으로 당신을 통해 프록시하라고 알려주지 않습니다. outproxy에는 고유한 취약점이 있지만, I2P 사용에 대한 간단한 개념 증명을 제공하고 일부 사용자에게는 충분할 수 있는 위협 모델 하에서 일부 기능을 제공합니다.
I2PTunnel은 사용 중인 대부분의 애플리케이션을 활성화합니다. 웹서버를 가리키는 “httpserver"를 통해 누구나 자신만의 익명 웹사이트(또는 “I2P Site”)를 운영할 수 있습니다 — 이 목적을 위해 웹서버가 I2P에 번들로 포함되어 있지만, 어떤 웹서버든 사용할 수 있습니다. 누구나 익명으로 호스팅되는 IRC 서버 중 하나를 가리키는 “client"를 실행할 수 있으며, 각 서버는 로컬 IRCd를 가리키는 “server"를 실행하고 자체 “client” tunnel을 통해 IRCd 간에 통신합니다. 최종 사용자는 또한 I2Pmail의 POP3 및 SMTP 대상을 가리키는 “client” tunnel을 가지고 있으며(이는 단순히 POP3 및 SMTP 서버를 가리키는 “server” 인스턴스임), I2P의 CVS 서버를 가리키는 “client” tunnel을 통해 익명 개발이 가능합니다. 때로는 사람들이 NNTP 서버를 가리키는 “server” 인스턴스에 접근하기 위해 “client” 프록시를 실행하기도 했습니다.
I2PSnark
I2PSnark 개발: jrandom 외, mjw 의 Snark 클라이언트에서 포팅
I2P 설치에 포함된 I2PSnark는 멀티토렌트 기능을 갖춘 간단한 익명 BitTorrent 클라이언트를 제공하며, 일반 HTML 웹 인터페이스를 통해 모든 기능을 제공합니다.
I2Pmail / Susimail
개발자: postman, susi23, mastiejaner
I2Pmail은 애플리케이션이라기보다는 서비스에 가깝습니다. postman은 mastiejaner와 함께 개발된 일련의 구성 요소에 접근하는 I2PTunnel 인스턴스를 통해 POP3 및 SMTP 서비스로 내부 및 외부 이메일을 모두 제공하여, 사람들이 선호하는 메일 클라이언트를 사용해 익명으로 메일을 주고받을 수 있도록 합니다. 하지만 대부분의 메일 클라이언트는 상당한 식별 정보를 노출하기 때문에, I2P는 I2P의 익명성 요구사항을 염두에 두고 특별히 구축된 susi23의 웹 기반 susimail 클라이언트를 번들로 제공합니다. I2Pmail/mail.i2p 서비스는 투명한 바이러스 필터링과 함께 hashcash로 강화된 할당량을 통한 서비스 거부 공격 방지 기능을 제공합니다. 또한, 각 사용자는 mail.i2p outproxy를 통한 전달 전에 자신의 배칭 전략을 제어할 수 있습니다. 이 outproxy는 mail.i2p SMTP 및 POP3 서버와는 별개입니다. outproxy와 inproxy 모두 I2P 자체를 통해 mail.i2p SMTP 및 POP3 서버와 통신하므로, 익명이 아닌 해당 위치들이 손상되더라도 사용자의 메일 계정이나 활동 패턴에 접근할 수 없습니다.