On 2024-10-25 18:18, Erik Schulz wrote:
I would like to use squid as an egress proxy, to prevent unauthorized egress.
Let's say that the only allowed egress is 'example.com'.
I can define acl along the lines of:
```
acl allowed_domains ssl::server_name .example.com
http_access allow allowed_domains
```
But can someone help me understand what actually happens?
A lot of thing happens, including: After parsing received HTTP(S) or FTP
request, Squid checks http_access rules and either allows or denies the
request. For HTTPS requests that are subject to ssl_bump rules, that
processing happens multiple times, at various SslBump steps, as detailed
at https://wiki.squid-cache.org/Features/SslPeekAndSplice
N.B. http_access check is a part of "Callout Sequence" referenced on the
above page in step1 and step2. There are some bugs in the current Squid
implementation of that document, but it is still a useful starting point.
I want to avoid any DNS egress attack.
How do you define "DNS egress attack"? To the extent possible, please
answer in terms of what Squid should or should not do with traffic Squid
receives.
The client does not have DNS access.
Am I correct that the client can use HTTPS_PROXY without DNS, such
that the proxy will perform the DNS lookup?
If you do not control the client, then you should assume that it can
send any request to/through Squid. This includes sending an HTTPS
requests without using DNS. Whether the proxy receiving the request is
going to perform a DNS lookup is a separate question. Many factors
affect that proxy decision.
Can you help me understand how the acl checks the server_name?
You already know how server_name documentation answers this question. It
is not clear to me what undocumented aspects you want to know about.
Could you please clarify by asking a more specific question?
In order to connect to the server, it must perform a DNS lookup, which
causes a leak.
Sorry, I am not sure what "it" is in this context, but, as you probably
already know from the same docs, "Unlike dstdomain, [ssl::server_name]
ACL does not perform DNS lookups."
If Squid needs to connect to server X, and X is a domain name, Squid
will (in most cases) attempt to resolve X to get server IP address(es),
but that attempt happens before and/or after Sqiud evaluates
ssl::server_name ACL.
So the ACL must validate the server_name without a DNS lookup, and
since the server IP is therefore unknown, without connecting to the
server or verifying against its certificate.
During server_name ACL evaluation, Squid does not attempt to connection
to any other server or service. The ACL match/mismatch decision is made
by comparing various strings using either domain comparison function
(for server_name) or regex evaluation (for server_name_regex).
The server IP address may or may not be known at ssl::server_name
evaluation time.
I'm assuming the hostname is known in the CONNECT phase of the request?
Assuming that CONNECT request has arrived at http_port, the answer
depends on many factors, possibly including:
* whether the client supplied a hostname in CONNECT request headers;
* whether the client supplied a hostname in TLS SNI field;
* whether the CONNECT request is subject to ssl_bump rules;
* whether Squid is opening a tunnel to an origin server or cache_peer
Is it possible to check against the connect hostname only?
Without SslBump, "dstdomain -n" would probably do that. With SslBump,
"dstdomain -n" would probably do that during SslBump step1 (and step2 if
client does not supply TLS SNI). All this needs careful testing though;
there are many configuration parameters and request specifics at play here!
The docs say that
"The ACL computes server name(s) using such information sources as CONNECT request URI, TLS client SNI, and TLS server certificate subject (CN and SubjectAltName). The computed server name(s) usually change with each SslBump step"
I find this concerning, because I assume the client could perform a
request with an IP, and a forged SNI name that passes the acl.
So I would like to only allow requests that declare FQDN hostname, and
reject IP hostnames.
You probably can use dstdomain_reject to reject IP-based hostnames, but
it may not be easy to do it reliably using regular expressions because
IP addresses come in many forms. Squid is probably missing an
"dst_is_ip" or similar ACL(s) to make such checks reliable.
And, only perform validation against the CONNECT request URI.
See above regarding using "dstdomain -n" for this.
HTH,
Alex.
_______________________________________________
squid-users mailing list
squid-users@xxxxxxxxxxxxxxxxxxxxx
https://lists.squid-cache.org/listinfo/squid-users