Evaluating the censorship resistance of Apple's iCloud Private Relay


Authors: Anonymous, David Fifield, Amir Houmansadr

中文版: 评估苹果的iCloud Private Relay的抗封锁能力

On September 20, 2021, Apple released iCloud Private Relay (archive) as a new service on iOS 15, iPadOS 15, and macOS Monterey.

Although Apple does not introduce Private Relay as a censorship circumvention tool, in this post, we attempt to understand the potential value of iCloud Private Relay for censorship circumvention. We first introduce how private relay works based on Apple’s documents and our measurement. We then present our empirical observation on its censorship resilience, supported by our measurements in China. As of September 23, 2021, we haven’t found any evidence of censorship against it in China. We also discuss its blocking resistance against common censorship methods, including DNS hijacking, SNI filtering, IP blocking, active probing, as well as self-censorship. Finally, we present some important but unanswered questions about the Private Relay.

We do not intend to make this a comprehensive report. Instead, we hope to start off discussions by presenting our thoughts, observations and measurement methods, encouraging more censorship measurement and circumvention enthusiasts to study it.

Main Findings

  • As of September 23, 2021, we haven’t found any evidence of censorship against Private Relay in China.
  • The Private Relay can be easily block by common censorship methods, including DNS hijacking, (QUIC) SNI filtering, IP blocking. It may be possible to block by active probing as well.
  • The service has been self-censored in many countries, though it is reportedly still usable with a foreign iCloud account.

Introduction

Below is an introduction based on our measurement and our understanding of Apple’s documents. In summary, the Private Relay has a two-hop structure, consisting of an ingress relay and an egress relay:


  ------------
 |DNS resolver|
  ------------
       ^
       |
    A mask.icloud.com?
HTTPS mask.icloud.com?
       |
       0
       |
    ------           -------------           ------------           -------
   |client| <==1==> |ingress relay| <==2==> |egress relay| <==3==> |website|
    ------           -------------           ------------           -------
  • Step 0: The client sends two plaintext queries of type A and HTTPS for mask.icloud.com or mask-api.icloud.com to a DNS resolver, asking for the IP addresses of ingress relays.
  • Step 1: The client then selects one IP address from the answers and initiates an encrypted QUIC connection to its port 443.
  • Step 2: According to the document, “[t]he second relay, which is operated by a third-party content provider, generates a temporary IP address, decrypts the name of the website you requested and connects you to the site”.
  • Step 3: The traffic between the egress relays and websites is exactly the same as traffic between clients and websites when no Private Relay is used.

Capture traffic between an iPhone and relays

To capture and analyze the traffic from a mobile device, one intuitive way is to set up a VPN that works at the network layer, tunneling all the traffic at the transport layer and above to a (local) server, where tcpdump or wireshark can be run. However, the iCloud Private Relay feature appears to be disabled when a VPN is used.

As an alternative, we set up a WiFi hotspot from the desktop and let the iPhone connect to it. We then captured and analyzed the traffic from the laptop. Below is the script we used to setup the hotspot, which was borrowed from this tutorial.

#!/bin/bash

set -x
set -e

## Source: https://computingforgeeks.com/create-wi-fi-hotspot-on-ubuntu-debian-fedora-centos-arch/

## Change the IFNAME to your Wi-Fi network interface: `ip link show`
IFNAME="wlp4s0"
CON_NAME="MyHotSpot"
PASSWORD="77fdda98a6feaf6cc9"

nmcli con add type wifi ifname "$IFNAME" con-name "$CON_NAME" autoconnect yes ssid "$CON_NAME"

nmcli con modify "$CON_NAME" 802-11-wireless.mode ap 802-11-wireless.band bg ipv4.method shared

nmcli con modify "$CON_NAME" wifi-sec.key-mgmt wpa-psk
nmcli con modify myhotspot wifi-sec.psk "$PASSWORD"

nmcli connection show "$CON_NAME"

nmcli con up "$CON_NAME"

nmcli connection show "$CON_NAME"

When observing the DNS and initial QUIC traffic, we find the following Wireshark filter helpful:

quic.long.packet_type == 0 or udp.port == 53

Measure current censorship and evaluate potential censorship cost

In this section, we measure current censorship in China, and discuss the cost for a censor to detect and block Private Relay using commonly used censorship methods.

DNS hijacking

As introduced above, the client needs to get an IP address of the ingress relay before initiating QUIC connections to it. Since these DNS queries are (possibly intentionally) sent in plaintext, it is vulnerable to the DNS poisoning attack. Actually, Apple suggests DNS hijacking as “[t]he fastest and most reliable way” to block Private Relay:

