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.
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| ------ ------------- ------------ -------
mask-api.icloud.comto a DNS resolver, asking for the IP addresses of ingress 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
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
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.
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.
In practice, we observed two ways for the client to get an IP address of the resolvers. The first way is:
mask.icloud.com. The responses include a type
mask.apple-dns.net, along with many type
CNAMEone. The client thus has to send another two DNS queries of type
The second way is:
mask-api.icloud.com. The responses include a type
mask-api.fe.apple-dns.net, along with many type
CNAMEone. The client thus has to send another two DNS queries of type
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 @18.104.22.168 mask.icloud.com -t HTTPS +timeout=2.
We thus used the follwing script with Scapy. Since
22.214.171.124 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 126.96.36.199 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="188.8.131.52" 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)))
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
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
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.
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 (
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 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.
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:
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.
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.
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.
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.
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.
We thank a person who prefers to stay anonymous for lending us an iPhone for testing.
We encourage you to share your comments publicly or privately. Our private contact information can be found at the footer of GFW Report.