이 번역은 기계 학습을 사용하여 생성되었으며 100% 정확하지 않을 수 있습니다. 영어 버전 보기

I2CP 개요

I2P 클라이언트 프로토콜(I2CP) 개요 - 세션 관리, 옵션, 페이로드 형식 및 다중화.

개요

I2P 클라이언트 프로토콜(I2CP)은 라우터와 네트워크를 통해 통신하려는 모든 클라이언트 간의 책임을 명확히 분리합니다. I2CP는 단일 TCP 소켓을 통해 메시지를 송수신함으로써 안전하고 비동기적인 메시징을 가능하게 합니다. I2CP를 사용하면 클라이언트 애플리케이션이 라우터에게 자신이 누구인지(자신의 “대상”), 어떤 익명성·신뢰성·지연 시간 간의 트레이드오프를 선택할지, 그리고 메시지를 어디로 보낼지를 지정할 수 있습니다. 반대로 라우터는 I2CP를 통해 메시지가 도착했을 때 클라이언트에게 알리거나 일부 터널 사용을 위한 인증을 요청할 수 있습니다.

프로토콜 자체는 자바로 구현되어 클라이언트 SDK를 제공합니다. 이 SDK는 I2CP의 클라이언트 측을 구현하는 i2p.jar 패키지로 제공됩니다. 클라이언트는 라우터 자체와 I2CP의 라우터 측을 포함하는 router.jar 패키지에 접근할 필요가 절대 없습니다. 자바가 아닌 클라이언트의 경우 TCP 스타일 연결을 위한 스트리밍 라이브러리 도 구현해야 합니다.

애플리케이션은 암호화 처리를 클라이언트가 직접 다루지 않아도 되는 간단한 익명 메시징(SAM) 프로토콜을 사용함으로써 기본 I2CP와 스트리밍데이터그램 라이브러리를 활용할 수 있습니다. 또한 클라이언트는 HTTP, CONNECT, SOCKS 4/4a/5 프록시 중 하나를 통해 네트워크에 접근할 수 있습니다. 또는 Java 클라이언트의 경우 ministreaming.jar와 streaming.jar에 포함된 라이브러리에 직접 접근할 수도 있습니다. 따라서 Java 애플리케이션과 비-Java 애플리케이션 모두를 위한 여러 가지 옵션이 존재합니다.

클라이언트 측 종단 간 암호화(I2CP 연결을 통한 데이터 암호화)는 I2P 릴리스 0.6에서 비활성화되었으며, 라우터에서 구현된 ElGamal/AES 종단 간 암호화만 유지되었습니다. 클라이언트 라이브러리가 여전히 구현해야 하는 유일한 암호화 기술은 LeaseSet세션 구성 을 위한 DSA 공개/개인 키 서명과 해당 키 관리입니다.

표준 I2P 설치에서는 포트 7654를 외부 Java 클라이언트가 I2CP를 통해 로컬 라우터와 통신하는 데 사용합니다. 기본적으로 라우터는 주소 127.0.0.1에 바인딩됩니다. 0.0.0.0에 바인딩하려면 라우터 고급 설정 옵션 i2cp.tcp.bindAllInterfaces=true를 설정하고 라우터를 재시작해야 합니다. 라우터와 동일한 JVM 내의 클라이언트는 내부 JVM 인터페이스를 통해 메시지를 직접 라우터에 전달합니다.

일부 라우터 및 클라이언트 구현은 i2cp.SSL=true 옵션으로 구성할 경우 SSL을 통한 외부 연결을 지원할 수도 있습니다. SSL은 기본값이 아니지만, 공개 인터넷에 노출될 수 있는 모든 트래픽에 대해서는 강력히 권장됩니다. SSL이 활성화되지 않으면 인증을 위한 사용자 이름/비밀번호(있는 경우), 대상(Destination)개인 키(Private Key)서명용 개인 키(Signing Private Key) 가 모두 평문으로 전송됩니다. 일부 라우터 및 클라이언트 구현은 도메인 소켓을 통한 외부 연결도 지원할 수 있습니다.

I2CP 프로토콜 사양

전체 프로토콜 사양은 I2CP 사양 페이지 를 참조하세요.

I2CP 초기화