The fastest and most reliable way to alert users is to return a negative answer from your network’s DNS resolver, preventing DNS resolution for the following hostnames used by Private Relay traffic. Avoid causing DNS resolution timeouts or silently dropping IP packets sent to the Private Relay server, as this can lead to delays on client devices.

mask.icloud.com

mask-h2.icloud.com

In practice, we observed two ways for the client to get an IP address of the resolvers. The first way is:

  1. The client first sends two DNS queries of type A and HTTPS for mask.icloud.com. The responses include a type CNAME answer mask.apple-dns.net, along with many type A answers.
  2. The client appears to select the first answer in the reponses, which is the CNAME one. The client thus has to send another two DNS queries of type A and HTTPS for mask.apple-dns.net.
  3. The client will then select the first answer in the responses.

The second way is:

  1. The client first sent two DNS queries of type A and HTTPS for mask-api.icloud.com. The responses include a type CNAME answer mask-api.fe.apple-dns.net, along with many type A answers.
  2. The client appears to select the first answer in the reponses, which is the CNAME one. The client thus has to send another two DNS queries of type A and HTTPS for mask-api.fe.apple-dns.net.
  3. The client will then select the first answer in the responses.

Note that we did not observe any query of the documented mask-h2.icloud.com. This observation aligns with the finding in this post.

Measuring current DNS censorship in China

Although it is trivial for the GFW to poison the domains mentioned above, we have not been able to observe any DNS poisoning against these domains yet. Specifically, we tested by sending DNS queries from China to the outside, and also from outside to China. You can also test it yourself from the outside of China, exploiting the bi-directional characterisitc of the GFW. It is worth noting that dig does not support type HTTPS queries yet; be careful that dig will fall back to type A queries without a blocking warning for a query like this: dig @1.1.1.1 mask.icloud.com -t HTTPS +timeout=2.

We thus used the follwing script with Scapy. Since 104.193.82.0 is a Chinese IP address without a DNS service running, we would have received responses injected by the GFW if any of the queries were censored.

#!/usr/bin/env python3

# This script is only reponsible for sending DNS queries, but not for receiving responses.
# To observe DNS responses, use tcpdump or wireshark. eg. :
# sudo tcpdump host 104.193.82.0

from scapy.all import *

# https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-07.html#name-the-svcb-record-type
TYPE_HTTPS=65

CHINESE_IP="104.193.82.0"

for qname in ["mask.icloud.com",
              "mask-api.icloud.com",
              "mask.apple-dns.net",
              "mask-api.fe.apple-dns.net",
              "mask-h2.icloud.com"]:
    for qtype in [TYPE_HTTPS, "A", "AAAA"]:
        send(IP(dst=CHINESE_IP)/UDP(dport=53)/DNS(rd=1, qd=DNSQR(qname=qname, qtype=qtype)))

SNI filtering

As explained in this answer, although clienthello messages are encryped in QUIC, the secrets are derived from a fixed salt and the Destination Connection ID field. The Initial packets can thus be easily decrypted. Actually, a newer version of the Wireshark can automate the decryption process for you.

It is therefore possible for censor to decrypt the Inital packets and check the SNI field against mask.icloud.com.

Measuring current (QUIC-)SNI censorship in China

We tested by capturing the initial packets from client and replaying them on a Chinese server. The server responded with QUIC handshake messages and we observed no disruption.

For example, we first saved the following hex stream as quic.hex:

