Apache 2.4.37 with openssl 1.1.1: cannot perform post-handshake authentication - apache

I updated apache to last version 2.4.37 and openssl to 1.1.1 and now, when client authenticates, I get this error only with Firefox 63, but not in Chrome:
[ssl:error] AH: verify client post handshake, referer: https://******/login
[ssl:error] AH10158: cannot perform post-handshake authentication, referer: https://******/login
[ssl:error]SSL Library Error: error:14268117:SSL routines:SSL_verify_client_post_handshake:extension not received
I used wireshark to try to find the problem, and I apreciate Firefox uses TLS 1.3, while Chrome uses TLS 1.2. In fact, if I set TLS max version in FF to TLS 1.2, it works fine.
I would like to get TLS 1.3 compatibility or, if it is not yet possible, to force, in my Apache configuration, the client always uses TLS 1.2, but I don't get it :(
This is my apache vhost config file:
[...]
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
SSLCertificateChainFile /etc/apache2/ssl/intermediate.crt
SSLCACertificateFile /etc/apache2/ssl/ca.pem
SSLVerifyDepth 3
SSLProtocol TLSv1.2
SSLHonorCipherOrder on
<Directory /var/www/html/>
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Order deny,allow
Allow from 10.55.12.0/24
Deny from all
</Directory>
<Files "login-ssl.php">
SSLVerifyClient optional
SSLOptions +StdEnvVars +StrictRequire
</Files>
[...]
Can someone help me, please?
Thanks.
Edited
I found the solution. SSLProtocol directive should be in /etc/apache2/mods-enabled/ssl.conf.

The problem is that Firefox doesn't support TLS 1.3 post-handshake authentication. I've reported this issue to Firefox at https://bugzilla.mozilla.org/show_bug.cgi?id=1511989
I'm not suggesting a workaround or fix here; I'm merely telling others who come across this page (as it is high up for this error message in the search results) what the situation is and where to find the latest information as Firefox works to resolve this issue.

In case this helps other, for my reverse proxy test configuration with Apache HTTP 2.4.41 on Windows, I wanted to protect only the balancer-manager URI with client certificate authentication, that I had generated using OpenSSL with CA certs, server certs signed by CA and client cert signed by CA, imported the P12 in my browser.
For my other back end URLs (Spring Boot with AJP enabled and running same application on 2 different set of ports to test balancing via Apache HTTP) that were being proxied, configuration was to do not perform any client certificate authentication.
Accessing https://myhostname.com was working and hitting my back end
via balancer, returning the expected response.
Accessing https://myhostname.com/balancer-manager was expected to
prompt me for selecting client certificate that I imported earlier,
but gave this error on Chrome 80.0 ( and did not work for other
browsers as well).
Forbidden You don't have permission to access this resource.Reason:
Cannot perform Post-Handshake Authentication.
In Apache error log, it showed:
SSL Library Error: error:14268117:SSL
routines:SSL_verify_client_post_handshake:extension not received
In Apache access log, it showed:
GET /balancer-manager HTTP/1.1" 403 199
Non working configuration for Virtual host config in httpd.conf looked like:
<VirtualHost *:443>
ServerName myhostname.com
ServerAlias myhostname.com
SSLEngine on
SSLCipherSuite ALL:!EXP:!eNULL:!aNULL:!MD5:-LOW:-RC4:-SSLv2:+HIGH:+MEDIUM
#no certificate authentication required except balancer manager
SSLVerifyClient none
SSLVerifyDepth 5
SSLProtocol all -SSLv3
SSLCertificateFile "path/to/server/certificate"
SSLCertificateKeyFile "path/to/server/key"
SSLCACertificateFile "path/to/CA/certificate"
<Location "/balancer-manager">
SSLVerifyClient require
SetHandler balancer-manager
Require host myhostname.com
</Location>
<Proxy balancer://cluster>
BalancerMember ajp://localhost:9090/ loadfactor=25 timeout=1
BalancerMember ajp://localhost:9091/ loadfactor=75 timeout=1
ProxySet lbmethod=byrequests
</Proxy>
ProxyPreserveHost off
ProxyRequests Off
ProxyPass / balancer://cluster/ stickysession=JSESSIONID
ProxyPassReverse / balancer://cluster/ stickysession=JSESSIONID
</VirtualHost>
To fix the issue, change SSLProtocol directive to use:
SSLProtocol -all +TLSv1.2
See these links also
Enable TLS in Apache
TLS-1-2
I used TLS 1.2 for tests (TLS 1.1 also worked but recommended to use TLS 1.2 or higher version).
Note:The Apache version 2.4.38 or higher versions support TLS v1.3. You
must upgrade Apache packages before enabled TLS 1.3 in SSL settings.
*

Related

How to hide weak SSL behind a Proxy?

So im having the following Setup:
Weak TLS 1.0 Application <--> DMZ Reverse Proxy <--> The Client
The Apache-Vhost is configured like that:
HTTP:
<VirtualHost x.x.x.x:80>
ServerName weak.application.de
Redirect / https://weak.application.de/
</VirtualHost>
HTTPS:
<VirtualHost x.x.x.x:443>
ServerName weak.application.de:443
SSLEngine on
SSLCipherSuite AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
SSLCompression off
SSLCertificateFile /actual/cert/of/the/application
SSLCertificateKeyFile /actual/key/of/the/application
SSLCertificateChainFile /actual/intermediate_chain/of/the/application
SSLProxyEngine On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ProxyRequests Off
ProxyPass / https://weak.application.de/
ProxyPassReverse / https://weak.application.de/
</VirtualHost>
And is working fine. But i just noticed the following:
When connecting using openssl s_client on the Proxy IP for this Application, i get connected with TLS 1.2, like intended
But when im accessing the same IP with my Browser, the Certificate Details tells me that im Connected using TLS 1.0 which is weak.
Is there a proper Way to hide the weak TLS behind the Proxy? Did i missed out something?
I would like to have something like this:
Weak Application <- TLS 1.0 -> DMZ Reverse Proxy <- TLS 1.2 -> The Client
i am using Apache/2.4.6 on Centos 7.8.
Thanks in advance
Cheers, Tomasz
I just figured out that this was some kind caching/session issue.
The config is correct, and after reloading httpd and using Private-Surfing i was able to connect with the weak server via proxy, but it looks like we are using TLS 1.2.
Since i am sending Requests to the Server using the Proxy IP as Hostname, i additionally had to add the following lines in order to prevent Server Errors:
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
Simply because the Proxy IP is not a CN or SAN in the Certificate of the Weak Server. So there would be a mismatch. When going live, these Options should be removed.
I Hope this helps someone. Correct me if im Wrong.
Bye

LetsEncrypt SSL Error - SSL routines:ssl3_get_record:wrong version number

I've managed to pull down a fresh cert from LetsEncrypt. My VirtualHost config is set up as:
<VirtualHost *:80>
ServerName example.com
Redirect 301 / https://example.com/
</VirtualHost>
<VirtualHost *:443>
Servername example.com
DocumentRoot /var/www/example.com/wav
ErrorLog /var/log/apache2/example.com/www/error.log
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
When trying to verify this with openssl:
openssl s_client -connect example.com -port 443
I get the following:
CONNECTED(00000003)
140229655213824:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 202 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1541086087
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
So, looks like the handshake is okay but the cert isn't being sent.
Worth pointing out that the Apache logs don't report any errors - just the usual - "starting up/shutting down" messages. apache2ctl configtest reports no issues.
So, looks like the handshake is okay but the cert isn't being sent.
The handshake is not ok. The Client has sent the ClientHello to start the handshake but received nothing useful back:
|- ClientHello
---
SSL handshake has read 5 bytes and written 202 bytes
---
|- nothing useful from server
I don't know what it is getting back in the 5 bytes but it does not look like TLS (too short for a TLS message). It might be some server misconfiguration which can not be seen from the part of the config you've shown. It might also be some middlebox (firewall, load balancer...) hurting the connection. It might also be that you don't connect to the expected server (i.e. example.com does not resolve to your actual server).
I recommend that you first check on the server itself (i.e. localhost) and if this works move further away from the server with your checks. You might also do a packet capture and have a look what you'll find in the 5 bytes received by the client.
Just sharing for anyone who ends up here with the same problem.
This is my experience in Ubuntu 20 with Apache
I was editing the default-ssl.conf in SITES-AVAILABLE folder but nothing happened. The above same error was repeating no matter what i did.
I copied the default-ssl.conf from sites-available into SITES-ENABLED folder without the IfModule mod_ssl.c tag and THAT SOLVED THE PROBLEM.
Hope this info helps someone.
Thanks
It seems apache's default *:80 HTTP handler will also listen on 443 for unmatched VirtualHost IPs including loopback.
For example, my machine has a NAT ip 192.168.32.5 and of course the 127.0.0.1 loopback. If my site conf uses <VirtualHost 192.168.32.5:443> then any requests that resolve to 127.0.0.1:443 are actually answered by the default HTTP handler...not HTTPS. Simply setting my hosts entry for the SSL hostname to 192.168.32.5 fixed the issue.
I had the same issue. My example.com.conf file did have HTTPS set up properly, but my 000-default.conf file did not. I seemed to have forgotten to include the SSL certificate and turn on the SSL engine for my 000-default.conf, but after I fixed that, it worked perfectly.
The code I added to 000-default.conf:
SSLEngine On
SSLCertificateFile /etc/ssl/example.com/domain.cert.pem
SSLCertificateKeyFile /etc/ssl/example.com/private.key.pem
I got the same error with you. suggest you test your https connection on local, add your domain name to /etc/hosts, ex:
127.0.0.1 yourdomain.com
in order to keep packet not going out.
then using "links" to test the https connection in local environment, if no problem, then it's caused by ISP firewall issue or setting, I finally found local https connection ok and throw the problem to ISP to solve this problem finally, good luck!
set your file types for ssl as well, this is confirmed working
See the FilesMatch section? If that is missing, you will see this error.
SSLEngine on
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
SSLCertificateFile /etc/letsencrypt/live/mysite.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mysite.net/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLHonorCipherOrder on
SSLProtocol all -SSLv2 -SSLv3
#SSLCipherSuite EECDH+AES:EDH+AES:-SHA1:EECDH+RC4:EDH+RC4:RC4-SHA:EECDH+AES256:EDH+AES256:AES256-SHA:!aNULL:!eNULL:!EXP:!LOW:!MD5
#SSLCipherSuite "AES256-SHA"
SSLCipherSuite HIGH:!aNULL:!MD5
We had the problem that our HTTPS-port was serving unencrypted HTTP.
The reason was that we had two VirtualHosts on the same port and one was configured to use SSLEngine on and the other one not.
Deactivating the unencrypted site fixed the problem. Using SSLEngine on on both VirtualHosts would also fix it.
Also, we needed a proper service restart to get out of that problem. A reload had not fixed the problem, although the config was correct at that time.

Apache reverse proxy and Wicket CsrfPreventionRequestCycleListener