클라이언트가 라우터에 연결하면, 먼저 단일 프로토콜 버전 바이트(0x2A)를 보냅니다. 그 후 GetDate 메시지 를 전송하고 SetDate 메시지 응답을 기다립니다. 다음으로 세션 설정을 포함하는 CreateSession 메시지 를 전송합니다. 이후 라우터로부터 수신 터널이 생성되었음을 알리는 RequestLeaseSet 메시지 를 수신할 때까지 대기한 후, 서명된 LeaseSet을 포함하는 CreateLeaseSetMessage로 응답합니다. 이제 클라이언트는 다른 I2P 목적지로 연결을 시작하거나, 다른 곳으로부터 연결을 수신할 수 있습니다.

I2CP 옵션

라우터 측 옵션

다음 옵션들은 일반적으로 세션 생성 메시지 또는 세션 재구성 메시지 에 포함된 SessionConfig 를 통해 라우터에 전달됩니다.

Router-side Options
OptionAs Of ReleaseRecommended ArgumentsAllowable RangeDefaultDescription
clientMessageTimeout8*1000 - 120*100060*1000The timeout (ms) for all sent messages. Unused. See the protocol specification for per-message settings.
crypto.lowTagThreshold0.9.21-12830Minimum number of ElGamal/AES Session Tags before we send more. Recommended: approximately tagsToSend * 2/3
crypto.ratchet.inboundTags0.9.471-?160Inbound tag window for ECIES-X25519-AEAD-Ratchet. Local inbound tagset size. See proposal 144.
crypto.ratchet.outboundTags0.9.471-?160Outbound tag window for ECIES-X25519-AEAD-Ratchet. Advisory to send to the far-end in the options block. See proposal 144.
crypto.tagsToSend0.9.21-12840Number of ElGamal/AES Session Tags to send at a time. For clients with relatively low bandwidth per-client-pair (IRC, some UDP apps), this may be set lower.
explicitPeersnullComma-separated list of Base 64 Hashes of peers to build tunnels through; for debugging only
i2cp.dontPublishLeaseSettrue, falsefalseShould generally be set to true for clients and false for servers
i2cp.fastReceive0.9.4true, falsefalseIf true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
i2cp.leaseSetAuthType0.9.4100-20The type of authentication for encrypted LS2. 0 for no per-client authentication (the default); 1 for DH per-client authentication; 2 for PSK per-client authentication. See proposal 123.
i2cp.leaseSetEncType0.9.384,00-65535,...0The encryption type to be used, as of 0.9.38. Interpreted client-side, but also passed to the router in the SessionConfig, to declare intent and check support. As of 0.9.39, may be comma-separated values for multiple types. See PublicKey in common structures spec for values. See proposals 123, 144, and 145.
i2cp.leaseSetOfflineExpiration0.9.38The expiration of the offline signature, 4 bytes, seconds since the epoch. See proposal 123.
i2cp.leaseSetOfflineSignature0.9.38The base 64 of the offline signature. See proposal 123.
i2cp.leaseSetPrivKey0.9.41A base 64 X25519 private key for the router to use to decrypt the encrypted LS2 locally, only if per-client authentication is enabled. Optionally preceded by the key type and ':'. Only "ECIES_X25519:" is supported, which is the default. See proposal 123. Do not confuse with i2cp.leaseSetPrivateKey which is for the leaseset encryption keys.
i2cp.leaseSetSecret0.9.39""Base 64 encoded UTF-8 secret used to blind the leaseset address. See proposal 123.
i2cp.leaseSetTransientPublicKey0.9.38[type:]b64 The base 64 of the transient private key, prefixed by an optional sig type number or name, default DSA_SHA1. See proposal 123.
i2cp.leaseSetType0.9.381,3,5,71-2551The type of leaseset to be sent in the CreateLeaseSet2 Message. Interpreted client-side, but also passed to the router in the SessionConfig, to declare intent and check support. See proposal 123.
i2cp.messageReliabilityBestEffort, NoneBestEffortGuaranteed is disabled; None implemented in 0.8.1; the streaming lib default is None as of 0.8.1, the client side default is None as of 0.9.4
i2cp.password0.8.2stringFor authorization, if required by the router. If the client is running in the same JVM as a router, this option is not required. Warning - username and password are sent in the clear to the router, unless using SSL (i2cp.SSL=true). Authorization is only recommended when using SSL.
i2cp.username0.8.2string
inbound.allowZeroHoptrue, falsetrueIf incoming zero hop tunnel is allowed
outbound.allowZeroHoptrue, falsetrueIf outgoing zero hop tunnel is allowed
inbound.backupQuantitynumber from 0 to 3No limit0Number of redundant fail-over for tunnels in
outbound.backupQuantitynumber from 0 to 3No limit0Number of redundant fail-over for tunnels out
inbound.IPRestrictionnumber from 0 to 40 to 42Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
outbound.IPRestrictionnumber from 0 to 40 to 42Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0 to disable.
inbound.lengthnumber from 0 to 30 to 73Length of tunnels in
outbound.lengthnumber from 0 to 30 to 73Length of tunnels out
inbound.lengthVariancenumber from -1 to 2-7 to 70Random amount to add or subtract to the length of tunnels in. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
outbound.lengthVariancenumber from -1 to 2-7 to 70Random amount to add or subtract to the length of tunnels out. A positive number x means add a random amount from 0 to x inclusive. A negative number -x means add a random amount from -x to x inclusive. The router will limit the total length of the tunnel to 0 to 7 inclusive. The default variance was 1 prior to release 0.7.6.
inbound.nicknamestringName of tunnel - generally used in routerconsole, which will use the first few characters of the Base64 hash of the destination by default.
outbound.nicknamestringName of tunnel - generally ignored unless inbound.nickname is unset.
outbound.priority0.9.4number from -25 to 25-25 to 250Priority adjustment for outbound messages. Higher is higher priority.
inbound.quantitynumber from 1 to 31 to 162Number of tunnels in. Limit was increased from 6 to 16 in release 0.9; however, numbers higher than 6 are incompatible with older releases.
outbound.quantitynumber from 1 to 3No limit2Number of tunnels out
inbound.randomKey0.9.17Base 64 encoding of 32 random bytesUsed for consistent peer ordering across restarts.
outbound.randomKey0.9.17Base 64 encoding of 32 random bytes
inbound.*Any other options prefixed with "inbound." are stored in the "unknown options" properties of the inbound tunnel pool's settings.
outbound.*Any other options prefixed with "outbound." are stored in the "unknown options" properties of the outbound tunnel pool's settings.
shouldBundleReplyInfo0.9.2true, falsetrueSet to false to disable ever bundling a reply LeaseSet. For clients that do not publish their LeaseSet, this option must be true for any reply to be possible. "true" is also recommended for multihomed servers with long connection times.

