[squid-users] LEGACY_SERVER_CONNECT, ALLOW_UNSAFE_LEGACY_RENEGOTIATION does not work - SSL bump, OpenSSL 3

Alex Rousskov rousskov at measurement-factory.com
Wed Dec 28 17:27:43 UTC 2022


Hi Amish,

     TLS options are used on _both_ sides, in various cases, but there 
are still too many unknowns, and I cannot quickly answer all of your 
questions at once. Sorry. I can only guide you one step at a time.

* If you are sure that SSL_CTX_set_options() is not called when talking 
to the origin server in your setup, then there is no need to hard-code 
those options. Instead, we need to figure out why Squid does not call 
SSL_CTX_set_options(). The best next step is to configure your Squid 
with the following ssl_bump rules and check whether 
SSL_CTX_set_options() is called for the Squid-server connection in that 
case. Sharing access.log records to double check that the origin server 
was contacted may be a good idea.

     ssl_bump stare all
     ssl_bump bump all

* If you are not sure whether SSL_CTX_set_options() is called when 
talking to the origin server in your setup, then hard-coding those 
options may still be the best next step. If it fixes the problem, then 
we will be able to resolve a few variables without the test in the first 
bullet.


HTH,

Alex.


On 12/28/22 11:49, Amish wrote:
> Hi Alex,
> 
> On 28/12/22 21:31, Alex Rousskov wrote:
>> Hi Amish,
>>
>>     Squid parsing code is tricky. tls_outgoing_options parsing code is 
>> triply so. Even its authors misinterpret it!
>>
>> I assume you have removed multiple tls_outgoing_options directives 
>> from your configuration before testing. If you have not, please merge 
>> those directives into one and retest. You should still see multiple 
>> parsing paths, in part, due to (unfortunate) Security::PeerOptions 
>> implementation and, in part, due to Squid parsing default options 
>> before Squid parses your actual configuration files.
>>
> Yes I had combined all tls_outgoing_options in to a single directive 
> (but in multiple lines ending with a backslash \). It can be seen in the 
> grep command in my previous email.
> 
> But wait, I have found something.
> 
> And I have a doubt that parsedOptions work only for client to squid side 
> of the connection and does not work for squid to server side of the 
> connection.
> 
> What I did is changed my "http(s)_port" directives to include 
> options=0x4. These directives control options for the client to squid 
> side of TLS connection.
> 
> $ grep 'ssl-bump' /etc/squid/squid.conf
> http_port 8080 ssl-bump generate-host-certificates=on 
> tls-cert=/etc/squid/ssl_cert/squid.pem 
> tls-dh=/etc/squid/ssl_cert/dhparam.pem options=0x4
> https_port 8081 intercept ssl-bump generate-host-certificates=on 
> tls-cert=/etc/squid/ssl_cert/squid.pem 
> tls-dh=/etc/squid/ssl_cert/dhparam.pem options=0x4
> 
> Now lets reproduce the issue:
> $ curl --no-progress-meter -kx 127.0.0.1:8080 https://www.jio.com |grep 
> 'TLS\|SSL'
> <pre>[No Error] (TLS code: 
> SQUID_TLS_ERR_CONNECT+TLS_LIB_ERR=A000152+TLS_IO_ERR=1)</pre>
> <p>Failed to establish a secure connection: error:0A000152:SSL 
> routines::unsafe legacy renegotiation disabled</p>
> 
> Lets see what cache.log has to say:
> 
> $ tail -f /var/log/squid/cache.log  |grep -i 'openssl\|parsed'
> 2022/12/28 21:52:56.532 kid1| 83,5| PeerOptions.cc(447) parseOptions: 
> INFO: TLS parsedOptions(1)=4
> 2022/12/28 21:52:56.532 kid1| 83,5| PeerOptions.cc(643) 
> updateContextOptions: set OpenSSL options for context=0x559075043e30, 
> parsedOptions=4
> 2022/12/28 21:52:56.532 kid1| 83,5| PeerOptions.cc(645) 
> updateContextOptions: get OpenSSL options for context=0x559075043e30, 
> getOptions=1179652
> 
> Bingo!! As we can see, parsedOptions is now set to 4!
> 
> And it is also confirmed by ssl_get_options() - 1179652  = 0x120004 (4 
> means the option is accepted by OpenSSL too)
> 
> But this also means that updateContextOptions() is called ONLY FOR 
> client to squid side (curl to squid) and it is not called for squid to 
> server (jio.com in this case) side.
> 
> The reason being that we do not see updateContextOptions() being called 
> twice for a request. But only once. And that is why request still fails 
> with the negotiation error.
> 
> So where exactly is the call for squid to server side being made?
> 
>> If merging directives does not deliver custom options to 
>> SSL_CTX_set_options(), then let's attack this from the other end: 
>> Supply the right options to each SSL_CTX_set_options() call:
>>
>>     const Security::ParsedOptions forcedParsedOptions = 0x4 | 0x40000;
>>     SSL_CTX_set_options(ctx.get(), forcedParsedOptions);
>>
>> Does the above temporary hack fix the problem in your test?
> 
> 
> I will try this tomorrow (its late night here).
> 
> But I think I will have to set this somewhere else and NOT in 
> PeerOptions.cc. Because above code appears to be for client to squid side.
> 
> And I need to add forcedParsedOptions to the code which connects squid 
> to server. But where?
> 
> Thank you,
> 
> Amish.
> 
> 
>> Thank you,
>>
>> Alex.
>>
>> On 12/28/22 02:32, Amish wrote:
>>> Hi Alex,
>>>
>>> Thanks again for your reply.
>>>
>>> To find answers to your questions, I added few debugs() lines to 
>>> PeerOptions.cc.
>>>
>>> The diff file (patch) is attached.
>>>
>>> It prints parsedOptions and options retrieved from SSL context and 
>>> session objects at several stages.
>>>
>>> Here is tls_outgoing_options setting:
>>>
>>> $ grep tls_outgoing_options /etc/squid/squid.conf
>>> tls_outgoing_options \
>>>      cafile=/etc/ssl/cert.pem \
>>> cipher=ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS \
>>>      options=0x4
>>>
>>>
>>> Here is what squid logs on reload i.e. on parsing the squid.conf
>>>
>>> $ systemctl reload squid
>>> $ tail -f /var/log/squid/cache.log  |grep -i 'openssl\|parsed'
>>> 2022/12/28 12:19:30.596 kid1| 83,5| PeerOptions.cc(547) parseOptions: 
>>> INFO: TLS parsedOptions(3)=0
>>> 2022/12/28 12:19:30.598 kid1| 83,5| PeerOptions.cc(547) parseOptions: 
>>> INFO: TLS parsedOptions(3)=0
>>> 2022/12/28 12:19:30.723 kid1| 83,5| PeerOptions.cc(547) parseOptions: 
>>> INFO: TLS parsedOptions(3)=4
>>> 2022/12/28 12:19:30.729 kid1| 83,5| PeerOptions.cc(547) parseOptions: 
>>> INFO: TLS parsedOptions(3)=0
>>> 2022/12/28 12:19:30.729 kid1| 83,5| PeerOptions.cc(547) parseOptions: 
>>> INFO: TLS parsedOptions(3)=0
>>> 2022/12/28 12:19:32.147 kid1| 83,5| PeerOptions.cc(447) parseOptions: 
>>> INFO: TLS parsedOptions(1)=0
>>> 2022/12/28 12:19:32.147 kid1| 83,5| PeerOptions.cc(547) parseOptions: 
>>> INFO: TLS parsedOptions(3)=0
>>> 2022/12/28 12:19:33.524 kid1| 83,5| PeerOptions.cc(447) parseOptions: 
>>> INFO: TLS parsedOptions(1)=0
>>> 2022/12/28 12:19:33.532 kid1| 83,5| PeerOptions.cc(547) parseOptions: 
>>> INFO: TLS parsedOptions(3)=0
>>> 2022/12/28 12:19:33.695 kid1| 83,5| PeerOptions.cc(447) parseOptions: 
>>> INFO: TLS parsedOptions(1)=0
>>> 2022/12/28 12:19:33.695 kid1| 83,5| PeerOptions.cc(643) 
>>> updateContextOptions: set OpenSSL options for context=0x562a5387fe30, 
>>> parsedOptions=0
>>> 2022/12/28 12:19:33.695 kid1| 83,5| PeerOptions.cc(645) 
>>> updateContextOptions: get OpenSSL options for context=0x562a5387fe30, 
>>> getOptions=1179648
>>
>>> 2022/12/28 12:19:33.708 kid1| 83,5| PeerOptions.cc(447) parseOptions: 
>>> INFO: TLS parsedOptions(1)=0
>>> 2022/12/28 12:19:33.708 kid1| 83,5| PeerOptions.cc(643) 
>>> updateContextOptions: set OpenSSL options for context=0x562a53e6e740, 
>>> parsedOptions=0
>>> 2022/12/28 12:19:33.708 kid1| 83,5| PeerOptions.cc(645) 
>>> updateContextOptions: get OpenSSL options for context=0x562a53e6e740, 
>>> getOptions=1179648
>>>
>>> It seems that squid parses the options multiple times and only once 
>>> it gets the value as 4. Rest are parsed as 0.
>>>
>>> The value of 1179648 (0x120000) corresponds to SSL_OP_NO_COMPRESSION 
>>> (0x20000) and SSL_OP_ENABLE_MIDDLEBOX_COMPAT. (0x100000)
>>>
>>>
>>> Now lets reproduce the issue:
>>>
>>> $ curl --no-progress-meter -kx 127.0.0.1:8080 https://www.jio.com 
>>> |grep 'TLS\|SSL'
>>> <pre>[No Error] (TLS code: 
>>> SQUID_TLS_ERR_CONNECT+TLS_LIB_ERR=A000152+TLS_IO_ERR=1)</pre>
>>> <p>Failed to establish a secure connection: error:0A000152:SSL 
>>> routines::unsafe legacy renegotiation disabled</p>
>>>
>>> So, as we can see, we are still not able to access the site.
>>>
>>> Lets see what cache.log has to say.
>>>
>>> $ tail -f /var/log/squid/cache.log  |grep -i 'openssl\|parsed'
>>> 2022/12/28 12:31:09.971 kid1| 83,5| PeerOptions.cc(447) parseOptions: 
>>> INFO: TLS parsedOptions(1)=0
>>> 2022/12/28 12:31:09.971 kid1| 83,5| PeerOptions.cc(643) 
>>> updateContextOptions: set OpenSSL options for context=0x562a53eb14e0, 
>>> parsedOptions=0
>>> 2022/12/28 12:31:09.971 kid1| 83,5| PeerOptions.cc(645) 
>>> updateContextOptions: get OpenSSL options for context=0x562a53eb14e0, 
>>> getOptions=1179648
>>>
>>> Strangely parsedOptions was zero and not 4!
>>>
>>> Now we can answer your questions as below.
>>>
>>>
>>> On 27/12/22 21:52, Alex Rousskov wrote:
>>>> On 12/27/22 10:42, Amish wrote:
>>>>> On 26/12/22 21:31, Alex Rousskov wrote:
>>>>>> tls_outgoing_options options=0x4,0x40000
>>>>
>>>>> With numeric hex values, I do not see the ERROR on stderr.
>>>>
>>>>> But it still does not seem to be working as expected. Squid still 
>>>>> does not open the page and gives same legacy negotiation error.
>>>>
>>>> There are still many unknowns (from my point of view), including:
>>>>
>>>> 1. Does OpenSSL accept the above options? You ask that question below.
>>>
>>> Google search shows some projects using OpenSSL v3 where there is 
>>> mention to use above option when a similar error occurred to them.
>>>
>>> But in our case, its clear that squid does not pass value 4 to SSL 
>>> context, hence we do not know yet if OpenSSL accepts above options.
>>>
>>>
>>>> 2. Does Squid indeed stare at the server, as expected?
>>>> 3. Does Squid apply the accepted options when staring at the server?
>>>
>>> A comment for parseOptions() in PeerOptions.cc states this:
>>>
>>> /**
>>>   * Pre-parse TLS options= parameter to be applied when the TLS 
>>> objects created.
>>>   * Options must not used in the case of peek or stare bump mode.
>>>   */
>>> void Security::PeerOptions::parseOptions()
>>>
>>> So it appears that TLS options is NOT used for peek as well as stare. 
>>> But why? I am not sure.
>>>
>>> How do I make squid use it for 'stare' atleast?
>>>
>>>
>>>> 4. Why does TLS negotiation fail despite those options applied,
>>>>    especially since it succeeds with using openssl s_client
>>>
>>> It possibly fails because options are not applied by squid.
>>>
>>> So, where do I check next on why parsedOptions is still set to 0 and 
>>> why its not used for 'stare'?
>>>
>>> Thanks and regards,
>>>
>>> Amish.
>>>
> _______________________________________________
> squid-users mailing list
> squid-users at lists.squid-cache.org
> http://lists.squid-cache.org/listinfo/squid-users



More information about the squid-users mailing list