Watch
0
0
Fork
You've already forked hyperhive
0

deny the IPv6 unspecified address at squid

This commit is contained in:
atlas 2026-10-28 14:27:43 +01:00 • committed by mara
commit e8868d52a8
4 changed files with 13 additions and 4 deletions

View file

@ -260,7 +260,7 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
- **Denied before any allow.** Destinations that resolve to loopback, - **Denied before any allow.** Destinations that resolve to loopback,
link-local, the bridge subnet, a private range (`10.0.0.0/8`, link-local, the bridge subnet, a private range (`10.0.0.0/8`,
`172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`), shared address space `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`), shared address space
(`100.64.0.0/10`), `0.0.0.0/8`, multicast or reserved space, and IP-literal (`100.64.0.0/10`), `0.0.0.0/8`, `::`, multicast or reserved space, and IP-literal
hosts, for every user including the unrestricted ones and for listed names. hosts, for every user including the unrestricted ones and for listed names.
Squid resolves names on the host and connects from it, so without these a Squid resolves names on the host and connects from it, so without these a
name pointing at `127.0.0.1`, at the host's own LAN address or at a private name pointing at `127.0.0.1`, at the host's own LAN address or at a private

View file

@ -35,6 +35,10 @@ let
# bridge, and the private, shared (CGNAT), unspecified, multicast and # bridge, and the private, shared (CGNAT), unspecified, multicast and
# reserved ranges. Squid checks the address it connects to, so a name an # reserved ranges. Squid checks the address it connects to, so a name an
# agent controls cannot point past them. # agent controls cannot point past them.
# `::` is listed because a connect to it lands on loopback; squid's
# built-in `to_localhost` has `0.0.0.0/32` and `::1` but not `::`. NAT64
# (`64:ff9b::/96`) and 6to4 (`2002::/16`) embed IPv4 addresses and are left
# out: they matter only on a host with such a route.
privateRanges = [ privateRanges = [
"10.0.0.0/8" "10.0.0.0/8"
"172.16.0.0/12" "172.16.0.0/12"
@ -45,6 +49,7 @@ let
"240.0.0.0/4" "240.0.0.0/4"
"fc00::/7" "fc00::/7"
"ff00::/8" "ff00::/8"
"::/128"
]; ];
# Evaluated top to bottom, first match wins. The destination denies sit # Evaluated top to bottom, first match wins. The destination denies sit
@ -206,7 +211,7 @@ in
for an unrestricted user. The self-check canary is allowed on top of for an unrestricted user. The self-check canary is allowed on top of
this list. A name must resolve, on this host's resolver, to a public this list. A name must resolve, on this host's resolver, to a public
address: one in a loopback, link-local, private, shared (100.64.0.0/10), address: one in a loopback, link-local, private, shared (100.64.0.0/10),
multicast or reserved range, or in the bridge subnet, gets a 403 for multicast or reserved range (or is `::`), or in the bridge subnet, gets a 403 for
every user. every user.
''; '';
}; };

View file

@ -550,6 +550,7 @@ let
"240.0.0.0/4" "240.0.0.0/4"
"fc00::/7" "fc00::/7"
"ff00::/8" "ff00::/8"
"::/128"
]; ];
} }
{ {

View file

@ -120,9 +120,10 @@ pkgs.testers.runNixOSTest {
imports = [ imports = [
hiveStubs hiveStubs
../host-modules/hive-squid.nix ../host-modules/hive-squid.nix
# Listeners a leaked destination would reach: loopback and the bridge. # Listeners a leaked destination would reach: loopback (`::` lands on `::1`) and the bridge.
(listen443 [ (listen443 [
"127.0.0.1" "127.0.0.1"
"[::1]"
bridgeIp bridgeIp
]) ])
]; ];
@ -157,6 +158,7 @@ pkgs.testers.runNixOSTest {
${bridgeIp} = [ "bridge.t.local" ]; ${bridgeIp} = [ "bridge.t.local" ];
"169.254.169.254" = [ "meta.t.local" ]; "169.254.169.254" = [ "meta.t.local" ];
"fd00:99::2" = [ "ula.t.local" ]; "fd00:99::2" = [ "ula.t.local" ];
"::" = [ "any6.t.local" ];
} }
// lib.listToAttrs ( // lib.listToAttrs (
map (p: { map (p: {
@ -173,6 +175,7 @@ pkgs.testers.runNixOSTest {
"bridge.t.local" "bridge.t.local"
"meta.t.local" "meta.t.local"
"ula.t.local" "ula.t.local"
"any6.t.local"
] ]
++ map (p: p.name) privateNets; ++ map (p: p.name) privateNets;
}; };
@ -242,7 +245,7 @@ pkgs.testers.runNixOSTest {
web.wait_for_unit("nginx.service") web.wait_for_unit("nginx.service")
proxy.wait_for_open_port(3128, "${bridgeIp}") proxy.wait_for_open_port(3128, "${bridgeIp}")
PRIVATE = ["priv10.t.local", "priv172.t.local", "priv192.t.local", "cgnat.t.local", "ula.t.local"] PRIVATE = ["priv10.t.local", "priv172.t.local", "priv192.t.local", "cgnat.t.local", "ula.t.local", "any6.t.local"]
def connect(host, cred=None): def connect(host, cred=None):
# The status squid answered the CONNECT with; 000 when none came back. # The status squid answered the CONNECT with; 000 when none came back.