FortiGate
FortiGate Next Generation Firewall utilizes purpose-built security processors and threat intelligence security services from FortiGuard labs to deliver top-rated protection and high performance, including encrypted traffic.
fricci_FTNT
Staff
Staff
Article Id 328324
Description

 

This article describes how FortiGate blocks the TLS Encrypted Client Hello (ECH) and forces the end client to send the inner SNI in clear.

 

When using the Encrypted Client Hello (ECH), TLS 1.3 protocol may split the Client Hello massage into two parts during its TLS handshake: an inner part (private) and an outer part (public). The outer part contains the outer Server Name Indication (SNI), which is sent in clear text during the TLS handshake while the inner part containing the inner SNI is encrypted.
The outer SNI and inner SNI can point to different domain servers and can be hosted on different hosts/locations.

 

More details on ECH can be found on this CloudFlare blog post.

 

In this scenario, a client connects to a HTTPS server, traffic flows through the FortiGate:

 

network_diagram.PNG

 

When ECH is used, the packet captures show that the FortiGate can only see the outer SNI and the inner SNI will be encrypted.

 

use-ECH-OK_allow-ECH-no-strip.PNG

 

outer-SNI.PNG

 

Scope

 

FortiGate 7.4.4+ , FortiGate 7.6.x.

 

Solution

 

FortiOS version 7.4.4+ implements two mechanisms to block ECH:

 

Option 1 - DNS filter option:

 

ECH_GUI_DNS-strip-01.PNG

 

ECH is used in conjunction with DNS-over-HTTPS (DoH). The DNS filter setting on the FortiGate analyses the DoH traffic and strips out the ECH parameters sent by the DNS server in the DoH response. If the client does not receive those parameters, it cannot encrypt the inner SNI, so it will send it in clear text.

 

Option 2 - SSL-SSH profile option (only available in a certificate-inspection profile):

 

ECH_GUI_02.PNG

 

In addition, when the SSL/SSH certificate Inspection profile setting 'Encrypted Client Hello' is set to 'Block' (default setting), the FortiGate blocks the TLS outer SNI manually configured from CLI (config ech-outer-sni):

 

config firewall ssl-ssh-profile

    edit "Custom-certificate-Block-ECH"

        set comment "Custom SSL handshake inspection profile."

            config https

                set ports 443

                set status certificate-inspection

                set quic bypass

                set encrypted-client-hello block <- Block is the default setting so it is only displayed when showing full config.

            end

            config ftps

            ...

            ...

                config dot

    set status disable

    set quic inspect

                end

                config ech-outer-sni

                    edit "tls-ech"

                        set sni "public.tls-ech.dev"
                    next
                    edit "defo.ie"
                        set sni "cover.defo.ie"
                    next
                end
      next
end

 

When implementing the settings, FortiGate is able to force the client to show the real inner SNI:

 

able-to-see-private-SNI.PNG

 

The test servers used, https//:defo.ie, display that ECH was not being used:

 

Error-getting-ECH_block-ECH-strip.PNG

 

Note: Encrypted Client Hello does not rely on DNS over HTTPS (DoH) to work, but they are a complement to each other to enhance privacy.

 

For ECH to work, the client needs to resolve the website using a DNS HTTPS query (Do not mistake with DNS over HTTPS). This is necessary for the browser to extract the ECH Config from the HTTPS record.

 

The easiest way to try is to enable DNS over HTTPS on Firefox (access about:preferences#privacy in Firefox, and enable DNS over HTTPS using Max Protection)

This will cause Firefox to perform DoH queries to Cloudflare by default, and HTTPS DNS queries will be performed:

 

ECH-OK.png

 

Setting DoH to Off:

 

ECH-NOK.png

 

In the example above disabling DoH on Firefox also caused ECH to fail.

This is because system DNS is not performing HTTPS DNS queries by default, so it cannot fetch the ECH public key from the HTTPS RR.

It is possible to change this behavior by enabling system HTTPS DNS queries:

  • On Firefox open 'about:config'.
  • Search for 'network.dns.native_https_query' and set to true.

 

After the change, it is still possible to access the test page with ECH status OK and using system DNS:

 

system-dns-ech-ok.png

 

On the pcap, it is possible to observe that the HTTPS DNS query was performed over plain text:

 

dns-https-plaintext.png

 

ECH:

 

pcap-ech.png