Accessing REST API in Apache Ignite Using HTTPS - ssl

I am using Apache Ignite 2.8.0.
This is my server configuration,
<property name="sslContextFactory">
<bean class="org.apache.ignite.ssl.SslContextFactory">
<property name="keyStoreFilePath" value="C:\\ignite\\apache-ignite-2.8.0-bin\\keystore.jks"/>
<property name="keyStorePassword" value="1234567"/>
<property name="trustStoreFilePath" value="C:\\ignite\\\\apache-ignite-2.8.0-bin\\\\trust.jks"/>
<property name="trustStorePassword" value="123456"/>
</bean>
</property>
<property name="connectorConfiguration">
<bean class="org.apache.ignite.configuration.ConnectorConfiguration">
<property name="jettyPath" value="C:\apache-ignite-2.8.0-bin\examples\config\jetty-config.xml" />
</bean>
</property>
And This is My jetty-config.xml,
https://apacheignite.readme.io/docs/rest-api (Copy pasted)
Still it works with HTTP only.. It doesn't work with HTTPS. What is wrong with me?
How I can enable the HTTPS on Rest API?

Unfortunately, the documentation snippet is not complete.
You also need sslContextFactory defined in jetty configuration:
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
<Set name="keyStorePath">src/test/keystore/server.jks</Set>
<Set name="keyStorePassword">123456</Set>
<Set name="keyManagerPassword">123456</Set>
<Set name="trustStorePath">src/test/keystore/trust-one.jks</Set>
<Set name="trustStorePassword">123456</Set>
</New>
You also need a differently configured connector:
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg><Ref refid="Server"/></Arg>
<Arg>
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.SslConnectionFactory">
<Arg><Ref refid="sslContextFactory"/></Arg>
<Arg>http/1.1</Arg>
</New>
</Item>
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg><Ref refid="httpCfg"/></Arg>
</New>
</Item>
</Array>
</Arg>
...
You also need trust store and signed server key. Generating those, especially ones which may be accepted by web browsers, is way out of scope of this answer. Try letsencrypt for generating these, perhaps.

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.

How to set custom REST port for apache ignite when ignite is started as a service in Opendaylight apache karaf?

Opendaylight uses port 8080 which is the same as the default ignite REST http port. So i tried to change the port on which ignite listens for REST requests. Here is a java code snippet for this.
System.setProperty("IGNITE_JETTY_PORT","7111");
System.setProperty("IGNITE_JETTY_HOST","localhost");
ignite = Ignition.start(config);
The above works fine and changes the ignite REST port when i run in eclipse. But fails when i start an ignite instance in apache karaf.
I think you may try with the configuration xml file of ignite
<property name="ConnectorConfiguration.jettyPath" value="config/ignite-rest.xml"/>
and in the ignite-rest.xml it like:
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Arg name="threadPool">
<!-- Default queued blocking thread pool -->
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">20</Set>
<Set name="maxThreads">200</Set>
</New>
</Arg>
<New id="httpCfg" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="secureScheme">https</Set>
<Set name="securePort">8443</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
</New>
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server"/></Arg>
<Arg>
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Ref refid="httpCfg"/>
</New>
</Item>
</Array>
</Arg>
<!--
Note that in order to override local host and port values,
system properties must have names IGNITE_JETTY_HOST and
IGNITE_JETTY_PORT accordingly.
-->
<Set name="host"><SystemProperty name="IGNITE_JETTY_HOST" default="localhost"/></Set>
<Set name="port"><SystemProperty name="IGNITE_JETTY_PORT" default="9090"/></Set>
<Set name="idleTimeout">30000</Set>
<Set name="reuseAddress">true</Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
</Array>
</Set>
</New>
</Set>
<Set name="stopAtShutdown">false</Set>
</Configure>
You could change the port in the configuration file as you like,
and then start your ignite like:
ignite = Ignition.start(igniteConfigPath);
You can change OpenDaylight's NB REST port if that would help. See the example provided by upstream configuration management tooling like puppet-opendaylight (docs, config logic).

How to enable SSL in Grails application using Jetty Plugin

