Squid connector¶
The Squid connector — binary enforcegate-squid-connector, configured by squid-connector.conf — runs in one of two Squid helper roles:
url_rewrite_program(default invocation, the historical role) — receives every URL Squid sees and forwards the request to the engine for evaluation. The engine returns a verdict (permit, deny, warn, AUP) and the connector translates it back to Squid as either an unchanged URL (permit), a302redirect URL (block / warn / AUP verdicts), or a rewritten URL (advanced use).external_acl_type(--aclinvocation, new in 2026.35.0) — runs as a Squid external-ACL helper consulted at the SslBump peek step. Returnssplice/bump/terminatefor cert-pinned destinations the engine has policy on — see Pinned destinations. The fallback behaviour when the helper can't reach the engine is configured via[ssl_bump_acl].fail_action.
The two roles are wired into Squid by the deployment / toolbox layer (the generated squid.conf and inspect.conf), not by operators directly. Both roles open their own Defendr session to the engine over the same protocol; a deployment running both shows them as separate rows in show neighbor summary.
Communication with the engine uses the proprietary Defendr binary protocol over TCP, upgraded to TLS after mutual authentication.
Squid maintains a pool of connector processes (5 by default in the standalone image). Each helper holds a long-lived Defendr session to the engine; the engine's show-neighbor-summary reports one row per connector helper.
The connector binary is /usr/local/bin/enforcegate-squid-connector inside the standalone image. It runs as the squid user (added to the enforcegate group by the Dockerfile so it can read the shared config files).
Stdout is reserved for Squid
The connector's LoggerConsole (when [logging].type = "console") writes its log output to stderr, never stdout. Stdout is the url_rewrite_program protocol channel — every line on it is parsed by Squid as a verdict response, so any other content would corrupt the protocol.
In a container, docker logs captures both streams interleaved (with the connector's lines tagged [connector] by the container log pipeline). For a bare-metal Squid forwarding to a remote engine, redirect them separately: 2>connector.log.
SIGTERM is normal
Squid sends SIGTERM to surplus connector helpers when load drops (the idle= argument to url_rewrite_children controls this). The connector logs SIGTERM received, exiting at [info] — this is expected behaviour, not an error. Squid spawns replacements on demand.
Configuration file¶
The connector reads its configuration from a TOML file. The default location is /etc/enforcegate/squid-connector.conf.
[global]¶
The [global] section defines per-connector identification parameters and timers.
| Name | Type | Description | Default |
|---|---|---|---|
asn |
string | Connector's Autonomous System Number (ASN). | 64512 |
ip |
string | Connector's identifier in dotted-decimal notation. | 127.0.0.1 |
retry |
integer | Retry timer interval, in milliseconds. | 30000 |
timeout |
integer | Timeout timer interval, in milliseconds. | 60000 |
dead |
integer | Dead timer interval, in milliseconds. | 180000 |
asn¶
The Autonomous System Number (ASN) of the connector. A unique 16-bit integer (1–65534) identifying a distinct administrative entity in the EnforceGate ecosystem. Default 64512.
ip¶
The connector's identifier. As of this writing it is used solely for administrative purposes and does not necessarily reflect the actual source IP of the engine session.
retry¶
Retry timer interval in milliseconds. Default 30 000 ms (30 s).
timeout¶
Duration after which an inactive engine is considered timed out. A keepalive is sent to verify the engine is still alive.
dead¶
Time after which an unresponsive engine is declared dead. The connector tears down the local session state and re-establishes from scratch.
[engine.<name>]¶
One sub-table per engine that the connector is allowed to connect to. The standalone image ships with exactly one entry ([engine.remote], pointing at loopback) and the engine pinned to the same host.
| Name | Type | Description | Default | Required |
|---|---|---|---|---|
net |
string | Transport protocol (currently only "tcp"). |
"tcp" |
Optional |
host |
string | Hostname or IP address of the engine. | Mandatory | |
port |
integer | Engine destination port (Defendr listener). | 11224 |
Optional |
key |
string | Shared authentication key. | Mandatory |
Example:
host¶
The hostname or IP address of the engine.
port¶
The TCP port to connect to. Default 11224 matches the engine's [connectors.local] listener.
key¶
Mandatory key attribute
EnforceGate enforces mutual peer authentication between the engine and the connectors. The key attribute is mandatory and must be explicitly configured. The connector silently aborts with no diagnostic if the key is missing.
The shared authentication key for mutual peer authentication. Any string of up to 128 characters; longer keys are truncated. Must match the engine's [connectors.<name>].key value (case-sensitive).
In the standalone image, the generate-engine-key boot one-shot writes the same random 32-character key into both files on first boot.
[redirector]¶
The [redirector] table configures how the connector parses the request line Squid pipes to it on stdin.
| Name | Type | Description | Default |
|---|---|---|---|
request_line_format |
integer | Squid request-line format the connector expects. | 1 |
request_line_format¶
0— standard. URL only, all other Squid macros ignored. The engine sees only the URL — no client IP, no SNI, no headers. The captive-portal "Proceed anyway" CTA cannot be rendered in this mode (theack_tokenemit precondition checks!clientIp.empty()).1— QF-3 (default). URL plus 17 tab-separated extras parsed positionally into the engine'sHTTPAttributes(client IP, MAC, username, listener IP/port, method, protocol, scheme, TLS version, SNI, domain, port, path, User-Agent, Referer, Accept, Accept-Language). Must be paired with the correspondingurl_rewrite_extrasdirective insquid.conf— see Squid integration below.
[tls]¶
The [tls] section governs the connector's TLS posture when connecting to the engine.
| Name | Type | Description | Default |
|---|---|---|---|
disable |
bool | Disable TLS support. | false |
disable¶
Disable TLS support entirely. The connector will not attempt to upgrade the Defendr session to TLS and will use unencrypted communication instead.
Security risks
We strongly recommend against disabling TLS. Disabling it leaves all communication between the engine and the connector vulnerable to man-in-the-middle attacks and eavesdropping. Disable only on loopback inside a single container for explicit performance benchmarking.
Performance considerations
Disabling TLS may improve performance by reducing the per-request processing overhead associated with encryption — at the cost of security. The shipped standalone image uses TLS by default even on loopback for defence in depth.
[ssl_bump_acl]¶
Consulted only when the connector is launched in --acl mode (Squid external_acl_type helper role; the url_rewrite_program role is separate). The connector returns a peek-step verdict to Squid based on the engine's pin: rules — see Pinned destinations.
| Name | Type | Description | Default |
|---|---|---|---|
fail_action |
string | The verdict the helper returns when it can't reach the engine (session down, timeout). One of splice, bump, terminate. Default splice for availability — pinned apps keep working through an engine blip instead of breaking under a forced bump. bump is the right choice for inspection-first deployments; terminate for fail-closed postures. |
"splice" |
The --acl connector role is wired by the deployment layer (the generated inspect.conf / init-ssl-bump.sh), not authored by operators directly. Operators set fail_action if their availability vs inspection trade-off differs from the default.
Squid integration¶
In the standalone image the connector is launched by Squid as a url_rewrite_program helper. The shipped squid.conf carries:
url_rewrite_program /usr/local/bin/enforcegate-squid-connector -c /etc/enforcegate/squid-connector.conf
url_rewrite_children 5 startup=1 idle=1 concurrency=0
url_rewrite_extras "%>a\t%>eui\t%un\t%>la\t%>lp\t%>rm\t%>rv\t%>rs\t%ssl::>negotiated_version\t%ssl::>sni\t%>rd\t%>rP\t%>rp\t%{User-Agent}>h\t%{Referer}>h\t%{Accept}>h\t%{Accept-Language}>h"
acl CONNECT method CONNECT
url_rewrite_access deny CONNECT
url_rewrite_access allow all
url_rewrite_bypass off
The url_rewrite_extras macros are TAB-separated (literal U+0009, not the two-character escape) and parsed positionally by the connector. A field-count mismatch throws on the first request with a clear diagnostic — there is no silent fallback.
CONNECT requests are not sent to the rewriter
url_rewrite_access deny CONNECT ensures the connector is never asked about a CONNECT host:port request. Without this guard, a blocked-host policy would respond with a deny-redirect URL, Squid would emit HTTP/1.1 302 Found on the CONNECT itself (a protocol violation), and browsers would surface NS_ERROR_CONNECTION_REFUSED. With ssl_bump active, blocking still works end-to-end: Squid bumps the CONNECT, the in-plaintext inner GET flows through the rewriter, and the deny-redirect is delivered inside the bumped TLS session.
For deploying a standalone Squid on a different host that forwards to a remote EnforceGate engine, replicate this stanza in that host's squid.conf, install the enforcegate-squid-connector binary plus its squid-connector.conf (with [engine.remote].host pointing at the engine's reachable address), and ensure the connector binary has read access to the conf file.