Skip to content

Explicitly deny to_localnet requests in squid.conf.default - #2491

Draft
rousskov wants to merge 6 commits into
squid-cache:masterfrom
measurement-factory:SQUID-1177-deny-to-localnet
Draft

rousskov wants to merge 6 commits into
squid-cache:masterfrom
measurement-factory:SQUID-1177-deny-to-localnet

Conversation

@rousskov

Copy link
Copy Markdown
Contributor

This ban is not appropriate for some use cases, but our default
configuration template should prioritize safety over coverage breadth.
This work can be seen as a followup to 2022 commit 6d2f8ed.

The new to_localnet ban appears to use a more complex http_access rule
than existing to to_localhost and to_linklocal bans, but that
additional complexity is misleading: In fact, existing bans should be
interpreted in their http_access allow localhost context. In other
words, existing bans can be viewed as if they were written like this:

http_access deny !localhost to_localhost
http_access deny !localhost to_linklocal

Existing bans exclude localhost requests because a client running on
localhost can send banned requests directly to those protected services,
bypassing Squid. We use the same "do not ban access to what the clients
may be able to access without going through Squid" logic for the new
to_localnet rule, resulting in the localnet clients exclusion:

http_access deny !localnet to_localnet

Unlike the localhost case, we do not want to allow all localnet
clients by default. That caveat necessitates a different rule shape.

XXX: This duplicates "local" address range definitions.
TODO: Add "local", similar to existing "all", "ipv4" and "ipv6" aliases?

Also show how to allow internally-generated requests. Without that or
some other "allow" rule that matches internally-generated requests, our
configuration template bans all AIA requests, effectively disabling
fetching of missing intermediate X.509 certificates. AIA requests are
currently the only known use case of an internally-generated request not
associated with a client-to-Squid connection. Typical src-based
http_access allow rules cannot cover such requests.

This ban is not appropriate for some use cases, but our default
configuration template should prioritize safety over coverage breadth.
This work can be seen as a followup to 2022 commit 6d2f8ed.

The new `to_localnet` ban appears to use a more complex http_access rule
than existing to `to_localhost` and `to_linklocal bans`, but that
additional complexity is misleading: In fact, existing bans should be
interpreted in their `http_access allow localhost` context. In other
words, existing bans can be viewed as if they were written like this:

    http_access deny !localhost to_localhost
    http_access deny !localhost to_linklocal

Existing bans exclude localhost requests because a client running on
localhost can send banned requests directly to those protected services,
bypassing Squid. We use the same "do not ban access to what the clients
may be able to access without going through Squid" logic for the new
`to_localnet` rule, resulting in the `localnet` clients exclusion:

    http_access deny !localnet to_localnet

Unlike the `localhost` case, we do not want to allow all `localnet`
clients by default. That caveat necessitates a different rule shape.

XXX: This duplicates "local" address range definitions.
TODO: Add "local", similar to existing "all", "ipv4" and "ipv6" aliases?

Also show how to allow internally-generated requests. Without that or
some other "allow" rule that matches internally-generated requests, our
configuration template bans all AIA requests, effectively disabling
fetching of missing intermediate X.509 certificates. AIA requests are
currently the only known use case of an internally-generated request not
associated with a client-to-Squid connection. Typical src-based
`http_access allow` rules cannot cover such requests.

@rousskov rousskov left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am marking this PR as a draft because I want to discuss two changes that may necessitate significant PR changes. Please see specific change requests for details.

Comment thread src/cf.data.pre
# Adapt to list your (internal) IP networks.
# It is common to deny access to these addresses, but your needs may vary.
acl to_localnet dst 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl to_localnet dst 10.0.0.0/8 # RFC 1918 local private network (LAN)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description:

XXX: This duplicates "local" address range definitions.
TODO: Add "local", similar to existing "all", "ipv4" and "ipv6" aliases?

These duplication problems and the elevated difficulty of addressing them were the reasons these changes were explicitly excluded from our earlier related work in #1161. Assuming we are still in agreement regarding this overall direction, we have two primary options here:

  1. Merge this PR with/despite this duplication of localnet address ranges. Follow up with a PR that adds a "local" alias, similar to existing "all", "ipv4" and "ipv6" aliases? That followup PR should also document "all", "ipv4", and "ipv6" aliases, I guess. Adding support for a "local" alias will not be trivial because existing alias-handling code cannot handle multiple distinct address ranges.
  2. Do the opposite: Post a PR that adds a "local" alias first. Then update this PR to use that alias to define to_localnet.

What is your preference? CC: @kinkie, @yadij.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This I think we should make to_linklocal a pre-define, unlike localnet the admin does not need to remove entries. They shoudl make a different ACL and allow X instead.