I am trying to enable SSL for my application which uses Jetty plugin.
I have followed https://wiki.eclipse.org/Jetty/Howto/Configure_SSL and created my key and certificate using JAVA keytool, But no luck so far.
Please help me in running my application using https locally or provide me some good reference to achieve my goal.
I have created a custom configuration
as shown below
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<Arg>
<New class="org.eclipse.jetty.http.ssl.SslContextFactory">
<Set name="keyStore">/keystore-ssl.jks</Set>
<Set name="keyStorePassword">password</Set>
<Set name="validateCerts">false</Set>
</New>
</Arg>
<Set name="port">8443</Set>
<Set name="maxIdleTime">30000</Set>
</New>
</Arg>
</Call>
</Configure>
and i am getting error
oejx.XmlConfiguration:main: Config error at <Call name="addConnector"><Arg>|
java.lang.ClassNotFoundException: org.eclipse.jetty.server.ssl.SslSelectChannelConnector
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.eclipse.jetty.util.Loader.loadClass(Loader.java:86)
This helped me in achieving my goal.
https://www.blackpepper.co.uk/blog/jetty-runner-https-xml-configuration
Just need to put the required xml content into jetty-server.xml

Configuring DataSources with IDEA IntelliJ Jetty Plugin (jetty-env.xml)

I'm trying to getting started with the IDEA IntelliJ Jetty Plugin. In our application we use a JNDI DataSource to access the actual database.
For development therefore we generate a jetty-env.xml and include this in the WEB-INF directory during development deploys:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.mortbay.jetty.webapp.WebAppContext">
<!-- Add an JNDI resource -->
<New class="org.mortbay.jetty.plus.naming.Resource">
<Arg>datasource_pbv</Arg>
<Arg>
<New class="org.apache.commons.dbcp.BasicDataSource">
<Set name="DriverClassName">oracle.jdbc.driver.OracleDriver</Set>
<Set name="Url">jdbc:oracle:thin:#dbserver:1521:DATABASE</Set>
<Set name="Username">user</Set>
<Set name="Password">pass</Set>
</New>
</Arg>
</New>
</Configure>
I reconfigured the Jetty WebAppDeployer in jetty.xml that way, so it uses the org.mortbay.jetty.plus.webapp.EnvConfiguration which reads and processes the jetty-env.xml:
<Configure id="Server" class="org.mortbay.jetty.Server">
...
<Array id="plusConfig" type="java.lang.String">
<Item>org.mortbay.jetty.webapp.WebInfConfiguration</Item>
<Item>org.mortbay.jetty.plus.webapp.EnvConfiguration</Item>
<Item>org.mortbay.jetty.plus.webapp.Configuration</Item>
<Item>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</Item>
<Item>org.mortbay.jetty.webapp.TagLibConfiguration</Item>
</Array>
...
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.WebAppDeployer">
...
<Set name="configurationClasses"><Ref id="plusConfig"/></Set>
</New>
</Arg>
</Call>
...
</Configure>
Unfortunately this doesn't work with the IDEA Jetty plugin. The IDEA Jetty Plugin generates a context-config.xml and a subsequent war-exploded.xml which does not add the EnvConfiguration. Therefore the jetty-env.xml is ignored when deploying with the Jetty IDEA Plugin.
How can I make this work or are the other ways to provide custom JNDI entries when deploying using the IDEA Jetty Plugin?
I haven't checked myself, but since IDEA Jetty integration relies on ContextDeployer, the following should work (if added to jetty.xml):
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.ContextDeployer">
...
<Set name="configurationClasses"><Ref id="plusConfig"/></Set>
</New>
</Arg>
</Call>

Is there a way to force Jetty to only use HTTPS?

I'm trying to force Jetty to only use HTTPS (or redirect to HTTPS from HTTP).
So far, I can access the server using both HTTP and HTTPS.
Here's the connector configuration:
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="port"><SystemProperty name="jetty.port" default="8888"/></Set>
<Set name="maxIdleTime">30000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<Set name="lowResourcesConnections">1000</Set>
<Set name="lowResourcesMaxIdleTime">500</Set>
</New>
</Arg>
</Call>
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.security.SslSocketConnector">
<Set name="Port">8443</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="handshakeTimeout">2000</Set>
<Set name="keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
<Set name="password">aaa</Set>
<Set name="keyPassword">bbb</Set>
<Set name="truststore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
<Set name="trustPassword">aaa</Set>
<Set name="handshakeTimeout">2000</Set>
</New>
</Arg>
</Call>
I've tried setting the default port as 8443 (in the first connector), that didn't work and generated an error.
Remove the first <Call name="addConnector"> section, that's the one that adds the plain HTTP connector (org.mortbay.jetty.nio.SelectChannelConnector).