How to configure jetty to request client certificate for specified resources? - ssl

sslConfig:
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
<Set name="KeyStorePath">../conf/jetty/etc/keystore</Set>
<Set name="KeyStorePassword">secretpass</Set>
<Set name="KeyManagerPassword">test</Set>
<Set name="TrustStorePath">../conf/jetty/etc/truststore</Set>
<Set name="TrustStorePassword">secretpass</Set>
<Set name="EndpointIdentificationAlgorithm"></Set>
<Set name="NeedClientAuth">true</Set>
<Set name="WantClientAuth">true</Set>
</New>
Setting NeedClientAuth to true requires client to provide certificate for all resources. But in my case I want to request certificate only for specified resources.
For example I need to request certificate for /resource1/*
And use just HTTPS for /resource2/*
How can I achieve this?

Not possible, as the SSL/TLS negotiation step occurs way before the request is actually made.
No web server can apply different SSL/TLS rules based on the resource being requested, as the information present in the http request hasn't even been sent yet at the time of the SSL/TLS negotiation.
If this is important, set up 2 different ServerConnectors, on different ports.
ServerConnector with Client Auth - the /resource1/* content is served from here
ServerConnector without Client Auth - all other web resources that don't need the client auth requirement (and doesn't even have the /resource1/* content)

Related

What is the difference between confidentialPort and securePort for Jetty

I am trying to enable Jetty's https port. Jetty is running inside a a Karaf server.
There are different suggested configs found online though:
A version from https://karaf.apache.org/manual/latest/
<!-- Use this connector for many frequently idle connections and for
threadless continuations. -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host">
<Property name="jetty.host" />
</Set>
<Set name="port">
<Property name="jetty.port" default="8181" />
</Set>
<Set name="maxIdleTime">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<Set name="lowResourcesConnections">20000</Set>
<Set name="lowResourcesMaxIdleTime">5000</Set>
</New>
</Arg>
</Call>
Another version from https://www.eclipse.org/jetty/documentation/9.1.5.v20140505/configuring-connectors.html
<New id="tlsHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Arg>
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="secureScheme">https</Set>
<Set name="securePort">
<Property name="jetty.tls.port" default="8443"/>
</Set>
<Set name="outputBufferSize">32768</Set>
<Set name="requestHeaderSize">8192</Set>
<Set name="responseHeaderSize">8192</Set>
<!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
</Call>
-->
</New>
</Arg>
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer"/>
</Arg>
</Call>
I am not getting any of the two approaches to work. Do you have any hints on how to debug this issue and which aproach is actually correct?
For stable (not-EOL) versions of Jetty, such as Jetty 9.4.x ...
The HttpConfiguration.securePort (a configuration present on a ServerConnector) is the logical port that identifies the secure port seen publicly to your clients.
Take this use case.
Browser on Public Internet, requests https://acme.com/foo
Browser looks up DNS for acme.com and gets 210.1.1.1
Browser connects to 210.1.1.1 on port 443
Load Balancer / Proxy is listening on 210.1.1.1:443 and accepts the request.
Load Balancer adds Forwarding header and connects to internal IP 10.2.2.2:8443
Jetty server listening on 10.2.2.2:8443 accepts the connect and processes the request.
At this point, the configuration on the Jetty server has a ServerConnector on port 8443, which has a HttpConfiguration.securePort which is value 443, as that's the public port that the browser sees.

Monitoring Apache Ignite performance by GridGain web console

I am using Apache Ignite 2.8.0. I have enabled HTTPS for REST API by following,
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
<Set name="keyStorePath">C:\\JAYAPRAKASH\\softwares\\ignite\\apache-ignite-2.8.0-bin\\keystore.jks</Set>
<Set name="keyStorePassword">1234567</Set>
<Set name="keyManagerPassword">1234567</Set>
<Set name="trustStorePath">C:\\JAYAPRAKASH\\softwares\\ignite\\apache-ignite-2.8.0-bin\\trust.jks</Set>
<Set name="trustStorePassword">123456</Set>
</New>
Now I am starting my web agent by following configuration,
tokens=adba082b-6b3f-46b5-bcf0-886e5571da4e
node-uri=https://localhost:8080
server-key-store=C:\\JAYAPRAKASH\\softwares\\ignite\\apache-ignite-2.8.0-bin\\keystore.jks
server-key-store-password=1234567
server-trust-store=C:\\JAYAPRAKASH\\softwares\\ignite\\apache-ignite-2.8.0-bin\\trust.jks
server-trust-store-password=123456
it gives the following output in command line,
[2020-05-19T09:24:19,457][INFO ][http-client-18][WebSocketRouter] Successfully completes handshake with server
[2020-05-19T09:24:19,616][ERROR][pool-2-thread-1][ClusterHandler] Failed execute request on node
[url=https://localhost:8080, parameters={cmd=top, attr=true, mtr=false, caches=false}]
javax.net.ssl.SSLHandshakeException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path
to requested target
How do I connect my GriGain Web Console with Ignite cluster when HTTPS is enabled for REST API?
I'm not sure that your Ignite REST is actually HTTPS. You need to configure that separately: Apache Ignite - how to enable HTTPS Rest API
Looks like your certficate is not signed by your trust store? Can you dump details of your trust and keystore?
Follow this Security Guide that covers in details how to enable SSL/TLS for Ignite client, servers and WebConsole: https://www.gridgain.com/docs/tutorials/security/ssl-guide

Setting up ActiveMQ with HTTPS REST

By following https://activemq.apache.org/rest.html, I'm able to push messages via the REST API (e.g. curl -u admin:admin -d "body=message" http://localhost:8161/api/message/TEST?type=queue works, and I can see in the admin console) However, I'd like to be able to use HTTPS. I found https://activemq.apache.org/http-and-https-transports-reference.html and http://troyjsd.blogspot.co.uk/2013/06/activemq-https.html but couldn't manage to make it work. Based on these two outdated/incomplete links:
I added to conf/activemq.xml
Imported self-signed certificate into JDK keystore (per http://troyjsd.blogspot.co.uk/2013/06/activemq-https.html)
Copied xstream and httpclient jars from lib/optional to lib/ (both under ActiveMQ directory, obviously)
So,
How can I set ActiveMQ so that it can be used with a HTTPS REST endpoint?
Assuming I did step 1, how can I test it (a similar curl command example like the above)?
I use ActiveMQ 5.9.1 and Mac OS 10.9.4
Uncomment the following section of conf/jetty.xml.
<!--
Enable this connector if you wish to use https with web console
-->
<!--
<bean id="SecureConnector" class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<property name="port" value="8162" />
<property name="keystore" value="file:${activemq.conf}/broker.ks" />
<property name="password" value="password" />
</bean>
-->
Jetty powers not only the WebConsole, but all HTTP stuff in ActiveMQ.
It should work out of the box for testing, but you probably want to roll your own keystore/certificate for real use.
You could use curl as before on port 8162 with HTTPS given you supply the "insecure" flag -k.
Otherwise, you need to create a trust store in pem format and supply it - see this SO for details. Curl accept the argument --cacert <filename.pem> with your certificate or issuing CA in it.

Apache Solr - Unable to access admin page

On mac snow leopard, I have installed Apache Solr 4.2.0 using brew and triggered the server using the below commands,
Usage: $ solr path/to/config/dir
When I try to access the admin page in browser using below link and the page with SolrCore Initialization failure occurs as below,
http://localhost:8983/solr/admin
collection1: org.apache.solr.common.SolrException:org.apache.solr.common.SolrException: Could not load config for solrconfig.xml
The page also has message,
There are no SolrCores running.
Using the Solr Admin UI currently requires at least one SolrCore.
Any help regarding this is greatly appreciated.
In the root for the Solr config directory, there is a file called solr.xml. This file configures Solr cores. The file might contain:
<cores adminPath="/admin/cores" host="${host:}" hostPort="${jetty.port:}" hostContext="${hostContext:}" zkClientTimeout="${zkClientTimeout:15000}">
<core default="true" name="auction" instanceDir="auctionConfigDir" />
</cores>
The important point is to match instanceDir="auctionConfigDir" with the actual path/to/config/dir. If Solr can't find the location of you configuration files, it wont be able to start a core.
sudo vim /opt/solr-4.8.1/example/etc/jetty.xml
change
<!-- This connector is currently being used for Solr because it
showed better performance than nio.SelectChannelConnector
for typical Solr requests. -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.bio.SocketConnector">
<Set name="host">127.0.0.1</Set>
<Set name="port"><SystemProperty name="jetty.port" default="8983"/></Set>
<Set name="maxIdleTime">50000</Set>
<Set name="lowResourceMaxIdleTime">1500</Set>
<Set name="statsOn">false</Set>
</New>
</Arg>
</Call>
to
<!-- This connector is currently being used for Solr because it
showed better performance than nio.SelectChannelConnector
for typical Solr requests. -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.bio.SocketConnector">
<Set name="host">0.0.0.0</Set>
<Set name="port"><SystemProperty name="jetty.port" default="8983"/></Set>
<Set name="maxIdleTime">50000</Set>
<Set name="lowResourceMaxIdleTime">1500</Set>
<Set name="statsOn">false</Set>
</New>
</Arg>
</Call>
then
sudo service solrd restart

Enabling authentication realm in jetty 8

I tried to follow the offical tutorial to enable MD5 authentication for my only web-app running on jetty. Nginx manages ssl and redirects to jetty
I placed
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.security.HashLoginService">
<Set name="name">My Realm</Set>
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
<Set name="refreshInterval">0</Set>
</New>
</Arg>
</Call>
In jetty.xml, and the content of realm.properties are :
test: MD5:098f6bcd4621d373cade4e832627b4f6,user
In the tutorial they do not tell where to assign the realm to a context so I don't know where to place this :
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="securityHandler">
<Set name="realmName">My Realm</Set>
</Get>
</Configure>
I tried to put in in jetty-context.xml, and in web.xml, but it is still not working. I receive a 502 (bad gateway) when I place this in jetty.xml, in the other cases I get a normal json result from the web service (Shouldn't I get a 503 - not authorized ?)
A "Context XML File" (as outlined in Configuring Security Realms) refers Webapp deployment using the ContextProvider (enabled by default on jetty-distribution).
This deploys webapps by using a XML file, usually found in ${jetty.home}/contexts/ with a description of where that webapp is located on disk, and some details on how you want that webapp deployed.
You can also use the WEB-INF/jetty-web.xml to embed this Context configuration within your WAR file.