Possibly with small sub-defines for the ipv4_linklocal, ipv6_linklocal, ipv4_cgn, rfc1918, rfc1122, etc

@yadij yadij Sep 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "broadcast" ranges should also be prohibited as part of to_localnet. These are not relevant to the received (from-localnet), but can be for the outgoing to_localnet traffic.

For pre-define that would be ipv4_broadcast (255.255.255.255) and ipv6_broadcast (FFFF:...).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "broadcast" ranges should also be prohibited as part of to_localnet.

Done in branch commits 2e6d513 (IPv4) and cd71aeb (IPv6).

For pre-define that would be ipv4_broadcast (255.255.255.255) and ipv6_broadcast (FFFF:...).

For IPv6, there is no such thing as "broadcast" AFAICT. There is multicast that uses FF:: rather than FFFF: prefix. Commit cd71aeb adds multicast.

we should make to_linklocal a pre-define

I agree. The question is whether to do that in this PR or a separate one? Given many potential disagreements on what "aliases" and "predefines" should be added (not to mention "how" they should be implemented), I suggest doing that in a separate followup PR(s), leaving this PR definitions where they are now. Are you OK with that plan?


I hope that this part of the discussion belongs to a different dedicated PR:

unlike localnet the admin does not need to remove entries

I agree that admins may define "local" differently than RFCs do.

I disagree that those legitimate admin adjustment needs should determine what is "predefined" by Squid. I think it is a mistake to (continue to) design ACLs based on our http_access template in squid.conf.documented. That historical approach makes it difficult to interpret configurations correctly, increasing security risks:

  • What does X mean?
  • Ah, do not worry about it, it is a Squid-defined ACL. Squid guys know what they are doing!
  • Ah, OK, I will look for the problem elsewhere.
  • Oh, wait, we redefined X five years ago in this custom included file, before we enabled IPv6 traffic!
  • OMG! That explains why we allowed malicious traffic into our network!

Instead, Squid-provided definitions should be constant. If admins want to customize their access controls, they sure can, but they must use their own names for those customizations! I bet that best-written custom rules will not actually need to change what "localnet" or "all" means. They will just add http_access rules that use those built-in and other/custom ACLs to achieve the correct result.

Developers have learned the hard way that variables are dangerous. Named things should be constant by default. The same logic applies to writing complex access rules. If we were to start from scratch, we could make ACLs constant as well, but that is too big of a change. We can and should make Squid-defined ACLs and parameter aliases constant though (despite some inconveniences for existing configurations that attempt to modify them).

Comment thread src/cf.data.pre
Comment on lines +2016 to +2017
# acl internallyGenerated transaction_initiator internal
# http_access allow internallyGenerated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rule addition can be moved into a dedicated followup PR. AIA issues were the last straw that triggered creation of this long anticipated PR, and adding this AIA rule affects other comments in this section, so merging this work into this PR is borderline OK IMO, but please let me know if I should separate the two changes/concerns.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay with me, though it does seem to expand the scope. So title should be something more like "Improve default http_access security policy"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather not make the title so generic, especially since followup PRs may also "improve default policy". IMO, the existing "Also show how to allow internally-generated requests" paragraph in the PR description is enough to disclose this extra addition, but if you can suggest a more specific PR title that includes both topics, I would be happy to use it. FWIW, I tried to find one before posting this PR and failed.

Comment thread src/cf.data.pre

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
# INSERT YOUR OWN RULE(S) HERE TO ALLOW PERMITTED TRANSACTIONS.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I adjusted this line because Squid-generated transactions, like those AIA requests, are not "FROM YOUR CLIENTS".

I also wanted to de-emphasize the "from" aspect of access control. These rules are also about "to" or "destination" controls, even though our examples do not illustrate that concern directly.

This comment annotates changes without requesting any discussion affecting this PR "draft" status.

* `foo` quotes code or configuration
* "bar" uses quotes for standard English language purposes

@yadij yadij left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole issue smells like overriding admin misconfiguration to me.

FTR; The default policy is currently to block always-dangerous, allow only admin allowed traffic, then to block *all (including to-LAN traffic).

To do this properly without breaking admin rules - the deny to_localnet should ideally come after admin preferences so they can allow local servers through, but then it is redundant with deny all.

Comment thread src/cf.data.pre Outdated
Comment thread src/cf.data.pre
# missing intermediate X.509 certificates) to any destination that was not
# banned earlier (e.g., all `to_localnet` destinations were banned for such
# requests).
# acl internallyGenerated transaction_initiator internal

