Cloudflare blocked IP circumvention

Continuing the discussion from Использование ESNI (Encrypted SNI) в России:

Cloudflare allows connection to any website (any domain/SNI) via any Cloudflare IP address which accepts connections to port 80/443. Although Cloudflare does ‘allocate’ IP addresses to the domains/websites, it does not prevent from connecting to this website using any other Cloudflare IP address.

https://bo0om.ru/ is allocated 104.28.27.13 and 104.28.26.13 by Cloudflare, but you can connect to it using any IP address from Cloudflare IP ranges which accepts connections to port 443.

$ curl -v --resolve *:443:198.41.215.0 https://bo0om.ru

* Added *:443:198.41.215.0 to DNS cache
* RESOLVE *:443 is wildcard, enabling wildcard checks
* Hostname bo0om.ru was found in DNS cache
*   Trying 198.41.215.0:443...
* TCP_NODELAY set
* Connected to bo0om.ru (198.41.215.0) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: OU=Domain Control Validated; OU=PositiveSSL Multi-Domain; CN=sni78855.cloudflaressl.com
*  start date: Nov  3 00:00:00 2019 GMT
*  expire date: May 11 23:59:59 2020 GMT
*  subjectAltName: host "bo0om.ru" matched cert's "bo0om.ru"
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO ECC Domain Validation Secure Server CA 2
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55559d146970)
> GET / HTTP/2
> Host: bo0om.ru
> User-Agent: curl/7.65.3
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 256)!
< HTTP/2 200 
< date: Wed, 06 Nov 2019 02:31:33 GMT
< content-type: text/html; charset=UTF-8
< set-cookie: __cfduid=ddb14359e6733369c987d1dd0065ffe8f1573007491; expires=Thu, 05-Nov-20 02:31:31 GMT; path=/; domain=.bo0om.ru; HttpOnly
< referrer-policy: unsafe-url
< x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< x-content-type-options: nosniff
< link: <https://bo0om.ru/wp-json/>; rel="https://api.w.org/"
< set-cookie: icwp-wpsf=9dbb0b8c2763d9c2918931fbc94fab2a; expires=Thu, 10-Oct-2069 05:03:02 GMT; Max-Age=1575599490; path=/; secure
< expires: Fri, 06 Dec 2019 02:31:32 GMT
< cache-control: private, must-revalidate, max-age=2592000
< vary: Accept-Encoding
< cf-cache-status: DYNAMIC
< strict-transport-security: max-age=2592000
< expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< server: cloudflare
< cf-ray: 5313a6d38caf7676-ARN
< 
<!DOCTYPE html>
<html lang="ru-RU" class="no-js">
…

But Cloudflare does not allow domain fronting. You can’t use one domain in TLS SNI and another in HTTP Host, you will get 403 Forbidden.

It seems you can use any cloudflare.com IP address to access their DoH service, so you can bypass that IP blocking.

1 Like

Yes, just with any cloudflare-hosted website really.

I don’t understand what this means. I tried domain fronting and using a bare IP address, and it doesn’t work for me.

$ curl --include https://1.1.1.1/dns-query
HTTP/2 400 
date: Tue, 05 Nov 2019 23:53:26 GMT
access-control-allow-origin: *
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 5312bf478925e202-ORD

$ curl --include https://mozilla.cloudflare-dns.com/dns-query
HTTP/2 400 
date: Tue, 05 Nov 2019 23:53:38 GMT
access-control-allow-origin: *
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 5312bf90d972e216-ORD

$ curl --include https://cloudflare.com/dns-query -H 'Host: 1.1.1.1'
HTTP/2 403 
server: cloudflare
date: Tue, 05 Nov 2019 23:54:09 GMT
content-type: text/html
content-length: 151
cf-ray: 5312c04ebb37ed9f-SJC