Setting to “false” may save significant outbound bandwidth, especially if the client is configured with a large number of inbound tunnels (Leases). If replies are still required, this may shift the bandwidth burden to the far-end client and the floodfill. There are several cases where “false” may be appropriate:

  • Unidirectional communication, no reply required
  • LeaseSet is published and higher reply latency is acceptable
  • LeaseSet is published, client is a “server”, all connections are inbound so the connecting far-end destination obviously has the leaseset already. Connections are either short, or it is acceptable for latency on a long-lived connection to temporarily increase while the other end re-fetches the LeaseSet after expiration. HTTP servers may fit these requirements.
참고: 큰 수량, 길이 또는 분산 설정은 성능이나 신뢰성에 심각한 문제를 일으킬 수 있습니다.

참고: 릴리스 0.7.7부터 옵션 이름과 값은 UTF-8 인코딩을 사용해야 합니다. 이는 주로 닉네임에 유용합니다. 해당 릴리스 이전에는 멀티바이트 문자를 포함한 옵션이 손상되었습니다. 옵션은 매핑 으로 인코딩되므로, 모든 옵션 이름과 값은 최대 255바이트(문자가 아닌)로 제한됩니다.

클라이언트 측 옵션

다음 옵션들은 클라이언트 측에서 해석되며, I2PClient.createSession() 호출을 통해 I2PSession에 전달될 경우 해석됩니다. 스트리밍 라이브러리도 이러한 옵션들을 I2CP로 전달해야 합니다. 다른 구현체는 다를 수 있는 기본값을 가질 수 있습니다.

