On 26/02/2013 9:33 p.m., Steve Hill wrote:
On 25.02.13 22:30, Amos Jeffries wrote:
I still have the question about whether it is necessary to have this as
a full-blown ACL test, or if a flag on the http_port is sufficient.
- ACLs are more flexible, but a Fast-ACL lookup only goes halfway
towards supporting all the Slow-ACL things people will be tempted to use
there.
- The main use-cases supporting this as to noted will simply be "deny
all" or "allow all".
I agree that most use cases are going to be "allow all" or "deny all",
and in fact I originally implemented this as a flag on http_port.
However, I realised that a fast ACL is basically no more effort to
implement and offers more flexibility so would be a better approach.
Admittedly a slow ACL would be more useful, but would also require a
reasonable amount of code restructuring to implement.
- Using this directive makes TPROXY into an equivalent of NAT, and
since there is now NAT in both IPv4 and IPv6 firewalls no benefits over
just using NAT rules in the firewall to begin with.
I don't see this as an equivalent of NAT - we keep all the
functionality of an intercepting proxy (which far exceeds the
functionality of a plain NAT firewall - it allows caching, request
modification, etc.), but we disable the spoofing of IP addresses. In
essence we end up with similar functionality to the old "intercept"
mode, but in an IPv6-compatible way.
Which is ALG-NAT. Client source IP on traffic entering the box, and
Squid IP as source on traffic leaving it.
Currently, if you want to run a transparent proxy without spoofing the
client addresses, you either have to use "intercept" mode (which
doesn't support IPv6) or you have to use "tproxy" mode and allow Squid
to spoof the address and then use Netfilter rules to NAT it back to
the server's own address. This increases the complexity of the setup
- it seems pointless to have to use Netfilter rules to undo a feature
of Squid because you are unable to disable that feature. Also, as far
as I'm aware, Netfilter doesn't support NAT for IPv6, so this solution
is still IPv4-only.
They added it last August. It should be filtering down to general use
around kernel 3.4 or so.
Also, my years of experience configuring and administering networks
leads me to try and avoid NAT wherever possible - it does tend to
cause no end of problems that just wouldn't happen if you never used
NAT. Certainly we currently need NAT in many situations, but as the
internet migrates towards IPv6 hopefully those situations will
diminish and I would want to avoid engineering solutions that require
NAT simply because we are unable to disable some functionality that
isn't wanted.
As an example of where address spoofing is undesirable:
I have a customer with a single powerful proxy server at their main
office which has a high bandwidth internet connection. They also have
several branch offices with relatively low bandwidth ADSL connections
to the internet. Each branch office has a low power firewall that
intercepts IPv4 and IPv6 port 80 traffic and forwards it to the proxy
over a GRE tunnel.
So lets assume the main office is 10.1.0.0/16 and the branch office is
10.2.0.0/16.
Assuming we have the standard spoofing behaviour:
- A web client (10.2.0.1) at a branch office makes a web request to
something on the internet (lets say the web server is 10.200.200.200),
so we have traffic like:
10.2.0.1:ephemeral -> 10.200.200.200:80
- The traffic is intercepted by the firewall and sent to the proxy
(10.1.0.1)
- The proxy forwards the request to the real web server, spoofed from
the client's IP, so we have something like:
10.2.0.1:ephemeral -> 10.200.200.200:80
- The web server responds:
10.200.200.200:80 -> 10.2.0.1:ephemeral
Notice the web server's response is going to the client's address, so
it will go to the branch office ADSL. It will then need to be routed
back up the ADSL's slow upstream over the GRE tunnel in order to get
to the proxy, whereupon the proxy will forward the response back over
the ADSL to the branch office. This is very undesirable - its
massively increasing the amount of data being transferred over the
ADSL, and its going to be limited by the ADSL's slow upstream connection.
Far better would be to disable spoofing:
- A web client (10.2.0.1) at a branch office makes a web request to
something on the internet (lets say the web server is 10.200.200.200),
so we have traffic like:
10.2.0.1:ephemeral -> 10.200.200.200:80
- The traffic is intercepted by the firewall and sent to the proxy
(10.1.0.1)
- The proxy forwards the request to the real web server, not spoofed
so it comes from the proxy's IP:
10.1.0.1:ephemeral -> 10.200.200.200:80
- The web server responds:
10.200.200.200:80 -> 10.1.0.1:ephemeral
The web server's response goes directly back to the proxy.
Great. *This* is what I've been looking for for the commit description.
(Note, I've used RFC1918 addresses for everything here for simplicity,
but you can assume that, especially in the IPv6 case, these may
instead be global scope addresses, and so the web server really will
be sending traffic directly back to the client's spoofed address).
I'm on the fence for this, but definitely want to see a clear use-case
need before we add yet another ACL lookup to Squid.
Can I ask what you see as an advantage in adding an option to
http_port rather than an ACL lookup? An ACL lookup doesn't seem to
increase the code complexity much beyond what an http_port flag would
do and does add flexibility even if the majority of use cases don't
need anything beyond an on/off switch.
Code simplicity. An "if(flags.spoof)" test is far faster than even
constructing a checklist and processing "allow all" in fast-ACL pathway.
So if the ACL flexibility does not actually have a clear need the speed
would be better.
In the case described above, spoofing may be desirable for traffic
that originates from web clients in the main office but not for
clients in the branch offices, so there seems to be a clear use-case
for an ACL.
1) 3.3 is closed to new features now. This will have to be targeted at
3.HEAD for merge.
I'm happy to rework the patch for 3.HEAD.
- for the sslBump fakeRequest please use HttpRequest::Pointer instead of
HttpRequest*X= HTTPMSGLOCK(...); and HTTPMSGUNLOCK(X).
I will investigate this. Thank you.
Cheers.
Amos