WL-Proxy-Client-Cert header not sent - apache

I m using Oracle HTTP Server as reverse proxy for WebLogic. I have set up SSL on both the proxy and the server with client certificate authentication. It works and the clients get authenticated by OHS, but i need to pass client certificate information to WebLogic so i can look at this certificate in my servlet. Documentation says that the proxy can forward client certificate within "WL-Proxy-Client-Cert" http header to the WebLogic server.
However, i can't get this to work. Within my servlet i tried both request.getHeader() and request.getAttribute() and getting null. I looked at both headers and attributes of the request objects and don't see anything like WL-Proxy-Client-Cert. In fact i don't see any headers starting with WL, only couple of headers starting with X-WebLogic, none of which has the certificate.
I did enable "Client Cert Proxy Enabled" option in Administration Console as described in the docs. Also i know that clients get authenticated since i see the certificate requested by the browser, after which i can successfully access the site.
Am i missing something?

I have finally got an answer from Oracle support on this. The problem was that i had to add one SSL directive to my virtual host configuration:
SSLOptions +ExportCertData
It goes under "IfModule ossl_module", right next to "SSLVerifyClient require" directive that specifies 2-way authentication for the proxy.
Note that after this, in the servlet, the certificate will be present in the usual "javax.servlet.request.X509Certificate" attribute, as if the server was doing client certificate authentication itself (no extra headers are received).
Also, note that you can have the server use 1-way SSL, if you feel secure with authentication done by the proxy, and you will still receive the certificate in the attribute in your servlet (in this case you should probably add a filter as they recommend to ensure the requests come from the proxy only). I have a feeling it will work even if the server port is regular http, though i haven't tested it yet.

Related

How to fix "We're sorry HTTPS required" in Keycloak with reverse proxy?

When I try to hit Keycloak 6 behind an Azure gateway (reverse proxy) using SSL/HTTPS I get a "We're Sorry HTTPS Required" error in my browser. In the Keycloak log I see
[org.keycloak.events] (default task-2) type=LOGIN_ERROR, realmId=master, clientId=null, userId=null, ipAddress=x.x.x.x, error=ssl_required
I'm assuming I misconfigured something along the way but I can't figure out what it is.
I followed these instructions to set up SSL in Keycloak 6 behind a reverse proxy:
https://www.keycloak.org/docs/latest/server_installation/index.html#setting-up-https-ssl
I did NOT do any certificate creating/importing because the guide says "If you are not using a reverse proxy or load balancer to handle HTTPS traffic for you, you’ll need to enable HTTPS for the Keycloak server. This involves
Obtaining or generating a keystore that contains the private key and certificate for SSL/HTTP traffic
Configuring the Keycloak server to use this keypair and certificate."
My question is, do I need to do the certificate creating/importing anyway, even if I'm behind the reverse proxy? If not, any other ideas?
Please note: I am running the Keycloak stand alone server, not using it as an overlay on any other server container like Wildfly
Found the answer on this thread.
why is keycloak removing the SSL in the redirect uri?
Bottom line, you don't need to generate/install the cert AND there is an undocumented attribute
proxy-address-forwarding="true"

HAProxy dynamic SSL configuration for multiple domains

I have something like 100 similar websites in two VPS. I would like to use HAProxy to switch traffic dynamically but at the same time I would like to add an SSL certificate.
I want to use add a variable to call the specific certificate for each website.
For example:
frontend web-https
bind 0.0.0.0:443 ssl crt /etc/ssl/certs/{{domain}}.pem
reqadd X-Forwarded-Proto:\ https
rspadd Strict-Transport-Security:\ max-age=31536000
default_backend website
I'd like also check if the SSL certificate is really available and in case it is not available then switch to HTTP with a redirect.
Is this possibile with HAProxy?
This can be done, but TLS (SSL) does not allow you to do it the way you envision.
First, HAProxy allows you to specify a default certificate and a directory for additonal certificates.
From the documentation for the crt keyword
If a directory name is used instead of a PEM file, then all files found in
that directory will be loaded in alphabetic order unless their name ends with
'.issuer', '.ocsp' or '.sctl' (reserved extensions). This directive may be
specified multiple times in order to load certificates from multiple files or
directories. The certificates will be presented to clients who provide a
valid TLS Server Name Indication field matching one of their CN or alt
subjects. Wildcards are supported, where a wildcard character '*' is used
instead of the first hostname component (eg: *.example.org matches
www.example.org but not www.sub.example.org).
If no SNI is provided by the client or if the SSL library does not support
TLS extensions, or if the client provides an SNI hostname which does not
match any certificate, then the first loaded certificate will be presented.
This means that when loading certificates from a directory, it is highly
recommended to load the default one first as a file or to ensure that it will
always be the first one in the directory.
So, all you need is a directory containing each cert/chain/key in a pem file, and a modification to your configuration like this:
bind 0.0.0.0:443 ssl crt /etc/haproxy/my-default.pem crt /etc/haproxy/my-cert-directory
Note you should also add no-sslv3.
I want to use add a variable to call te specific certificate for each website
As noted in the documentation, if the browser sends Server Name Identification (SNI), then HAProxy will automatically negotiate with the browser using the appropriate certificate.
So configurable cert selection isn't necessary, but more importantly, it isn't possible. SSL/TLS doesn't work that way (anywhere). Until the browser successfully negotiates the secure channel, you don't know what web site the browser will be asking for, because the browser hasn't yet sent the request.
If the browser doesn't speak SNI -- a concern that should be almost entirely irrelevant any more -- or if there is no cert on file that matches the hostname presented in the SNI -- then the default certificate is used for negotiation with the browser.
I'd like also check if the ssl is real available and in case is not available switch to http with a redirect
This is also not possible. Remember, encryption is negotiated first, and only then is the HTTP request sent by the browser.
So, a user will never see your redirect unless they bypass the browser's security warning -- which they must necessarily see, because the hostname in the default certificate won't match the hostname the browser expects to see in the cert.
At this point, there's little point in forcing them back to http, because by bypassing the browser security warning, they have established a connection that is -- simultaneously -- untrusted yet still encrypted. The connection is technically secure but the user has a red × in the address bar because the browser correctly believes that the certificate is invalid (due to the hostname mismatch). But on the user's insistence at bypassing the warning, the browser still uses the invalid certificate to establish the secure channel.
If you really want to redirect even after all of this, you'll need to take a look at the layer 5 fetches. You'll need to verify that the Host header matches the SNI or the default cert, and if your certs are wildcards, you'll need to accommodate that too, but this will still only happen after the user bypasses the security warning.
Imagine if things were so simple that a web server without a valid certificate could hijack traffic by simply redirecting it without the browser requiring the server's certificate being valid (or deliberate action by the user to bypass the warning) and it should become apparent why your original idea not only will not work, but in fact should not work.
Note also that the certificates loaded from the configured directory are all loaded at startup. If you need HAProxy to discover new ones or discard old ones, you need a hot restart of HAProxy (usually sudo service haproxy reload).