Client-side Options
OptionAs Of ReleaseRecommended ArgumentsAllowable RangeDefaultDescription
i2cp.closeIdleTime0.7.11800000300000 minimum(ms) Idle time required (default 30 minutes)
i2cp.closeOnIdle0.7.1true, falsefalseClose I2P session when idle
i2cp.encryptLeaseSet0.7.1true, falsefalseEncrypt the lease
i2cp.fastReceive0.9.4true, falsetrueIf true, the router just sends the MessagePayload instead of sending a MessageStatus and awaiting a ReceiveMessageBegin.
i2cp.gzip0.6.5true, falsetrueGzip outbound data
i2cp.leaseSetAuthType0.9.4100-20The type of authentication for encrypted LS2. 0 for no per-client authentication (the default); 1 for DH per-client authentication; 2 for PSK per-client authentication. See proposal 123.
i2cp.leaseSetBlindedType0.9.390-65535See prop. 123The sig type of the blinded key for encrypted LS2. Default depends on the destination sig type. See proposal 123.
i2cp.leaseSetClient.dh.nnn0.9.41b64name:b64pubkeyThe base 64 of the client name (ignored, UI use only), followed by a ':', followed by the base 64 of the public key to use for DH per-client auth. nnn starts with 0. See proposal 123.
i2cp.leaseSetClient.psk.nnn0.9.41b64name:b64privkeyThe base 64 of the client name (ignored, UI use only), followed by a ':', followed by the base 64 of the private key to use for PSK per-client auth. nnn starts with 0. See proposal 123.
i2cp.leaseSetEncType0.9.3800-65535,...0The encryption type to be used, as of 0.9.38. Interpreted client-side, but also passed to the router in the SessionConfig, to declare intent and check support. As of 0.9.39, may be comma-separated values for multiple types. See also i2cp.leaseSetPrivateKey. See PublicKey in common structures spec for values. See proposals 123, 144, and 145.
i2cp.leaseSetKey0.7.1For encrypted leasesets. Base 64 SessionKey (44 characters)
i2cp.leaseSetOption.nnn0.9.66srvKey=srvValueA service record to be placed in the LeaseSet2 options. Example: "_smtp._tcp=1 86400 0 0 25 ...b32.i2p". nnn starts with 0. See proposal 167.
i2cp.leaseSetPrivateKey0.9.18Base 64 private keys for encryption. Optionally preceded by the encryption type name or number and ':'. For LS1, only one key is supported, and only "0:" or "ELGAMAL_2048:" is supported, which is the default. As of 0.9.39, for LS2, multiple keys may be comma-separated, and each key must be a different encryption type. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts. See proposals 123, 144, and 145. See also i2cp.leaseSetEncType. Do not confuse with i2cp.leaseSetPrivKey which is for encrypted LS2.
i2cp.leaseSetSecret0.9.39""Base 64 encoded UTF-8 secret used to blind the leaseset address. See proposal 123.
i2cp.leaseSetSigningPrivateKey0.9.18Base 64 private key for signatures. Optionally preceded by the key type and ':'. DSA_SHA1 is the default. Key type must match the signature type in the destination. I2CP will generate the public key from the private key. Use for persistent leaseset keys across restarts.
i2cp.leaseSetType0.9.381,3,5,71-2551The type of leaseset to be sent in the CreateLeaseSet2 Message. Interpreted client-side, but also passed to the router in the SessionConfig, to declare intent and check support. See proposal 123.
i2cp.messageReliabilityBestEffort, NoneNoneGuaranteed is disabled; None implemented in 0.8.1; None is the default as of 0.9.4
i2cp.reduceIdleTime0.7.11200000300000 minimum(ms) Idle time required (default 20 minutes, minimum 5 minutes)
i2cp.reduceOnIdle0.7.1true, falsefalseReduce tunnel quantity when idle
i2cp.reduceQuantity0.7.111 to 51Tunnel quantity when reduced (applies to both inbound and outbound)
i2cp.SSL0.8.3true, falsefalseConnect to the router using SSL. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
i2cp.tcp.host127.0.0.1Router hostname. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
i2cp.tcp.port1-655357654Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
참고: 숫자를 포함한 모든 인수는 문자열입니다. 참/거짓 값은 대소문자를 구분하지 않는 문자열입니다. 대소문자를 구분하지 않고 "true"가 아닌 모든 값은 거짓으로 해석됩니다. 모든 옵션 이름은 대소문자를 구분합니다.

I2CP 페이로드 데이터 형식 및 다중화

I2CP에서 처리하는 종단 간 메시지(클라이언트가 SendMessageMessage 에서 전송하고 클라이언트가 MessagePayloadMessage 에서 수신하는 데이터)는 RFC 1952 에서 명시한 대로 0x1F 0x8B 0x08로 시작하는 표준 10바이트 gzip 헤더를 사용하여 압축됩니다. 0.7.1 릴리스부터 I2P는 동일한 대상에 대해 스트리밍과 데이터그램을 지원하고 여러 채널이 존재하더라도 데이터그램을 이용한 질의/응답이 신뢰성 있게 작동할 수 있도록 gzip 헤더의 무시되는 부분을 활용하여 프로토콜, 발신 포트(from-port), 수신 포트(to-port) 정보를 포함합니다.