@yadij yadij Sep 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this can be a pre-define. Which would allow adding AIA as an exception to the proposed deny ... to_locanet addition earlier.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which would allow adding AIA as an exception to the proposed deny ... to_locanet addition earlier.

AFAICT, adding such an exception is not a good idea because we do not want to structure our default template to allow AIA access to localnet (after some allow rules are added as we instruct the admin to do in INSERT YOUR OWN RULE(S) HERE). In other words, we do want to deny AIA requests for localnet resources (in most cases).

I also disagree that it makes sense to pre-define/name such simple ACLs as internallyGenerated, but that is secondary.

Comment thread src/cf.data.pre Outdated
Comment thread src/cf.data.pre Outdated
rousskov and others added 4 commits September 14, 2026 16:08
Co-authored-by: Amos Jeffries <yadij@users.noreply.github.com>
... for the same reasons IPv4 broadcast (handled in the previous commit)
should be a part of that ACL.

@rousskov rousskov left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope I have addressed all in-scope concerns, especially if we keep aliases/pre-defines outside this PR scope.

Comment thread src/cf.data.pre
# Adapt to list your (internal) IP networks.
# It is common to deny access to these addresses, but your needs may vary.
acl to_localnet dst 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl to_localnet dst 10.0.0.0/8 # RFC 1918 local private network (LAN)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "broadcast" ranges should also be prohibited as part of to_localnet.

Done in branch commits 2e6d513 (IPv4) and cd71aeb (IPv6).

For pre-define that would be ipv4_broadcast (255.255.255.255) and ipv6_broadcast (FFFF:...).

For IPv6, there is no such thing as "broadcast" AFAICT. There is multicast that uses FF:: rather than FFFF: prefix. Commit cd71aeb adds multicast.

we should make to_linklocal a pre-define

I agree. The question is whether to do that in this PR or a separate one? Given many potential disagreements on what "aliases" and "predefines" should be added (not to mention "how" they should be implemented), I suggest doing that in a separate followup PR(s), leaving this PR definitions where they are now. Are you OK with that plan?


I hope that this part of the discussion belongs to a different dedicated PR:

unlike localnet the admin does not need to remove entries

I agree that admins may define "local" differently than RFCs do.

I disagree that those legitimate admin adjustment needs should determine what is "predefined" by Squid. I think it is a mistake to (continue to) design ACLs based on our http_access template in squid.conf.documented. That historical approach makes it difficult to interpret configurations correctly, increasing security risks:

  • What does X mean?
  • Ah, do not worry about it, it is a Squid-defined ACL. Squid guys know what they are doing!
  • Ah, OK, I will look for the problem elsewhere.
  • Oh, wait, we redefined X five years ago in this custom included file, before we enabled IPv6 traffic!
  • OMG! That explains why we allowed malicious traffic into our network!

Instead, Squid-provided definitions should be constant. If admins want to customize their access controls, they sure can, but they must use their own names for those customizations! I bet that best-written custom rules will not actually need to change what "localnet" or "all" means. They will just add http_access rules that use those built-in and other/custom ACLs to achieve the correct result.

Developers have learned the hard way that variables are dangerous. Named things should be constant by default. The same logic applies to writing complex access rules. If we were to start from scratch, we could make ACLs constant as well, but that is too big of a change. We can and should make Squid-defined ACLs and parameter aliases constant though (despite some inconveniences for existing configurations that attempt to modify them).

Comment thread src/cf.data.pre
# missing intermediate X.509 certificates) to any destination that was not
# banned earlier (e.g., all `to_localnet` destinations were banned for such
# requests).
# acl internallyGenerated transaction_initiator internal

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which would allow adding AIA as an exception to the proposed deny ... to_locanet addition earlier.

AFAICT, adding such an exception is not a good idea because we do not want to structure our default template to allow AIA access to localnet (after some allow rules are added as we instruct the admin to do in INSERT YOUR OWN RULE(S) HERE). In other words, we do want to deny AIA requests for localnet resources (in most cases).

I also disagree that it makes sense to pre-define/name such simple ACLs as internallyGenerated, but that is secondary.

Comment thread src/cf.data.pre
Comment on lines +2016 to +2017
# acl internallyGenerated transaction_initiator internal
# http_access allow internallyGenerated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather not make the title so generic, especially since followup PRs may also "improve default policy". IMO, the existing "Also show how to allow internally-generated requests" paragraph in the PR description is enough to disclose this extra addition, but if you can suggest a more specific PR title that includes both topics, I would be happy to use it. FWIW, I tried to find one before posting this PR and failed.

@rousskov
rousskov requested a review from yadij September 14, 2026 21:13
@rousskov rousskov added the S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box label Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants