개요
0.9.32 릴리스부터 개별 라우터 주소 내의 호스트 이름을 더 이상 사용하지 않도록 netdb 사양을 업데이트합니다. 모든 I2P 구현에서 호스트 이름이 구성된 발행 라우터는 발행하기 전에 호스트 이름을 IP로 대체해야 하며, 다른 라우터는 호스트 이름이 포함된 주소를 무시해야 합니다. 라우터는 발행된 호스트 이름의 DNS 조회를 수행하지 않아야 합니다.
동기
호스트 이름은 I2P 초기부터 라우터 주소에 허용되었습니다. 그러나 공용 호스트 이름(몇몇 사용자만 가지고 있는 것)과 수동 설정(몇몇 사용자만 수행하는 것)을 모두 필요로 하기 때문에, 거의 모든 라우터가 호스트 이름을 발행하지 않습니다. 최근 샘플에서 0.7%의 라우터가 호스트 이름을 발행하고 있었습니다.
호스트 이름의 원래 목적은 IP가 변경될 때 연결이 끊어지지 않도록 동적 DNS 서비스(예: http://dyn.com/dns/)를 사용하여 자주 변경되는 IP를 가진 사용자를 돕는 것이었습니다. 그러나 당시 네트워크는 작았고 라우터 정보 만료가 더 길었습니다. 또한, Java 코드는 로컬 IP가 변경되었을 때 라우터를 재시작하거나 라우터 정보를 다시 발행하는 작동 로직이 없었습니다.
초기 I2P에서는 IPv6을 지원하지 않았기 때문에 호스트 이름을 IPv4 또는 IPv6 주소로 해석하는 복잡성이 없었습니다.
Java I2P에서는 구성된 호스트 이름을 두 발행 전송 모두로 전파하는 것이 항상 도전 과제였으며, IPv6과 함께 상황은 더욱 복잡해졌습니다. 듀얼 스택 호스트가 호스트 이름과 리터럴 IPv6 주소를 모두 발행해야 하는지는 불명확합니다. 호스트 이름은 SSU 주소에 대해 발행되지만 NTCP 주소에는 발행되지 않습니다.
최근 DNS 문제는 조지아 공과 대학의 연구에 의해 간접적 및 직접적으로 언급되었습니다. 연구자들은 발행된 호스트 이름을 가진 다수의 플러드필을 실행했습니다. 즉각적인 문제는 만약 로컬 DNS가 손상된 소수의 사용자에게 I2P가 완전히 중단된다는 점이었습니다.
큰 문제는 일반적으로 DNS이며 DNS(활성 또는 수동)가 네트워크를 매우 빠르게 열거하는 데 사용될 수 있는 방법입니다. 특히 발행 라우터가 플러드필인 경우에 그렇습니다. 유효하지 않은 호스트 이름이나 응답이 없거나 느리거나 악의적인 DNS 응답자는 추가 공격에 사용될 수 있습니다. EDNS0은 추가 열거 또는 공격 시나리오를 제공할 수 있습니다. DNS 조회 기반의 공격은 라우터 간 연결 시간, 연결 그래프 구축, 트래픽 추정 및 기타 추론을 드러낼 수 있습니다.
또한, 조지아 공과 대학의 David Dagon이 이끄는 그룹은 프라이버시 중심 애플리케이션에서 DNS에 대한 여러 우려를 제기했습니다. DNS 조회는 일반적으로 애플리케이션이 제어하지 않는 낮은 수준의 라이브러리에 의해 수행됩니다. 이들 라이브러리는 익명화 위해 설계되지 않았으며, 애플리케이션에 의해 세부 제어를 제공하지 않을 수 있으며, 그들의 출력은 지문이 남길 수 있습니다. Java 라이브러리는 특히 문제가 될 수 있지만, 이는 Java 문제에 국한되지 않습니다. 일부 라이브러리는 거부될 수 있는 DNS ANY 쿼리를 사용합니다. 모두 수동 DNS 모니터링과 다양한 조직에서 이용 가능한 쿼리가 널리 퍼져 있어 이러한 상황은 더욱 우려스럽습니다. 모든 DNS 모니터링과 공격은 I2P 라우터의 관점에서 벗어나 있으며 네트워크 내 I2P 자원이 거의 필요하지 않거나 전혀 필요하지 않으며 기존 구현의 수정이 필요 없습니다.
가능한 문제를 완전히 생각해 본 것은 아니지만 공격 표면은 상당히 큰 것 같습니다. 네트워크를 열거하고 관련 데이터를 수집할 수 있는 다른 방법이 있지만, DNS 공격은 훨씬 더 쉽고 빠르며 덜 탐지될 수 있습니다.
이론적으로 라우터 구현은 정교한 3자 DNS 라이브러리를 사용하는 것으로 전환할 수 있지만, 이것은 매우 복잡하고 유지 관리 부담이 되며 I2P 개발자의 핵심 전문 영역을 벗어납니다.
Java 0.9.31에서는 정지도 문제 해결, DNS 캐시 시간 증가, DNS 부정적 캐시 구현 등 즉각적인 해결책이 포함되었습니다. 물론 캐시 시간을 늘리면 처음부터 routerinfos에 호스트 이름을 갖는 이점이 줄어듭니다.
그러나 이러한 변화는 단기 완화만 제공하며 상기의 근본 문제를 해결하지 못합니다. 따라서 가장 간단하고 완전한 해결책은 라우터 정보에서 호스트 이름을 금지하여 이를 위한 DNS 조회를 제거하는 것입니다.
설계
라우터 정보 발행 코드의 경우 구현자는 호스트 이름에 대한 구성 옵션을 비활성화/제거하거나 발행 시 호스트 이름을 IP로 변환하는 두 가지 선택을 할 수 있습니다. 어느 경우든 라우터는 IP가 변경되면 즉시 다시 발행해야 합니다.
라우터 정보 검증 및 전송 연결 코드를 위해 구현자는 호스트 이름이 포함된 라우터 주소를 무시하고 IP가 포함된 다른 발행 주소를 사용해야 합니다. 라우터 정보에 IP가 포함된 주소가 없으면 발행된 라우터에 연결하지 않아야 합니다. 어떤 경우에도 라우터는 발행된 호스트 이름의 DNS 조회를 직접 또는 기저 라이브러리를 통해 수행하지 않아야 합니다.
사양
NTCP 및 SSU 전송 사양을 변경하여 “host” 매개변수는 호스트 이름이 아닌 IP여야 하며 라우터는 호스트 이름이 포함된 개별 라우터 주소를 무시해야 함을 명시합니다.
이는 SSU 주소의 “ihost0”, “ihost1” 및 “ihost2” 매개변수에도 적용됩니다. 라우터는 호스트 이름이 포함된 인트로듀서 주소를 무시해야 합니다.
메모
이 제안은 리시드 호스트에 대한 호스트 이름을 다루지 않습니다. 리시드 호스트에 대한 DNS 조회는 훨씬 더 드물긴 하지만 문제를 일으킬 수 있습니다. 필요한 경우, 이는 URL의 하드코딩된 목록에서 호스트 이름을 IP로 대체함으로써 간단히 해결될 수 있습니다; 명세 또는 코드 변경이 필요하지 않습니다.
마이그레이션
이 제안은 점진적 마이그레이션 없이 즉시 구현할 수 있습니다. 호스트 이름을 발행하는 라우터는 거의 없으며, 발행하는 경우 일반적으로 모든 주소에 대해 호스트 이름을 발행하지 않기 때문입니다.
라우터는 발행된 라우터의 버전을 체크할 필요가 없으며, 다양한 라우터 구현 간의 조정된 릴리스 또는 공통 전략이 필요하지 않습니다.
호스트 이름을 계속 발행하는 라우터의 경우 하나의 수신 연결이 적으며, 결국 수신 터널을 구축하기 어려울 수 있습니다.
영향을 더욱 최소화하기 위해 구현자는 플러드필 라우터에 대해서만 호스트 이름이 포함된 라우터 주소를 무시하거나 발행된 버전이 0.9.32 미만인 라우터에 대해 무시할 수 있으며, 모든 라우터에서 호스트 이름을 무시합니다. 이는 후속 릴리스에서 적용할 수 있습니다.