gzip 기능은 완전히 끌 수 없지만, i2cp.gzip=false로 설정하면 gzip effort 값을 0으로 바꾸어 약간의 CPU 사용량을 절약할 수 있습니다. 구현체는 콘텐츠의 압축 가능성 평가에 따라 소켓별 또는 메시지별로 서로 다른 gzip effort 값을 선택할 수 있습니다. API 0.9.57(제안서 161)에서 구현된 대상지 패딩의 압축 가능성 덕분에, 페이로드 자체가 압축 불가능하더라도 양방향 스트리밍 SYN 패킷과 응답 가능한 데이터그램의 압축을 권장합니다. 구현체는 gzip effort 값이 0일 경우를 위해 간단한 gzip/gunzip 함수를 작성할 수 있으며, 이 경우 기존 gzip 라이브러리보다 훨씬 높은 효율을 얻을 수 있습니다.

BytesContent
0-2Gzip header 0x1F 0x8B 0x08
3Gzip flags
4-5I2P Source port (Gzip mtime)
6-7I2P Destination port (Gzip mtime)
8Gzip xflags (set to 2 to be indistinguishable from the Java implementation)
9I2P Protocol (6 = Streaming, 17 = Datagram, 18 = Raw Datagrams) (Gzip OS)
참고: I2P 프로토콜 번호 224-254는 실험용 프로토콜을 위해 예약되어 있으며, I2P 프로토콜 번호 255는 향후 확장을 위해 예약되어 있습니다.

데이터 무결성은 RFC 1952 에서 명시한 표준 gzip CRC-32를 사용하여 검증됩니다.

표준 IP와의 주요 차이점

I2CP 포트는 I2P 소켓과 데이터그램을 위한 것입니다. 이들은 로컬 소켓이나 포트와는 관련이 없습니다. I2P가 0.7.1 릴리스 이전까지 포트와 프로토콜 번호를 지원하지 않았기 때문에, 하위 호환성을 위해 포트와 프로토콜 번호가 표준 IP의 그것과 다소 다릅니다:

  • 포트 0은 유효하며 특별한 의미를 가집니다.
  • 포트 1-1023은 특별하거나 권한이 부여된 포트가 아닙니다.
  • 서버는 기본적으로 포트 0에서 수신 대기하며, 이는 “모든 포트"를 의미합니다.
  • 클라이언트는 기본적으로 포트 0으로 전송하며, 이는 “임의의 포트"를 의미합니다.
  • 클라이언트는 기본적으로 포트 0에서 전송하며, 이는 “지정되지 않음"을 의미합니다.
  • 서버는 포트 0에서 수신 대기하는 서비스와 더 높은 포트에서 수신 대기하는 다른 서비스를 가질 수 있습니다. 이 경우 포트 0의 서비스가 기본값이며, 들어오는 소켓이나 데이터그램 포트가 다른 서비스와 일치하지 않을 경우 이 서비스에 연결됩니다.
  • 대부분의 I2P 목적지에는 하나의 서비스만 실행되므로 기본값을 사용하고 I2CP 포트 설정은 무시할 수 있습니다.
  • 프로토콜 0은 유효하며 “임의의 프로토콜"을 의미합니다. 그러나 이는 권장되지 않으며 작동하지 않을 가능성이 높습니다. 스트리밍은 프로토콜 번호가 6으로 설정되어야 합니다.
  • 스트리밍 소켓은 내부 연결 ID로 추적됩니다. 따라서 dest:port:dest:port:protocol의 5튜플이 유일할 필요는 없습니다. 예를 들어, 두 목적지 사이에 동일한 포트를 사용하는 여러 소켓이 존재할 수 있습니다. 클라이언트는 아웃바운드 연결을 위해 “사용 가능한 포트"를 선택할 필요가 없습니다.

향후 작업

  • 현재의 인증 메커니즘은 해시된 비밀번호를 사용하도록 수정될 수 있습니다.
  • 리스 세트 생성(Create Lease Set) 메시지에 서명용 개인 키(Signing Private Keys)가 포함되어 있으나, 이는 필요하지 않습니다. 폐기 기능은 구현되어 있지 않으며, 랜덤 데이터로 대체하거나 제거되어야 합니다.
  • 일부 개선 사항에서 이전에 정의되었으나 구현되지 않은 메시지를 활용할 수 있을 수 있습니다.

Was this page helpful?