I need to send SNI when connecting to the backend; how do I set it up?
Short answer
On the Backend Service, while SSL Service is on, the SNI field is filled in: if the Request HTTP header content variable (Header Name = Host) is added with the field's fx button, the name requested by the client is sent in each request; if a fixed domain name is written, the same name is sent in each connection. Since the value is calculated from the HTTP request in each request, the field is applied on HTTP vServices. If the field is left empty, SNI is not sent; this is the default. When used together with Certificate Verification = Required, the name in the server certificate is checked against the SNI value. In WEB-CLI, the same field is written with --sni.
Problem: The Server Hosts More Than One Site on the Same IP
Servers that host more than one HTTPS site on the same IP, such as IIS, nginx or cloud services, understand which site is requested from the SNI in the TLS handshake. If TR7 connects to these servers without sending SNI, the server returns its default certificate or its default site; if Require Server Name Indication is on in IIS, or in services where SNI is mandatory, such as ADFS, the connection is not established at all.
Solution: Two Methods
| Your situation | Suitable method |
|---|---|
| From the UI; each request's own name should go, or a single fixed name is enough | Method 1: SNI field |
| From the command line | Method 2: WEB-CLI |
Method 1: SNI Field Recommended
- How it works TR7 writes the value in the SNI field into the ClientHello message of the TLS connection it establishes to the Backend Service. If the value is a variable added with fx, it is recalculated in each request.
- Where it is openedLoad Balancer → Backend Services → Edit → SSL Service → SNI
- Requirement SSL Service on in the Backend Service; a port on the server that listens with TLS
- vService type HTTP
Step-by-Step Configuration
On the Load Balancer → Backend Services screen, the Backend Service is selected and Edit is clicked. If the setting is to be given in common to all the servers in a Backend Group, the group is edited on the Load Balancer → Backend Groups screen.
SSL Service must be on; only then does the SNI field appear (What is SSL bridging; how do I also encrypt the traffic to the backend?).
For the name requested by the client to be sent, the fx button next to the SNI field is clicked; the window opens with the Request HTTP header content variable and Header Name = Host, Submit is clicked, and the ↓H badge appears in the field. If the server works with a single name, this name is written in the field as a fixed value (e.g. portal.example.com).
Edit at the bottom of the form is clicked; the setting is applied to all the vServices that use the Backend Service. In a cluster setup, with the default auto-sync, the change is also sent to the peer device; if Manual Sync Mode is on, it is sent to the peer device manually.
Verification
On the server, the ClientHello message of the connection coming from TR7 is captured; since SNI is unencrypted, the name can be read.
Command: tcpdump -nn -A -s0 -i any tcp port 443 | grep -a portal.example.com
The requested domain name appears in the ClientHello · the correct site respondsMethod 2: WEB-CLI
- How it works The SNI field is written from the command line. Since
--snican be used only with--sslService true, the two fields are written in the same command. - Where it is opened TR7 WEB-CLI →
lb backend update - Requirement WEB-CLI access; a port on the server that listens with TLS
- vService type HTTP
Step-by-Step Configuration
In place of <id>, the Backend Service is selected with Tab (SSL fields); since the command also keeps SSL Service on, it is used only on servers that listen with TLS:
lb backend update id <id> --sslService true --sni portal.example.comFor each request's own name to go, the variable that corresponds to the fx selection in the UI is written in single quotes:
lb backend update id <id> --sslService true --sni '%REQHEADER(Host)'Verification
Command: lb backend show <id>
sslService true · sni portal.example.comCommon Mistakes
- Leaving the SNI field empty. SNI is not sent and the form gives no warning; on a server that requires SNI, the default site or a connection error is seen.
- Expecting SNI while SSL Service is off. SNI is sent only when TR7 connects to the Backend Service with TLS; while SSL Service is off, the field does not appear in the form.
- Using the Host header variable on an L7 TCP vService. An L7 TCP vService does not read HTTP headers; this field is applied on HTTP vServices.
- Overlooking the relationship between SNI and certificate verification. When used together with Certificate Verification = Required, the name in the server certificate is checked against the SNI value; if a name that is not in the certificate is written in SNI, the connection is not established (Can I verify the backend certificate when connecting to the backend over HTTPS?).
How it is done in the documentation