c80000000108bec8eac6d55fe88a08e87fe5dfa21d247700452c6a2a855275bb191ffe213c2ad1e07467f9ed24956172c4bee69e8446049a94fbae38973cf11ce80cc1379237e4a0f610ae2408ac096635b3978dcf21b4c81d96a2e53d9a9b04dc234341869f7ea85dc99e2ea028827257c4b6993a29ae07e9368c22426d1780abcf8c4b5ab8b2e3ba4de878306ecf4a4e5851c2168b8412f9a55fa5971520914f13c4a86106161e19bfa1eff9c08a9b566e1656ebceeb7184d60a0328203e5e66fc16ad8452343dee5e2ad22ba0ef80b978ba62c64ac75826b79d119c5a7bf9859655d79116e3f4069e87269bab7f9d0373d8e98e4c4891eaf621ce073c61f59eeddd828c96d785ff3155083f5ac93263e5496a6a38a2a2e0bbf64041e76a500bf4748143f2b8705c3732dc12b218f428eeadd02c50e71c5ffaa1ca14c483ac44c75d10e98d38ddaa38f38c0ba7af20108967541586c51bccd2765781b123b4a91fed0f32f0b11bfc4ff5beaccb023f7d977787a0d09942f5159da772b9ca5a7c512a8644bb399858cc6ee2a5d5c099be6780a619cbadc6407db320d34179bf1ff94401ef0e134d0d8ae705a468b5dcd7b9c078e72ddba146e947dca7d4968b3fc892e425ef60bec05df120b20f26f340ed134b064b4fddd194fee666ff49c943b82f812c6f57daaa70ef5aa7b511e8d9501a447783a4e7eee709499161c4055941d516f16bc4ed114d90f6d49c1a297484749fa99f84eb309c2743018eeebb71c6050061e4899b94ecc746fb98174ce383a9d250f61d3aca4db9249122763ca03c41a67b616e722f5171e34a610aeb9cfb6c74f8bdd549d1b0fbd4a766dd66dc355de7f55d55e029d495687c149d9bac0eba89276a0c8048a97545c08597ea836917ceaebe2e334d9376f3c3dc29ee6df84508558d2c77a1139907aba7735945846e3a8c4675845e01c7e2cb1370b31221f95e1bd0c8e5ecc9e86bf5658859379e3c752e34d6bf9e0e9481cf9ed5df79b9c756cb904603eaab2478b6aaa5740b28213f2716b2b4769e21d9c7e2d62e9708de9644a3de048745f079717e0a565475d0684be9cb13c261f55832953c37078cde29894b2176eab5157e4262dbba7919ef2c66d0cf86d7de93059e9f013e2e82544dc803dea878e184d248065454c65c26d8c67b7778e229390de7560815e6cdc53cce1fb11d62d9b0ecea890b4310ffcf7cd544ca8d6a1b9eed7b92a93fd6c00d0a2338f66ad77c9220c69437b3651b18899c68a8e59f12dc2f014d70a6ca5b4aa419516fde01079a1f76c3198db4f6229641e5e89b1b6aa9797c27b55f439e98858f9d3eef1ffff6f5e52e9e94468d21e8ab965abb864836be07016fdbb63a24e954b863a98d590033bd163df6a7740d256a0bbaa910e45a8f40877b6b84fd2d8f57604d236e4351bd228dc707fe3538440b2796dbab58183f306912c6104d13ea96c649fd338994b4a2d5ecbfdd66b69b5245763371cc38c92774723f546a27519db4660f5dc6312f5f56edad2dcb77bd3034c8a4a084ee7e57016fea8a5fcb114ee5ae97d55b177dd8b1ccd0508fb6baee6244ccedf2705ba35a760b944acb4b3e0394b5add44e851d18e0400d99b4910cd4cb63311727f4a98289ce4ee960c506b72243fde14cf5d3185cc4b598f080faf9ebc75847dc7126bb90c47368c5408898e7bdaf9cde4f04299043600dcdf850c306c737d4be37c316eed63718804e9972f6c95d79771ada173293b06037f1282f4e79f8116e3d4c5fed2ec6db335faf2b0481b3aa3a0192f9ff3fea35ae1bafe71bbcd07a301fe11638a180b6b202c29dea331ac6a2527587a82175cd7b96033b165b88580e83df7759ebe6586d68d4efe6028403d5d0d700e967ca4908bbd8e4

We then send it to the ingress relay and received a response:

xxd -r -p quic.hex | nc -u mask.icloud.com 443 -v

Note that the payload in the example will not get a reponse from an ingress relay anymore, approximately two days after it was first generated. One can probably still trigger reponses from the ingress relays with freshly generated Initial packets.

(Quic-)TLS fingerprint filtering

As explained above, the clienthello messages in the Initial packets can be easily decrypted. It is thus possible for the censor to conduct censorship based on the TLS fingerprint.

Our observation of the TLS fingerprint of the Private Relay aligns with the findings in this report:

The connection to the relay uses QUIC to port 443/UDP and TLS 1.3. The clienthello includes the server name extension and the server name “mask.icloud.com.” Only 3 cipher suites are offered (TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256). The server ends up selecting the AES128 suite. Application Layer Protocol Negotiation (ALPN) is also used, with unsurprisingly HTTP/3 being the only option.

Note that, apart from the 3 cipher suites, we saw a forth Grease ciphersuit (0x2a2a).

