Tsantilas Christos wrote:
Issue 1: one cannot block CONNECT in an elegant way. I.e. a CONNECT
to an undesired site cannot be redirected or anything since the
application (possibly browser) want do a SSL handshake and it it fails
it displays the 'vague error' "cannot connect to site www.example.com"
which is indeed vague for an end user who usually only understands
messages like "you are not authorised to go to www.example.com".
For true SSL+HTTP (https) sites, issue 1 can be resolved by *not* blocking
the CONNECT and wait for the next "GET https://www.example.com/index.html"
and block/redirect this object. Lets call this a 'postponed SSL+HTTP
block'.
But for sites which do not use SSL+HTTP there is not a good solution since
Squid and the URL redirector only see a CONNECT and never see a
GET/HEAD/POST.
I think you are describing the Bump-Server-First feature which is
currently under development:
http://wiki.squid-cache.org/Features/BumpSslServerFirst
I read about this feature before posting. The feature description
only talks about CONNECT to an SSL+HTTP endpoint while I like
to extend the scope to CONNECT to any endpoint.
The number of data protocols that Squid can encounter are infinite:
- SSL+HTTP
- SSL+ANYTHING
- ANYTHING
Issue 2: Skype does not work any more with sslBump. SSH tunnels, VPNs
and other
chat applications also stop working with sslBump since the sslBump feature
does its SSL certificate checking and if this fails, the CONNECT fails.
Using the options 'sslproxy_cert_error allow all' and
'sslproxy_flags DONT_VERIFY_PEER' is not considered useful since thay are
truely very unsafe and I recommend never to use them.
A ways is to use ACLs to select sites and maybe applications which can
be sslBumped or not.
Eh, yeah. Not so easy. I do like very much that Squid administrators
make these lists. Not all admins have sufficient knowledge or complete
understanding of all pitfalls and risks.
ufdbGuard probes CONNECT endpoints and caches the result.
It has a table of known Skype login servers but there are many
Skype nodes (Skype users) that can only be detected dynamically.
For a CONNECT to a Skype endpoint, ufdbGuard has the knowledge to signal
to Squid to sslBump or not. And if the configuration says to block Skype,
ufdbGuard can signal to Squid "do not do the effort of doing an SSL handshake
and terminate the thing".
But lets not focus on just Skype, there is a growing number of applications
that use CONNECT. And they may use any protocol.
More background information:
The URL redirector ufdbGuard has a feature to probe HTTPS connections.
It does a SSL-handshake if this works it is followed by "GET / HTTP/1.0"
If the SSL-handshake does not work it probes for SSH, Skype and other
chat protocols to find out where the the application CONNECTs to.
ufdbGuard can block CONNECT to IP addresses but make exceptions
for the CONNECTs which are used by allowed chat protocols.
SSH and VPNs are blocked by ufdbGuard if the administrator has configured
to block proxies.
HTTPS is used more and more. Even Google uses it for their search engine.
It is necessary to have a safe HTTPS proxy and content filtering in an
absolutely safe and efficient way.
Proposal:
To have a good combination of web proxy and content filtering combination
I propose the following:
A) Squid's behaviour is modified for sslBump: after an unsuccessful SSL
handshake, the CONNECT does not fail any more by default. This is to
ensure
that Skype et al. remains functional.
Correct.
This behaviour partially is already implemented under the
Bump-Server-First feature.
I am saying partially because currently works only with HTTPS protocol
(requires that both client-to-squid and squid-to-server connections are
supporting SSL) but can easily extended to support other protocols.
It is easy to extend Bump-Server-First to not initiate SSL connection
with the client if the server is not an SSL server.
But again, why not using ACLs to avoid applying sslBump on applications
like skype?
What ACL do you have in mind?
B) Squid gets a new option to define its behaviour in case the SSL
handshake
fails. The options could be called sslBumpForNoneSSL with values
prohibitNoneSSL (terminate connection), passNoneSSL (always allow),
filterNoneSSL (default value - let ICAP or URL rewritor decide).
Yep, looks that you are right here, something like that required...
C) Squid notifies the URL rewritor and ICAP server about the result of
the SSL handshake. This is to optimise the filters and not do things twice.
Web servers do no like probes and may temporarily block sites that use
Squid
if they receive too many probes, so the least number of probes the better.
I.e. the line sent to the URL redirector is extended with a new flag
like "SSLhandshake=(verified|noSSL)". This should not break existing URL
redirectors since it already has the variable length urlgroup and most URL
redirectors will consider the new flag part of the urlgroup.
Probably a few URL redirectors need a minor modification.
For ICAP Squid could send a new header called X-Squid-SSLhandshakeResult.
D) squid.conf.documented, wiki and other documentation is updated that
'sslproxy_flags DONT_VERIFY_PEER' and 'sslproxy_cert_error allow all' are
unsafe and not recommended.
E) the option 'squid-uses-ssl-bump' is introduced to ufdbGuard. If set to
'yes' it will not verify the use of proper SSL certificates.
If Squid can send the new flag SSLhandshake (URL redirector) or
X-Squid-SSLhandshakeResult (ICAP server), the URL redirector and ICAP
servers can be optimised further.
If I am understanding well you are proposing something like the following:
- web client send CONNECT request to squid
- squid reads the CONNECT request and start SSL handshake to the HTTP
server
issue: one does not know upfront is a server has SSL or not.
Case 1: The server is an SSL server
1a) The squid-to-server connection fails with an SSL error (and
maybe the connection dropped, if the error can not be ignored).
depends on the SSL error. If the handshake fails the server endpoint
probabley has no SSL.
1b) Squid initiates an SSL handshake with the client and wait the
first GET (or other request, tunnelled through client-to-squid SSL
handshake)
issue: we know the server has SSL but do not know if it has SSL+HTTP.
it might be SSL+SMTP or SSL+anything
1c) Read the GET request from client and send it to the ICAP server
WITH the "X-Squid-SSLhandshakeResult" header.
Here is an interesting phase. Reading the data from the client
gives us a clue if the CONNECT is for SSL+HTTP.
Note that a server can send data before the client sends data.
If there is a GET/HEAD/POST we assume SSL+HTTP and the filter
can be asked for a decision.
If there is no "GET/HEAD/POST" the CONNECT is not to and SSL+HTTP
endpoint and also the filter should decide on what to do.
1d) Squid send the error page to the web client. Or any possible
error/deny page from ICAP server. Or just ignore the SSL error (eg an
error certificate expired) and continue as normal.
sslBump takes over the certificate checking for a community of users.
IMHO Squid may *never* allow unsafe connections. One should
be extremely careful here. I am in favor of modifying
squid.conf.documented to suggest a Squid admin to publish to all
users which sites are not checked for having valid certificates.
Case 2) The server is not an SSL server:
2a) Squid does not initiate SSL handshake with the client, and allow
CONNECT request continue without ssl bump.
Here the filter remains necessary. In another thread there was
a slight favor for implementing a filter pipe in tunnel mode.
Am I correct? Is this what you need?
In an other thread I wrote this:
I think Squid should do the following in the sslBump handler:
- Open socket. If error, close socket to the browser.
- *possibly*: go to the filters indicating the start of a CONNECT, a filter may
decide to BLOCK just based on the endpoint address.
- Initiate SSL/TLS handshake, if error, signal filters (preferably indicating
there is no SSL/TLS)
If the filter says "PASS", reopen a socket to have a clean tunnel
- If the SSL/TLS handshake is ok, do the certificate checking. If error, send
an erroneous certificate to the browser to give the end user a good idea of
what is going on.
- Verify that the server speaks SSL+HTTP, if not signal filters (preferably
indicating there is SSL/TLS but no HTTP)
- If the endpoint speaks SSL+HTTP, go to the filters, indicating a succesful
CONNECT to an SSL+HTTP endpoint.
The implementation of the second step is a trade off between a delay of the
roundtrip to the filter and preventing unnecessary SSL handshakes for blocked
endpoints.
I do not know much about Squid internals, so maybe the suggested logic needs to
be changed a little.
Marcus