Draft protocol specification for the NAT64 handoff protocol Copyright (C) 2019 Kasper Dupont Licensed as CC BY-NC-ND 4.0 The author intends to relicense this document in accordance with RFC 5378 if and when this specification is first released as an IETF draft standard. Introduction: NAT64 handoff is a protocol which will allow a NAT64 to hand over parts of its responsibilities to a service running on the IPv4 hosts with which it communicates. When an IPv4 host supports this protocol it assumes responsibility to maintain the connection table, log connections, and respond to protocols other than TCP and UDP. If an IPv4 host wants further control this protocol allows the IPv4 host to take full responsibility for packet translation and use this protocol as just a tunneling protocol. Packet format: The NAT64 handoff packets are UDPv4 packets exchanged between a port on the IPv4 address of the NAT64 and the NAT64 handoff server port (TBD) on the IPv4 address of the server. The UDP payload consist of a sequence of messages. Messages are grouped according to the value of the first nibble of the message. 0 - Reserved for Teredo headers. Rationale: No use of Teredo headers inside of NAT64 handoff messages is currently defined. But the range is reserved nevertheless to avoid any ambiguity in case somebody decide to combine the two protocols in "creative" ways. 1 - Reserved for future extensions 2 - Reserved for future extensions 3 - Various messages consisting of one octet type+subtype, one octet length, and 0-510 octets of payload. Rationale: If accidentally interpreted as an IP version number this would refer to a long forgotten version. Additionally for subtypes 0 to 9 the ASCII representation of the full byte produce the digit corresponding to the subtype. 4 - IPv4 packet 5 - Reserved for future extensions 6 - IPv6 packet 7-15 - Reserved for future extensions Subtypes used in second nibble when first nibble is 3 (hexadecimal octet values 30 - 3f): 0 - Reserved for future extensions 1 - Protocol identifier (length 144) Payload is the fixed 144 octet string string "[[ This is the NAT64 handoff protocol. The client is using " "IPv6. To know their real IP address you need to use this " "protocol or support IPv6. ]]" Required to be present in messages transferring connection tracking entries from NAT64 to server. Permitted in all messages where it is considered useful. Rationale: System administrators may wonder why they are receiving traffic on this UDP port. To aid those who inspect the network traffic an explanation is present in those messages which will usually be sent while the NAT64 doesn't know if the server supports the protocol. 2 - No-op (length variable) Can be included in any message. Must be ignored by receiver. Useful for a nonce value in validation packets sent by server. 3 - Always invalid (length variable) Rationale: It can be useful to have a byte value which is guaranteed to always be invalid. During development not yet implemented fields can be filled with octet value 33 which renders a recognizable pattern in both hexadecimal and ASCII dumps of the packets. 4 - Token (length variable) The token is chosen by the NAT64 and is included in messages in both directions. This message is optional in packets from server to NAT64 if the packet contains a remote IPv6 address authenticator message. In all other packets on the control channel this message is mandatory. 5 - Token rotation (length variable) When NAT64 receives a message from server using an old token after a token rotation the NAT64 must include this message in the next packet it sends to the server. The packet must contain messages with both the old and the new token. When server receives a packet with an unexpected token it must look for this option and if found it must update the expected token. In packets which already have the expected token the server must ignore this message. NAT64 may preemptively include this message in the first packet it sends to a given server after the NAT64 has been restarted. 6 - Remote IPv6 address authenticator (length variable) Chosen by NAT64. This message is required in every message transferring a connection tracking entry or an IPv6 packet in either direction. This is used by NAT64 to confirm the server is allowed to communicate with the given remote IPv6 address. 7 - Connection tracking entry (length 32) Contents of this message: - 2 octets mapped port number - 12 octets NAT64 range (Only /96 NAT64 prefixes are supported by this protocol) - 16 octets peer IPv6 address - 2 octets peer port number Left out fields: - IPv4 addresses are implicit (as they will be taken from the IPv4 header in which this protocol is carried). - Protocol number is left out as this protocol shares the connection tracking table between UDP and TCP. - Server side port number is left out as this protocol shares the connection tracking table between all port numbers on the given server IPv4 address. Usage of this message: - Sent from NAT64 to server when a connection tracking entry created by the NAT64 sees the first return packet from server to client. - Sent from server to NAT64 when the server has received a packet from NAT64 for which it wants the connection tracking entry to be cached on the NAT64. Mandatory if the server choose to return a packet it received from NAT64 to the NAT64. - Re-transmitted from NAT64 to server when a connection tracking entry previously sent is expired by cache and has not in the meantime been seen in any message from the server. 8 - Mapped port hint (length 2) Sent from NAT64 to server with a hint about a mapped port number which the NAT64 has previously used for this client IP and port combination. The server should use this mapped port number if it is available, otherwise the server should ignore this message and choose a number on its own. 9-15 Reserved for future extensions A packet must not contain multiple messages of the same type except for connection tracking entries sent from NAT64 to server and their associated Remote IPv6 address authenticator messages. When sending multiple connection tracking entries in one packet they must be ordered as one or more groups in which each group consist of exactly one Remote IPv6 address authenticator message followed by one or more connection tracking entries using that Remote IPv6 address authenticator. Packets with multiple connection tracking entries must not exceed 1232 bytes of UDP payload and they must not contain IPv4 or IPv6 packets. NAT64 operation: Upon receiving a packet the NAT64 must first classify the packet as one of the following: - Packet subject to NAT - Control plane packet - ICMP packet - Packet with invalid destination IP IPv4 packets are classified as follows: - Incoming packets with destination address different from the NAT64 public IPv4 address are considered as invalid destination. - Packets with protocol number 1 are ICMP. - Packets sent from UDP port (TBD) to the client side port (chosen by NAT64) are control packets. - Packets with destination port 80 may be treated as HTTP. - All other packets are subject to NAT. IPv6 packets are classified as follows: - If destination address is within one of the NAT64 prefixes configured on this NAT64 and the first octet of the embedded IPv4 address is not 0 or 127 the packet is subject to NAT. - Any other destination address is considered as invalid destination. IPv4 packets subject to NAT are handled as follows: - If it is neither TCP nor UDP forward it over the control connection to the server. - If it matches a cached connection tracking entry from the server perform translation. - If it matches a NAT64 generated connection which has previously been used with this IPv4 address perform translation. - If it matches a NAT64 generated connection which has not been used with this IPv4 address and no valid control packets have ever been received from that server IPv4 address the NAT64 can choose between performing translation and sending the packet over the control channel to the server. - Otherwise send the packet over the control channel to the server. IPv6 packets subject to NAT are handled as follows: - If it is neither TCP nor UDP forward it over the control connection to the server. - If it matches a cached connection tracking entry from the server perform translation. - If it matches a NAT64 generated connection entry which has previously been used with this IPv4 address perform translation. - If a valid control packet has previously been received from this server IPv4 address forward it over the control connection to the server. - If no NAT64 generated connection tracking entry exists for this source IPv6/port create an entry. Record that the entry (new or existing) has been used with this server IPv4 address. Perform translation. ICMP error messages containing a (truncated) IPv4 error are handled as follows: - If the ICMP packet has invalid checksum it is silently dropped. - If the embedded packet source address does not match the NAT64 public IPv4 address, the ICMP error is silently dropped. - If the embedded IP payload is an ICMP packet, handle the packet according to RFC 792 considering the NAT64 itself to be the final destination of the packet. - If the embedded packet is a UDP packet from the client side port (chosen by NAT64) to the server side port (TBD) it's considered to be an undelivered control packet and is silently dropped. If the origin IP of the ICMP error matches the destination IP of the inner IP packet, and the ICMP error has type 3 and code 3, and the payload contains a valid token, the NAT64 must consider the handoff server to be down. The NAT64 must switch back to generating connection entries as if that server IPv4 address never supported handoff in the first place. Any previously cached connection entries from that server must be kept in cache and expired as if the server was still responding. Once the server is confirmed to be responding again the still cached connection entries must be sent to the server. - If the embedded IP payload is not TCP or UDP forward the packet over the control connection to the source IP of the embedded IP payload. - If the embedded IP payload matches a cached connection from the server perform translation. - If the embedded IP payload matches a NAT64 generated connection previously used with the destination IP of the embedded IP packet perform translation. - Otherwise forward the packet over the control connection to the source IP of the embedded IP payload. All other ICMP messages are handled according to RFC 792 considering the NAT64 itself to be the final destination of the packet. Packets with invalid destination IP are outside the scope of this document and may be silently dropped. It's permitted (but not recommended) for the NAT64 to implement the control channel over IPv6 and rely on itself to translate the control channel between IPv6 and IPv4. Server operation: When server receives a message from a NAT64 which it has not previously communicated with it must validate the remote port number and token by sending a message to UDP port 9 (discard) on the client IPv4 address. The packet should be formatted as a control channel packet and contain at least the following messages: - Remote IPv6 address authenticator - Routing table entry or IPv6 packet with matching IPv6 address. - No-op message or IPv6 packet containing a MAC calculated by server over token, client IPv4 address, and client port. The server may rotate the MAC key 30 seconds after it was last used to send a validation packet. The NAT64 must treat this as a packet not matching a known connection tracking entry and encapsulate the entire packet in a UDP packet sent back to the server. If the NAT64 implements attenuation against reflection attacks it must parse the received packet as a control channel packet and look for a valid token or remote IPv6 address authenticator, if either of those is found it must not drop the packet. The server will verify the MAC in the returned packet and if it matches store the token for validation of future packets. When the server receives an IPv6 packet over the control connection it must look for a matching connection tracking entry and if none exists it must create one. When using the public IPv4 address of the NAT64 for the connection entry it must use a port number in the range 1024-65535 avoiding the following port numbers: - 3544 - NAT64 handoff client port (TBD) - NAT64 handoff server port (TBD) - The most recently validated port number of that NAT64 The server must then either: - Translate the packet to IPv4 and deliver it directly - Translate the packet to IPv4 and return it to the NAT64 - Return the connection tracking entry and IPv6 packet to the NAT64 When the server receives an IPv4 packet over the control connection it must look for a matching connection tracking entry. If no matching connection tracking entry is found the server should return the packet to the NAT64 if it is a TCP or UDP packet and otherwise construct an appropriate ICMP error message which it can either deliver directly or send back over the control connection to the NAT64. If a match is found the server must then either: - Translate the packet to IPv6 and deliver it directly - Translate the packet to IPv6 and return it to the NAT64 - Return the connection tracking entry and IPv4 packet to the NAT64 Server side NAT: When the server creates new connection tracking entries it can choose between using the public IPv4 address of the NAT64 or an address from the well-known pool (TBD, substitute a RFC 1918 or RFC 6598 range while no well-known pool has been allocated for this protocol). A minimal server side implementation will always use the public IPv4 address of the NAT64 and never perform NAT itself. This will be limited to TCP and UDP support and will cost an extra roundtrip each time the NAT64 cache needs to be populated. It will be subject to the limitations in choice of port number for connection tracking entries outlined in this protocol. But it still allows a larger number of connections than relying entirely on the NAT64 as it won't be competing against servers on other IPv4 addresses for the same pool of port numbers. Using a local IP range on the server side has several advantages. But it requires server side NAT which also requires the server to run with the additional privileges needed to create a virtual network interface for this purpose. Advantages of server side NAT is that there is access to more IPv4 addresses thus a larger pool of available ports. And it is not subject to the requirements that the same port number be used for mappings towards all TCP and UDP ports server side. It also allows translation of all protocols needed by the server, not just TCP and UDP. It also completely avoids the use of cache entries on the NAT64 and the roundtrips needed to populate the cache. A mixed mode operation is also possible where the public IPv4 address of the NAT64 is used even with protocols not supported by the NAT64 and connections absent from the NAT64 cache. In this mode the NAT64 will tunnel IPv6 packets to the server. The server performs NAT and can either deliver the IPv4 packets directly or tunnel them back to the NAT64. IPv4 packets from the server are sent to the NAT64 which tunnels them to the server for translation. Once packets have been translated to IPv6 the server can either deliver them directly or tunnel them back to the NAT64. The extra roundtrip due to all the IPv4 packets needing to go from server to NAT64 and back to the server makes this mode less desirable. The extra roundtrip can be avoided at the cost of very complicated routing rules on the server. Whether to use this operation mode is choice made server side and the complexity of supporting it lies server side. The NAT64 is required to support this operation mode in case any server it communicates with makes use of it. The NAT64 side just needs to support the tunneling required for this.