Since integrating CsrfPreventionRequestCycleListener into our Apache Wicket (7.6.0) application, we have a problem operating the application behind an Apache reverse proxy.
Our configuration terminates SSL at Apache, and the reverse proxy passes the requests via http to our Wildfly 10 application server. This allows us to offload TLS/SSL among other things.
But since adding the CsrfPreventionRequestCycleListener, we are seeing the following in the server.log file and connections are aborted:
[org.apache.wicket.protocol.http.CsrfPreventionRequestCycleListener]
(default task-12) Possible CSRF attack, request URL:
http://example.com/example/portal/wicket/page,
Origin: https://example.com, action: aborted with error
400 Origin does not correspond to request
The problematic Apache config:
<VirtualHost example.com:443>
ServerName example.com
LogLevel debug
SSLEngine On
SSLCertificateFile /var/example/example.com/signed.crt
SSLCertificateKeyFile /var/example/example.com/domain.key
SSLCACertificateFile /var/example/example.com/intermediate.pem
SSLProtocol +TLSv1.2 +TLSv1.1 +TLSv1
SSLOpenSSLConfCmd DHParameters "/usr/local/apache2/1024dhparams.pem"
SSLProxyEngine on
ProxyPass / http://localhost:8390/ timeout=600
ProxyPassReverse / http://localhost:8390/ timeout=600
ProxyPreserveHost On
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"
Header edit Location ^http(\:\/\/.*)$ https$1
We found a solution using http2 but would prefer one without http2 (for reasons, see in https://http2.pro/doc/Apache).
The working Apache configuration using http2
<VirtualHost example.com:443>
ServerName example.com
LogLevel debug
SSLEngine On
SSLCertificateFile /var/example/example.com/signed.crt
SSLCertificateKeyFile /var/example/example.com/domain.key
SSLCACertificateFile /var/example/example.com/intermediate.pem
SSLProtocol +TLSv1.2 +TLSv1.1 +TLSv1
SSLOpenSSLConfCmd DHParameters "/usr/local/apache2/1024dhparams.pem"
SSLProxyEngine On
ProxyPreserveHost On
# Settings for http2 communication
Protocols h2 http/1.1
ProxyPass / https://localhost:8754/ timeout=600
ProxyPassReverse / https://localhost:8754/ timeout=600
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"
# Header edit Location ^http(\:\/\/.*)$ https$1
</VirtualHost>
Can anyone help us create a valid apache reverse proxy configuration that works with the CsrfPreventionRequestCycleListener without the http2 module?
I think I had a similar issue here and solved it just now. I think you might have solved your issue by now but maybe anyone else is falling over this topic.
You might want to look into a network dump to verify the problem. For me, apache sent requests to the locally running service (your case to http://localhost:8754) while some request headers were still referring the public name https://example.com. This was detected as a security risk and the connection refused by the underlying service.
I made sure, that mod_headers was enabled in apache and added the line
RequestHeader edit Referer "https://example.com" "http://localhost:8754"
After that no more references to anything related to example.com was in my tcp dumps and the connection was opened successfully.
You might need to adopt according to your setup (maybe you need multiple headers corrected or something similar). I cannot try it out at the moment.

Apache 2.4 SSL Config

I've got a question regarding ssl config for apache 2.4. I got the following ssl settings for my vhost. There are more than 1 Directory but the config is mostly the same, only IPs are different. If I active the the three commented lines the apache should check the requests against the cert and not just pass the request through, correct? I assume the apache breakts the encryption for all requests from the internet and re-encrypts again to pass the request on. Am I right? Is there a way to not break the encryption and just delegate the cert checks to the next system?
RequestHeader set ClientProtocol HTTPS
SSLEngine On
SSLProtocol ALL -SSLv2 -SSLv3
SSLProxyEngine On
SSLProxyProtocol ALL -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:HIGH:!MD5:!aNULL:!EDH
SSLCertificateFile /path/to/file.crt
SSLCertificateKeyFile /path/to/file.key
<Directory /folder-name>
#SSLVerifyClient optional_no_ca
#SSLVerifyDepth 1
#SSLOptions +OptRenegotiate +ExportCertData
ProxyPass https://10.20.30.40:8443/
ProxyPassReverse https://10.20.30.40:8443/
</Directory>
Thanks for your help guys and regards. Sebastian
Yes, this Apache acting as a proxy terminates SSL. It then makes or reuses a pooled SSL connection to the backend.
There's no way to truly let the backend think it's handshaking with the client unless it accessed apache as a forward proxy using the mod_proxy_connect module.
Some application servers accept the body of the client certificate in a proprietary header, making that identity available in the backend server. But they are not actually authenticating it in the handshake like the proxy/apache has done.

Apache ProxyPass - Error during SSL Handshake with remote server

Im using proxy pass to redirect http to https backend server (tomcat)
Error im getting is : Error during SSL Handshake with remote server
My Configuration :
<VirtualHost *:80>
ServerName mypersonal.server.com
ProxyRequests Off
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyPass /publisher https://localhost:9443/publisher
ProxyPassReverse /publisher https://localhost:9443/publisher
</VirtualHost>
I'm trying to find a way to overcome the verification of SSL, but the following commands appears in grey in my config
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
Im using Server version: Apache/2.4.6 (CentOS)
Appreciate your assistance
Late to the party here, but somebody might find this useful.
Check your SSLProxyProtocol directive. If, for security purposes, you have disabled the protocol that your backend is using, then the handshake will fail.
For example, I was using SSLProxyProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2 but had to relax it to SSLProxyProtocol all -SSLv2 -SSLv3 -TLSv1 because my backend is still using TLS v1.1.
EDIT in 2023: I just saw this was upvoted recently. If you're still having problems, also check your values for SSLProxyCipherSuite (see apache docs and values recommended by Mozilla)