Can I put my gRPC services behind TR7?
Short answer
Yes. Since gRPC runs over HTTP/2, both sides of the connection must be HTTP/2: on the HTTP vService, HTTP/2 is selected as the frontend Protocol and a certificate is attached, and on the Backend Service, SSL Service is turned on and HTTP 2.0 Enabled is selected in the ALPN field; if the gRPC server listens on unencrypted HTTP/2 (h2c), SSL Service is left off and Cleartext HTTP/2 (h2c) is checked. Since the connection TR7 opens to the Backend Service is HTTP/1.1 by default, gRPC calls do not work unless one of these two settings is made. If TLS is to terminate on the gRPC server, passthrough with an L7 TCP vService can also be used.
Problem: Why Does gRPC Not Work with the Default Settings?
gRPC carries requests and responses over HTTP/2 streams and cannot fall back to HTTP/1.1. In TR7, the client side is opened in the HTTP/2 frontend row; but the connection TR7 opens to the Backend Service is HTTP/1.1 by default. On the Backend Service side, HTTP/2 is opened over TLS with ALPN, or on an unencrypted connection with the Cleartext HTTP/2 (h2c) setting.
Solution: Two Methods
| Your situation | Suitable method |
|---|---|
| TR7 should see the request: HTTP Logs, WAF and path-based routing should be used | Method 1: HTTP vService |
| TLS and the HTTP/2 negotiation should stay end to end on the gRPC server | Method 2: L7 TCP passthrough |
Method 1: HTTP vService Recommended
- How it works TR7 talks to the client over HTTP/2 and forwards the request to the Backend Service with HTTP/2 over TLS or with unencrypted HTTP/2 (h2c).
- Where it is opened vService → Frontend → Protocol → HTTP/2; Backend Service → SSL Service → ALPN → HTTP 2.0 Enabled or, on an unencrypted server, Backend Service → Cleartext HTTP/2 (h2c)
- Requirement A certificate uploaded to TR7; the gRPC server offering HTTP/2 over TLS or unencrypted HTTP/2 (h2c)
- vService type HTTP
- Backend Service side On the TLS path, the gRPC server is made to listen with TLS (with a certificate); TR7 does not verify this certificate by default (verification can be turned on with Certificate Verification).
Step-by-Step Configuration
On the Load Balancer → Backend Services screen, the Backend Service of the gRPC server is selected and the Edit button is clicked. If there is no Backend Service, the add form is opened with Add (How is a Backend Service added; which information is required?).
For a new Backend Service, Backend Service Name and Address (the IP of the server and the TLS port, e.g. 192.0.2.30:443; on a server listening on h2c, the unencrypted port) are entered. For an existing record, it is checked that the port in Address is the port the server listens on.
SSL Service is turned on; TR7 connects to the Backend Service with TLS. If the gRPC server listens on unencrypted HTTP/2 (h2c), SSL Service is left off, Cleartext HTTP/2 (h2c) is checked and step 4 is skipped; if the health check is HTTP, HTTP/2 is selected in the HTTP Version field of the Health Checks profile.
HTTP 2.0 Enabled is selected in the ALPN field.
The Edit (Add for a new record) button at the bottom of the form is clicked.
If the certificate of the domain the clients will connect to is not in TR7, the Certificates & PKI → SSL/TLS Certificates → Add steps are followed (how to add).
Certificate Name is entered. For separate PEM files, Type = Manual is selected and the certificate and the private key are pasted into the Certificate Content and Key Content fields; for a PFX file, PFX is selected, the file is selected from the PFX File field and the password of the file is entered in the Password field. Details: How do I upload my certificate to TR7; which formats are supported?
The Add button at the bottom of the form is clicked.
On the Load Balancer → Load Balancer vService List screen, the vService of type HTTP is selected and the Edit button is clicked; for a new vService, the form is opened with Add, Name is entered and Type stays HTTP.
In the Protocol field of the row with port 443, HTTP/2 is selected from the Encrypted (HTTPS) group, and the certificate is selected in the Certificate field.
The gRPC Backend Service is selected in the Default Backend Services table.
If there are long-running (streaming) calls, the Details → Timeout box is checked and a Timeouts profile whose Client Timeout and Server Timeout values (default 90 seconds) are greater than the longest stream silence is selected. If there is no profile, it is first created with Load Balancer → Profiles → Timeouts → Add (how to add). Editing a profile used by other vServices affects them too (Why is the request cut off during long operations (report, file upload); which timeout should I increase?).
The Save button is clicked. In a cluster setup, the change is also transferred to the peer device with the default auto-sync; if Manual Sync Mode is on, it is sent manually with Synchronize.
Verification
grpcurl api.example.com:443 listThe list of services on the serverlist command requires reflection to be on in the server; if it is off, a method is called with grpcurl -d '{}' api.example.com:443 paket.Servis/Metot.The gRPC call is examined on the HTTP Logs screen of the vService.
POST HTTP/2.0 https://api.example.com/paket.Servis/MetotMethod 2: L7 TCP Passthrough
- How it works TR7 does not decrypt TLS; the encrypted stream goes to the gRPC server as it is, and the HTTP/2 negotiation is made directly between the client and the server.
- Where it is opened vService → Type: L7 TCP → Frontend → Protocol: TCP
- Requirement The certificate being on the gRPC server; SSL Service being off on the Backend Service
- vService type L7 TCP
- Backend Service side The gRPC server performs TLS and the HTTP/2 negotiation itself; no change is required on the server.
Step-by-Step Configuration
On the Load Balancer → Backend Services screen, the Backend Service of the gRPC server is selected and the Edit button is clicked; if there is none, the add form is opened with Add.
Address is the TLS port of the server (e.g. 192.0.2.30:443; for a new record, Backend Service Name is also entered) and SSL service stays off. If SSL service is on, TR7 opens its own TLS session to the server and the encrypted stream of the client enters a second TLS layer.
The Edit (Add for a new record) button at the bottom of the form is clicked.
The Load Balancer → Load Balancer vService List → Add steps are followed; Name is entered and L7 TCP is selected as the Type.
In the Frontend row, the IP is selected, the port is set to 443 and TCP in the Unencrypted group is selected as the Protocol. TCP + TLS is not selected: with this option, TR7 terminates TLS and offers only HTTP/1.1 to the client in ALPN; the gRPC client cannot connect. If the IP is not in the list, it is first added with Network → Interfaces → Actions → Add IP (Why can't I type the Frontend IP manually; what should I do to use an IP that is not in the list (e.g. IPv6) on a vService?).
The gRPC Backend Service is selected in the Default Backend Services table.
The Save button is clicked. In a cluster setup, the change is also transferred to the peer device with the default auto-sync.
Verification
grpcurl api.example.com:443 listThe list of services on the serverCommon Mistakes
- Not turning on ALPN on the Backend Service (Method 1). If HTTP 2.0 Enabled is not selected in the ALPN field, TR7 connects to the Backend Service with HTTP/1.1; gRPC calls fail.
- Turning on SSL Service on a gRPC server that listens on unencrypted HTTP/2 (h2c) (Method 1). For a server without TLS, SSL Service is left off and Cleartext HTTP/2 (h2c) is checked; if this setting is not made, TR7 connects to the server with HTTP/1.1.
- Leaving SSL service on in passthrough (Method 2). While SSL Service is on, the TLS session of the client reaches the server inside a second TLS layer and the connection cannot be established.
- Using the Keep Header Names action. On the vService this action is attached to, HTTP/2 is turned off and gRPC does not work.
- Looking for a gRPC-specific health check. There is no gRPC among the health check types; a health check of type TCP, which checks the connection to the Backend Service, or TCPS, which also checks the TLS handshake, is assigned.
How it is done in the documentation
