[squid-users] Help regarding access controls for TLS connections

Erik Schulz erikschulz184 at gmail.com
Mon Oct 28 15:47:10 UTC 2024


Hi Alex,

Thank you for your detailed response!

I realized later that I was applying 'localnet' rules before the
dstdomain rules, which was the cause of the unauthorized dns lookup.
By rearranging the rules, such that `dstdomain -n` rules are tested
first, there is no dns lookup. Well, I do see a reverse dns lookup for
the client's ip, that I can't explain, but even if that is the case,
it would require client IP spoofing. But I don't understand why the
reverse lookup happens. I'm only testing `src`, not `srcdomain`.
----
# deny if not authenticated
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
acl authenticated proxy_auth REQUIRED
http_access deny !authenticated

# deny if not allowed domains
acl user_user2 proxy_auth user2
acl allowed_domains2 dstdomain -n .example.com
http_access deny user_user2 !allowed_domains2

# deny public ip
acl localnet_src src 0.0.0.1-0.255.255.255
acl localnet_src src 10.0.0.0/8
acl localnet_src src 100.64.0.0/10
acl localnet_src src 169.254.0.0/16
acl localnet_src src 172.16.0.0/12
acl localnet_src src 192.168.0.0/16
acl localnet_src src fc00::/7
acl localnet_src src fe80::/10
http_access deny !localnet_src

# deny local destination (resolved hostname)
acl localnet_dst dst 0.0.0.1-0.255.255.255
acl localnet_dst dst 10.0.0.0/8
acl localnet_dst dst 100.64.0.0/10
acl localnet_dst dst 169.254.0.0/16
acl localnet_dst dst 172.16.0.0/12
acl localnet_dst dst 192.168.0.0/16
acl localnet_dst dst fc00::/7
acl localnet_dst dst fe80::/10
http_access deny localnet_dst

acl Safe_ports port 80
acl Safe_ports port 443
http_access deny !Safe_ports

cache deny all

http_access allow
----

Regarding what DNS egress attack is:
The use of a forward proxy ("egress controller") is to prevent
unauthorized egress, i.e. leaking any data, including TLS or CA
private keys, which can be relatively few bytes.
Unauthorized DNS egress is low bandwidth, but that doesn't matter.
Here is a ChatGPT explanation of what a DNS egress attack is:
---
A DNS egress attack exploits DNS queries to stealthily extract
sensitive information from within a network. Here’s how it operates
and why it’s effective:
- DNS as a Covert Channel: DNS requests are typically unfiltered and
allowed through most firewalls. Attackers use DNS requests to
exfiltrate data by embedding information in DNS queries, which often
bypasses traditional egress filters.
- Steganography in DNS Requests: Attackers encode sensitive
information (like passwords or encryption keys) into DNS request
subdomains. For example, a query like data1234.attacker.com can encode
data (data1234) before resolving to the attacker-controlled domain.
- Recursive Resolver Complicity: Since DNS queries are recursively
resolved, intermediate DNS resolvers help propagate the data-laden
requests to the final DNS server controlled by the attacker. This adds
complexity to tracking and blocking the egress path.
- Low Detectability: Normal DNS queries blend into typical network
traffic, making these attacks hard to detect, especially if small
amounts of data are exfiltrated over time.
- Mitigation Gaps: Most firewalls overlook the payload within DNS
queries, focusing instead on blocking IPs or domains, which doesn't
stop the encoding of sensitive data in the DNS request itself.
- DNS data egress attacks are potent because they exploit a
foundational internet protocol for covert data transmission. Solutions
demand vigilant DNS traffic analysis and strict egress filtering
policies.
---

On Mon, Oct 28, 2024 at 12:14 AM Alex Rousskov
<rousskov at measurement-factory.com> wrote:
>
> 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 at lists.squid-cache.org
> https://lists.squid-cache.org/listinfo/squid-users


More information about the squid-users mailing list