Mutli-tenant TLS terminating proxy for L7 traffic. Supports unlimited domains and certs with HTTP/1.1, 2, and 3.
Unlike other solutions, Gildra sits in your cloud. This means that requests aren't slowed down by being routed through another provider, and nobody sees your unencrypted traffic but you.
All connections will be terminated and forwarded to the origin as HTTP(S)/1.1
Gildra supports answering both the ACME HTTP-01 challenge, and the ZeroSSL custom HTTP challenge.
The keys for each challenge token must be served by the Control Plane.
Env Var | Description | Required (that you set) | Default Value |
---|---|---|---|
INTERNAL_PORT |
The port that the internal API will listen on | no | 8091 |
SHUTDOWN_SLEEP_SECONDS |
The number of seconds that the server will sleep before shutting down servers. Used for when cloud load balancer take time to de-register. This will vary by setup. For example, AWS NLBs and ALBs with EKS should have this set to ~35 seconds based on production experience. |
no | 0 |
SHUTDOWN_TIMEOUT_SEC |
The number of seconds that are allowed for the servers to shutdown (the context deadline). During this time new connections are not accepted and existing connections must be drained. Useful for if you don't need SHUTDOWN_SLEEP_SECONDS . |
no | 1 |
CONCURRENT_FETCH_ROUTING_CONFIG |
Whether to concurrently fetch the routing config when fetching a cert. Set to anything other than 1 to disable. |
no | 1 |
CP_AUTH |
The bearer token that will be used when contacting the control plane. | no | none |
X-Fowarded-For
- will create or append to the headerX-Forwarded-Proto
- the protocol in which the inbound connection was made to the Gildra node. Options HTTP/1.1
, HTTP/2.0
, HTTP/3.0
X-Forwarded-To
This is the destination (e.g. http://internal-domain/path-prefix
) that the request was forwarded to, as the host header and path are based on the incoming request, this is based on the destination match. This is useful for when you have something like a tenant ID in a subdomain (e.g. {tenant}.internal-dash.domain.com
), and can easily pull the tenant ID out of the subdomain instead of doing a reverse domain name lookup of the host header in your DB.X-Url-Scheme
- the URL scheme of the request made to Gildra. Options https
, http
, ws
, wss
X-Replayed
- whether this request was replayed. The previous number of replays if replayed, otherwise the header is absent.G-Req-Id
- the Gildra request IDx-replay
headerIf your response has a status code of < 500 and has an x-replay
header, then the request will be replayed by the Gildra node targeting the address provided in the x-replay
header.
This allows you to relay a request to a specific IP address or domain (including protocol) within your private network.
If you exceed the MAX_REPLAYS
env var (default 3
) for a single request then it will return a 502 Bad Gateway
to the client and log a warning.
OTLP Tracing can be configured with the TRACING
(= 1
, default off), OLTP_ENDPOINT
, and TRACING_SERVICE_NAME
(default gildra
) environment variables. If an OTLP_ENDPOINT
is not provided, it will pretty-print to stdout for debug.
The metrics server is run by default in port 8091
. This can be changed with the INTERNAL_PORT
env var. Metrics will be served at /metrics
.
This was decided for a few reasons:
This is where the CONCURRENT_FETCH_ROUTING_CONFIG
setting comes in. Because certs are cached more aggressively, and you always need to have both the cert and routing config to answer a request, when we are filling the cert cache we asynchronously fill the routing config cache in the background.
This works especially well because the groupcache package not only already handles request collapsing, but since it's running on the same pool the owning node for the cert cache will also be the owning node for the routing config cache. In simpler terms that means they are cached in the same spot, so connections to the control plane can be reused when fetching both at the same time.
As a result, after we load the cert into the request handler and go to look up the routing config, we've already started fetching it and save that much time. Often it's ready in cache once we go to look it up!
While this wouldn't be too difficult to add, it does require a decent change in request handling architecture and configurability. Additionally, most services that use TCP directly such as databases prefer to be the managers of certificates and encrypted traffic (just see the warnings that happen when you run them without!), and are not multi-tenant in the same way a web service might be.
We also wanted the ability to support L7 configuration options like headers, routing, and more.
TL;DR we wanted to start simple, and hit the majority of uses cases.
It requires the least amount of involvement from end-users. They only have to make a single A
or CNAME
DNS record for base domains or subdomains.
With the DNS-01 challenge, they must delegate the ACME challenge to the hosting provider as a second DNS record. If they ever remove this record, then you are unable to manage certs for them. If they ever change the A
or CNAME
record it will be very obvious very fast that they've broken something.
You can still use Gildra with DNS-01 challenge certs though! For example if you wanted to support wildcard subdomains. However, Gildra won't handle the challenge for you.
You can check https://acmeclients.com/certificate-authorities/ for a great guide, but I would generally say start with Let's Encrypt.
For example Vercel uses Let's Encrypt. Cloudflare uses both Let's Encrypt and Google (among others, see: https://developers.cloudflare.com/ssl/edge-certificates/troubleshooting/caa-records/#what-caa-records-are-added-by-cloudflare)
Options I'd consider:
All of these offer free certificates when using ACME.