How to set the Host header in JAX-RS / Apache CXF - ssh

I am trying to access a service over HTTPS but due to restrictive network settings I am trying to make the request through an ssh tunnel.
I create the tunnel with a command like:
ssh -L 9443:my-service.com:443 sdt-jump-server
The service is only available via HTTPS, its hosted with a self-signed certificate, and it is behind a load-balancer that uses either the hostname or an explicit Host header to route incoming requests to the appropriate backend service.
I am able to invoke the endpoint from my local system using curl like
curl -k -H 'Host: my-service.com' https://localhost:9443/path
However, when I try to use the CXF 3.1.4 implementation of JAX-RS to make the very same request, I can't seem to make it work. I configured a hostnameVerifier to allow the connection, downloaded the server's certificate, and added it to my truststore. Now I can connect, but it seemed like the load-balancer was not honoring the Host header that I'm trying to set.
I was lost for a bit until I set -Djavax.net.debug and saw that the Host header being passed was actually localhost and not the value I set. How to make CXF honor the Host header I'm setting instead of using the value from the URL of the WebTarget?!

CXF uses HttpUrlConnection, so you need to set a system property programmatically
System.setProperty("sun.net.http.allowRestrictedHeaders", "true")
or at startup:
-Dsun.net.http.allowRestrictedHeaders=true
See also How to overwrite http-header "Host" in a HttpURLConnection?

Related

Kubernetes/Ingress/TLS - block access with IP Address in URL

A pod is accessible via nginx-ingress and https://FQDN. That works well with the configured public certificates. But if someone uses https://IP_ADDRESS - he will get a certificate error because of the default "Kubernetes Fake Certificate". Is it possible to block access completely using the IP_ADDRESS url?
I think you would first need the TLS handshake to complete, before Nginx could deny the access.
On the other hand, HAproxy may be able to close the connection while checking the ServerName. Say setting some ACL in your https frontend, routing applications to their backends. Though I'm not sure this would be doable unless mounting a custom HAproxy configuration template into your ingress controller.

icCube XMLA requests in SSL (HTTPS)

SSL is enabled in iccube.xml using a self-signed certificate. As describe in the icCube documentation, 8443 is assigned to the sslPortNumber variable, the certificate location is assigned to sslKeyStorePath and the right password is specified for sslKeyStorePassword. The web administration application and gvi requests work fine when using 8443 as the port in the URL.
Unfortunately, sending XMLA requests in SSL using the same port (8443) does not work. What's wrong with the configuration file? Is there another section to fill out in the configuration file that is specific to XMLA? Is there a special way to build the calling URL?
Thank you

WL-Proxy-Client-Cert header not sent

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.

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.

HTTPS Web(only)Proxy

I just read over node-tls-proxy (http://code.google.com/p/node-tls-proxy/), a https proxy. I like the idea of it, but I'm not getting why this proxy needs a local http server (see the local-proxy.js script).
So I was wondering if this is necessary?
My idea of the proxy was actually like this: Client -> HTTPS Connection to trusted Server/Proxy -> Internets
In this case network sniffing between the Client and the Server wouldn't (hardly) be possible because it would be ssl encrypted.
Thanks,
Seb
If I get the idea correctly, the goal is to set up a "remote" proxy in a location that one trusts to be secure. Your client shall only communicate with this remote proxy using TLS, the remote proxy is then allowed to do the actual (no longer encrypted) HTTP requests.
What you do on the client side now is this: you configure the "local" proxy in your browser. Since you type "http://..." in your browser even when using the proxy, your browser will initiate an unencrypted HTTP connection to the local proxy first. Then the local proxy will open an encrypted TLS connection to the remote proxy and forward your request over a secured channel.
This means you need the local proxy for the purpose of "transforming" HTTP into HTTPS requests because your browser will dutifully only use HTTP when asked to make an actual HTTP request.