As a side note, we also observed two GREASE extensions 0xAAAA and 0X3A3A. They probably do not have anything to do with authentication (if they do, it’s something very non-standard Apple is doing). The GREASE extensions turned out to be not uncommon; web browsers send them as well. As expalined in this doc, they were used to “reserve a set of TLS protocol values that may be advertised to ensure peers correctly handle unknown values”. In other words, GREASE is meant to provide automated diversity to protocol fields, to prevent the protocol from “rusting shut” by assuming only certain values may appear.

We are also curious, by any chance, tlsfingerprint.io can tell us how unique these (or any) (QUIC) ClientHello fingerprints are? (@sergeyfrolov, @ewust)

Active probing to ingress relay

We find that the ingress relay will respond to a replay of the Initial packets within approximately two days since the packets were generated. We also tried to use quic-go and curl --http3 to send a typical Quic with SNI=mask.apple.com to the ingress relay; however, the ingress relay did not respond anything in this case. We suspected that has something to do with the ALPN extension included in the clienthello sent by the legitimate clients. It may also be possible that the client traffic contains some other authenticators.

IP blocking to ingress relays

As introduced above, we could still receive responses from ingress relays by sending Initial packets from China. This indicates that, at least for the IP addresses we tested, China has not blocked it yet.

However, it could be fairly easy to block the ingress relay IP in serveral ways:

  1. block all IP addresses to which mask.icloud.com, mask-api.icloud.com and mask-h2.icloud.com resolve.
  2. observe QUIC connections with SNI=mask.apple.com and confirm it is indeed an ingress relay using the active probing approach mentioned above. Then block the corresponding IP addresses.

IP-based discrimination against egress relays

Similar to Tor exit relays, which are available publicly, Apple provides an up-to-date lists of egress IP ranges (archive). This list could be easily used by websites to discriminate against Private Relay users, like what Tor users have been suffering from.

Questions not answered yet

How Apple implements the self censorship

Apart from all the possible external censorship methods discussed above, Apple has been conducting self-censorship to prevent users in heavily censored areas from using the Private Relays. It is thus important to understand how Apple implements the self censorship in order to circumvent it.

Specifically, Apple admitted that:

Private Relay isn’t available in all countries and regions. If you travel somewhere Private Relay isn’t available, it will automatically turn off and will turn on again when you re-enter a country or region that supports it. Private Relay will notify you when it’s unavailable and when it’s active again.

According to many news sources, these countries include China, Belarus, Colombia, Egypt, Kazakhstan, Saudi Arabia, South Africa, Turkmenistan, Uganda, the Philippines, and Russia.

It remains an unanswered questions on how and what self-censorship has been implemented by Apple. From our testing, it seems that the ingress server does not refuse service based on the geolocation of client IP addresses. However, it is still unclear to us how Apples determines the location of the user and thus refuse to be activated.

One report claimed (archive) that Apple learned users’ geo-location from users’ IP addresses connected to its certain servers; proxying traffic to these certain servers will activate the Private Relay service.

Another user report claimed (archive) that it is sufficient to activate Private Relay by changing the iCloud region to ones where Private Relay is not self-censored. However, another user in the post failed to activate the service with the same settings.

We note that it is not uncommon for a Chinese iOS circumventor to have a non-Chinese iCloud account. This is because, due to the heavy censorship against circumvention tools in Chinese app stores, it is almost essential to have a non-Chinese iCloud account to install other circumvention tools.

How does the user authentication work?

Apple claims that:

Private Relay validates that the client connecting is an iPhone, iPad, or Mac, so you can be assured that connections are coming from an Apple device.

All connections that use Private Relay validate that the client is an iPhone, iPad, or Mac and that the customer has a valid iCloud+ subscription. Private Relay enforces several anti-abuse and anti-fraud techniques, such as single-use authentication tokens and rate-limiting.

We are curious how (or if) Apple authenticates Priavet Relay users on the ingress and egress relays.

How does the underlying decryption work?

In the introduction section, we mentioned that the Private Relay “has a two-hop structure”. However, we do not have know anything more about the underlying structure. For example, is an onion-routing structure used? Amir Houmansadr expressed concerns on the intransparency of the underlying protocol. Further investigation is required to better understand the underlying encryption/decryption mechanism.

Acknowledgement

We thank a person who prefers to stay anonymous for lending us an iPhone for testing.

Contacts

This report first appeared on Net4People. We also maintain an up-to-date copy of the report on GFW Report and ntc.party.

We encourage you to share your comments publicly or privately. Our private contact information can be found at the footer of GFW Report.


Comments