403 - Forbidden: Access is denied, certificates issue in IIS7

I have installed a renewed SSL certificate on my web server running IIS7.
After installation, I applied website binding to port 443.
My application uses client certificates too, so I have changed the SSL setting to Require 'client certificate'.
Both client and SSL server certificates are valid but still I am not able to access my application. The error I get is:
403 - Forbidden: Access is denied.
I have enabled client certificate mapping in IIS role settings also but still not getting rid of this 403 error.
I guess client certificate is not able to handshake with server certificate. Please help!
In certificate Store verified all server certificate and client cert with its authority hierarchy are available.
also cross check below settings
Application Authentication: Anonymous
Application SSL Setting: Require SSL/ Accept
ApplicationHost.config: enabled OnetoOneMapping under iisClientCertificateMappingAuthentication also added base64 certificate mapped with service accounts
Also based on my past experience we need to ensure we have SChannel registry setting as mentioned in below post.
https://support.microsoft.com/en-us/kb/2464556
Simplest workaround just discovered this today. In IIS for your application, Go to Edit Bindings and change your port number. 443 to 4431 or 44301. Any variation you want. In your client computer, type in the new URL using new port number and you will establish a fresh connection to application. Make sure you SSL Settings for IIS Application is set to "Accept" instead of "Require". This means you can click "Cancel" when the pop up asks you to select a certificate you can simply hit "Cancel" and still hit the site. No 403 Error.
Do not spend hours trying to mess with your certificate store, just simply change the port on IIS Server and you'll be fine.

Putting X509 Certificate in HTTP Request

I'm using Spring Security for X.509 preauthentication.
To make sure the client sends its certificate per HTTP request, is it necessary to:
Modify pom.xml to set <wantClientAuth> and <needClientAuth> to true
Set Apache's SSLVerifyClient to require reference
Based on reading, the web server must tell the client-side to sends its certificate in order for the client to actually send it. I'm confused if Spring Security AND Apache configuration is required to achieve this.
Spring Security configuration has nothing to do with whether the client sends a certificate or not. That's decided at the SSL protocol level and hence by the negotiation between the client and the server. Your question is a bit unclear in that it refers to a maven pom and an Apache configuration without explaining how your system is set up. Are you running the maven Jetty plugin with an Apache server in front?
Spring Security's X.509 authentication won't work if the SSL connection doesn't terminate at the servlet container. So if you have HTTPS between the client and Apache, and a non-SSL connection from Apache to the servlet container, then the client certificate won't normally be available.
If you are using an AJP connector, then you can configure Apache to pass the certificate on to the back end using the ExportCertData option. If you aren't, you can still take the exported certificate and pass it as a request header (you'll find examples of this elsewhere on SO). You would also need to customize the Spring Security X.509 code to extract the certificate from the header, rather than the standard java property name which it uses by default.

WCF service using wildcard cert giving a DNS identity error

I have a WCF web service that is setup to use Message based security. The service is using a wildcard certificate for securing the message: *.domain.com
After renewing the SSL cert, the service now throws the following error:
"Identity check failed for outgoing message. The expected DNS identity of the remote endpoint was '*.domain.com' but the remote endpoint provided DNS claim 'domain.com'. ..."
How do I fix this so the service still responds with *.domain.com as the DNS claim?
Unfortunately updating the client configs is not really an option to use the new DNS claim via the DNS identity property.
Thanks,
Mark
This is an bug in WCF. Visit the connect site and upvote if its a blocking issue. http://connect.microsoft.com/wcf/feedback/details/683178/wcf-x509-certificate-validation-only-checks-last-dnsname-in-subject-alternative-name
Turns out the issue was with the SANs list on the Wild Card Cert. The order that the domains were listed were:
*.domain.com
domain.com
WCF was basically always resolving to the last item in the SANs list. I did stumble across a few articles where Office Communicator had a similar issue. I'm not sure if this is a WCF bug or not.
My solution was to ask the Certificate Authority to generate me a wildcard cert without the SANs attribute.
The dns setting for the client is simply used to verify the certificates authenticity, so you can simply set the dns of the client to "domain.com" instead of "service.domain.com".