Forum Moderators: phranque

Message Too Old, No Replies

SetEnv for SSL PROTOCOL

         

dstiles

10:06 am on Feb 22, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I've been trying to catch the SSL protocol status in an include file. This file includes various tests for baddies, bots etc and works well but I cannot get SSL_PROTOCOL to work. Not sure if it's the wrong variable name or for some other reason I haven't spotted. I have tried all of the lines below but they always trigger regardless of the SSL protocol status. I have also tried <if...> and plain SetEnvIf with the same results.
SetEnvIfExpr " %{SSL_PROTOCOL} =~ /TLSv1\.2/" ssl=ok
SetEnvIfExpr "! %{SSL_PROTOCOL} =~ /TLSv1\.2/" ssl=bad
SetEnvIfExpr " %{HTTP:SSL_PROTOCOL} =~ /TLSv1\.2/" ssl=ok

It's likely I have an incorrect variable name but if so, why do I get a trigger in ALL cases? I would expect there to be no trigger at all.

In PHP I have the following, which gives either the expected response.
if(isset($_SERVER['SSL_PROTOCOL'])) { $ssl=$_SERVER['SSL_PROTOCOL']; } else { $ssl=""; }

Can anyone suggest a reason why the apache version fails, please?

w3dk

1:24 pm on Feb 22, 2021 (gmt 0)

10+ Year Member Top Contributors Of The Month




I have tried all of the lines below but they always trigger regardless of the SSL protocol status.

SetEnvIfExpr " %{SSL_PROTOCOL} =~ /TLSv1\.2/" ssl=ok
SetEnvIfExpr "! %{SSL_PROTOCOL} =~ /TLSv1\.2/" ssl=bad
SetEnvIfExpr " %{HTTP:SSL_PROTOCOL} =~ /TLSv1\.2/" ssl=ok



This would seem to be impossible. I would assume you must have a logic error elsewhere?

#1 and #2 are mutually exclusive - they cannot both be true. And #3 can never be true since there is no HTTP request header called "SSL_PROTOCOL" (at least there shouldn't be).

Note that SSL_PROTOCOL is an optional environment(?) variable. If this is not set then the above "%{SSL_PROTOCOL}" will result in an error. To avoid this error use a function instead. eg. regenv('SSL_PROTOCOL').

dstiles

2:41 pm on Feb 22, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Nothing fails in the file except this one test.

By "all the lines below" I meant separately, not together.

I'm aware the var isn't always available but I think that would come into play when testing for the first case: if it matches, it's ok; if not (or does not exist) then ssl is not set.

w3dk

4:31 pm on Feb 22, 2021 (gmt 0)

10+ Year Member Top Contributors Of The Month



By "all the lines below" I meant separately, not together.


Yes, but presumably you are testing the "same type of" request?

The point is that #2 could never match, if #1 also matched a similar request. And #3 could never match.

Strictly speaking you should have some anchors on your regex.

Are you sure there isn't another env var called "SSL" being set on your system?

Just curious why you are setting another env var in Apache when all the logging is presumably handled by PHP anyway?

In PHP I have the following, which gives either the expected response.


What do you mean by "either"?

lucy24

5:46 pm on Feb 22, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I spent some time poring over docs [httpd.apache.org], because SSL_PROTOCOL isn't strictly speaking a header field, which is what SetEnvIf claims to look at.
This module can be configured to provide several items of SSL information as additional environment variables to the SSI and CGI namespace. Except for HTTPS and SSL_TLS_SNI which are always defined, this information is not provided by default for performance reasons.
What are your current SSLOptions settings?
This per default is disabled for performance reasons, because the information extraction step is a rather expensive operation.
Apache must really want to stress this point, since they say it twice on the same page.

phranque

12:01 am on Feb 23, 2021 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



fwiw:
When mod_ssl is built into Apache or at least loaded (under DSO situation) any variables provided by mod_ssl can be used in expressions for the ap_expr Expression Parser. The variables can be referenced using the syntax ``%{varname}''. Starting with version 2.4.18 one can also use the mod_rewrite style syntax ``%{SSL:varname}'' or the function style syntax ``ssl(varname)''.
Example (using mod_headers)

Header set X-SSL-PROTOCOL "expr=%{SSL_PROTOCOL}"
Header set X-SSL-CIPHER "expr=%{SSL:SSL_CIPHER}"


This feature even works without setting the StdEnvVars option of the SSLOptions directive.

source: https://httpd.apache.org/docs/current/mod/mod_ssl.html#expressionparser

what version of apache are you running?

dstiles

11:16 am on Feb 24, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



w3dk:
Strictly speaking you should have some anchors on your regex.
Get it working first, tidy up by stages afterwards.
another env var called "SSL" being set on your system?
Definitely not.
why you are setting another env var in Apache when all the logging is presumably handled by PHP anyway?
This is not for logging. The intention is to use it as part of the access prohibition mechanism. It will incidentally be logged for my own analyser. But as I said above, "Get it working first".
What do you mean by "either"?
A typo - I changed the way I wrote it.

Lucy:
SSL_PROTOCOL isn't strictly speaking a header field
Yes, I read that doc - several times - and came away still confused. I've assumed that is why setenv does not work but neither does an <if>. And in any case, why is the envar always set if the var cannot be tested?
What are your current SSLOptions settings?
+StrictRequire
stress this point
Yes, but how to enable it?

phranque:
Yes, I read that and thought it only applicable to logging and setting headers.
what version of apache are you running?
version 2.4.18

Ok. I wrote the above yesterday. I took Lucy's and phranque's comments and added +StdEndVars to SSLOptions. That works! Thanks, Guys. :)

Unfortunately... Isn't there always? I originally set up all this after discovering, via the php line I gave above, that almost all of the 200-response hits showed TLSv1.2 but many of the 4xx responses showed no SSL at all. I thought Ah! here's another way to reject the baddies - a couple of the bad SSL responses were found to be from previously unknown servers. The idea of adding the test to my trap file was intended to help with this. Except: apart from a few bingbot hits on robots.txt ALL of the hits, 200 and 4xx, now show TLSv1.2 so the idea is now off the cards. :(

Ah, well. Such is life. I can probably disable the StdEnvVars flag again.

w3dk

1:44 pm on Feb 24, 2021 (gmt 0)

10+ Year Member Top Contributors Of The Month



I took Lucy's and phranque's comments and added +StdEndVars to SSLOptions. That works!


Although that doesn't explain why all 3 directives were seemingly successful in the beginning?!

dstiles

4:18 pm on Feb 24, 2021 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



There was obviously something amiss there. I'm guessing some random response from an undefined function, fixed when StdEndVars was enabled?