<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>
$ dig +short cloudflare.com
198.41.214.162
198.41.215.162
$ curl --insecure --include https://198.41.215.162/dns-query -H 'Host: 1.1.1.1'
HTTP/2 403 
server: cloudflare
date: Tue, 05 Nov 2019 23:54:48 GMT
content-type: text/html
content-length: 151
cf-ray: 5312c1445d389dd1-ORD

<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>

That’s because we are talking not about domain fronting.

Cloudflare allows connection to any website (any domain/SNI) via any Cloudflare IP address which accepts connections to port 80/443. Although Cloudflare does ‘allocate’ IP addresses to the domains/websites, it does not prevent from connecting to this website using any other Cloudflare IP address.

https://bo0om.ru/ is allocated 104.28.27.13 and 104.28.26.13 by Cloudflare, but you can connect to it using any IP address from Cloudflare IP ranges which accepts connections to port 443.

$ curl -v --resolve *:443:198.41.215.0 https://bo0om.ru

* Added *:443:198.41.215.0 to DNS cache
* RESOLVE *:443 is wildcard, enabling wildcard checks
* Hostname bo0om.ru was found in DNS cache
*   Trying 198.41.215.0:443...
* TCP_NODELAY set
* Connected to bo0om.ru (198.41.215.0) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: OU=Domain Control Validated; OU=PositiveSSL Multi-Domain; CN=sni78855.cloudflaressl.com
*  start date: Nov  3 00:00:00 2019 GMT
*  expire date: May 11 23:59:59 2020 GMT
*  subjectAltName: host "bo0om.ru" matched cert's "bo0om.ru"
*  issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO ECC Domain Validation Secure Server CA 2
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55559d146970)
> GET / HTTP/2
> Host: bo0om.ru
> User-Agent: curl/7.65.3
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 256)!
< HTTP/2 200 
< date: Wed, 06 Nov 2019 02:31:33 GMT
< content-type: text/html; charset=UTF-8
< set-cookie: __cfduid=ddb14359e6733369c987d1dd0065ffe8f1573007491; expires=Thu, 05-Nov-20 02:31:31 GMT; path=/; domain=.bo0om.ru; HttpOnly
< referrer-policy: unsafe-url
< x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< x-content-type-options: nosniff
< link: <https://bo0om.ru/wp-json/>; rel="https://api.w.org/"
< set-cookie: icwp-wpsf=9dbb0b8c2763d9c2918931fbc94fab2a; expires=Thu, 10-Oct-2069 05:03:02 GMT; Max-Age=1575599490; path=/; secure
< expires: Fri, 06 Dec 2019 02:31:32 GMT
< cache-control: private, must-revalidate, max-age=2592000
< vary: Accept-Encoding
< cf-cache-status: DYNAMIC
< strict-transport-security: max-age=2592000
< expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< server: cloudflare
< cf-ray: 5313a6d38caf7676-ARN
< 
<!DOCTYPE html>
<html lang="ru-RU" class="no-js">
…

But Cloudflare does not allow domain fronting. You can’t use one domain in TLS SNI and another in HTTP Host, you will get 403 Forbidden.

Here is a simple example of what I meant:

$ curl --connect-to ::cloudflare.com: -H 'accept: application/dns-json' 'https://mozilla.cloudflare-dns.com/dns-query?name=example.com&type=AAAA'

{"Status": 0,"TC": false,"RD": true, "RA": true, "AD": true,"CD": false,"Question":[{"name": "example.com.", "type": 28}],"Answer":[{"name": "example.com.", "type": 28, "TTL": 1918, "data": "2606:2800:220:1:248:1893:25c8:1946"}]}

As @ValdikSS said, this is not domain fronting. It doesn’t protect against SNI-triggered blocking, since you are still sending the mozilla.cloudflare-dns.com SNI. But it does protect against blocking of mozilla.cloudflare-dns.com by IP address.

1 Like

A post was merged into an existing topic: Использование ESNI (Encrypted SNI) в России