Search Guard With Spring Data ES - elasticsearch

I followed steps mentioned here to secure my local ES installation using SearchGuard (no tag exist for it on SO). Now, it is reachable via Postman only through basic authentication with username password as default admin/admin.
Now, I need to allow my Spring Data ES project to be able to access this ES installation.
I tried:
Settings esSettings = Settings.settingsBuilder()
.put("path.home", ".")
.put("cluster.name", clusterName)
.put("searchguard.ssl.transport.enabled", true)
.put("searchguard.ssl.transport.keystore_filepath", "kirk-keystore.jks")
.put("searchguard.ssl.transport.truststore_filepath", "truststore.jks")
.put("searchguard.ssl.transport.enforce_hostname_verification", false)
.put("request.headers.sg.impersonate.as", "admin")
.build();
TransportClient client = TransportClient.builder().settings(esSettings)
.build().addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName(elasticsearchHost), elasticsearchPort));
client.prepareGet().putHeader("Authorization", "Basic " + Base64.encodeBase64("admin:admin".getBytes())).get();
return client;
Added header as suggested here.
But all I get is:
[elasticsearch[Meteorite][generic][T#3]] INFO org.elasticsearch.client.transport -
[Meteorite] failed to get node info for {#transport#-1}{127.0.0.1}{127.0.0.1:9300}, disconnecting...
org.elasticsearch.transport.NodeDisconnectedException: [][127.0.0.1:9300][cluster:monitor/nodes/liveness] disconnected
I need to get and post new data in ES (2.4.4).

Related

No server chosen by com.mongodb.async.client.ClientSessionHelpe from cluster description ClusterDescription

I am trying to connect to aws DocumentDB with async mongoClient.
I created a DocumentDB cluster in aws and success connect via ssh command line.
I went over here and created MongoClient and success connected and insert events.
But when I tried create com.mongodb.async.client.MongoClient, connection failed with folowing error:
No server chosen by WritableServerSelector from cluster description
ClusterDescription{type=REPLICA_SET, connectionMode=MULTIPLE,
serverDescriptions=[ServerDescription{address=aws-cluster:27017,
type=UNKNOWN, state=CONNECTING,
exception={com.mongodb.MongoSocketReadTimeoutException: Timeout while
receiving message}, caused by
{io.netty.handler.timeout.ReadTimeoutException}}]}. Waiting for 30000
ms before timing out.
ClusterSettings clusterSettings = ClusterSettings.builder()
.applyConnectionString(new ConnectionString(connectionString)).build();
List<MongoCredential> credentials = new ArrayList<>();
credentials.add(
MongoCredential.createCredential(
mongoUserName,
mongoDBName,
mongoPassword));
MongoClientSettings settings = MongoClientSettings.builder()
.credentialList(credentials)
.clusterSettings(clusterSettings)
.streamFactoryFactory(new NettyStreamFactoryFactory())
.writeConcern(WriteConcern.ACKNOWLEDGED)
.build();
com.mongodb.async.client.MongoClient mongoClient = MongoClients.create(settings);
MongoDatabase testDB = mongoClient.getDatabase("myDB");
MongoCollection<Document> collection = testDB.getCollection("test");
Document doc = new Document("name", "MongoDB").append("type", "database");
//**trying insert document => here I got an error**
collection.insertOne(doc, new SingleResultCallback<Void>() {
#Override
public void onResult(final Void result, final Throwable t) {
System.out.println("Inserted!");
}
});
Do you have any ideas, why does it happen?
I solved it by using uri:
String uri = "mongodb://<username>:<Password>#<hostname>:27017/?ssl=true&ssl_ca_certs=cert";
MongoClientSettings settings = MongoClientSettings.builder()
.streamFactoryFactory(new NettyStreamFactoryFactory())
.applyConnectionString(new ConnectionString(uri))
.build();
com.mongodb.async.client.MongoClient mongoClient = MongoClients.create(settings);
I encountered a similar error , for me it was related to the TLS configs.
I disabled the TLS in documentDB https://docs.aws.amazon.com/documentdb/latest/developerguide/security.encryption.ssl.html
In my case I had to restart the cluster after disabling the TLS. (TLS was not needed for the use case). After the restart the connection was established successfully.

Getting Error - javax.net.ssl.SSLHandshakeException: Server chose TLSv1, but that protocol version is not enabled or not supported by the client

Getting Error - javax.net.ssl.SSLHandshakeException: Server chose TLSv1, but that protocol version is not enabled or not supported by the client when making a call to a secured webservice.
Appended the following option to the JAVA_OPTIONS variable in the mydomain\bin\ setDomainEnv.cmd as advised in the oracle site but same issue.
-Dweblogic.security.SSL.protocolVersion=TLS1
Java client code :
File pKeyFile = new File("C:\\myJKS.jks");
if (pKeyFile.exists() && !pKeyFile.isDirectory()) {
logger.debug("JKS file exists, and it is a file");
}
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(pKeyFile.toString()),
pKeyPassword.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance("SunX509");
keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());
**SSLContext context = SSLContext.getInstance("TLSv1.1");**
context.init(keyManagerFactory.getKeyManagers(), null,
new SecureRandom());
sockFact = context.getSocketFactory();
if(sockFact == null){
logger.debug("SocketFactory is null");
throw new NullPointerException("socketFactory == null");
}
Client Env - JDK version: 7, Application server:Weblogic.
Trying to make it work from couple of days, but no luck.

How to Create culster in elasticsearch 6.2

Settings settings = Settings.builder()
.put("client.transport.ignore_cluster_name", false)
.put("client.transport.sniff", true)
.put("cluster.name", "TESTCULSTER").build();
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
// ClusterAdminClient clusterAdminClient = client.admin().cluster();
ClusterHealthResponse healths = client.admin().cluster().prepareHealth().get();
String clusterName = healths.getClusterName();
System.out.println(clusterName);
I am geeting this error
Exception in thread "main" NoNodeAvailableException[None of the configured nodes are available: [{#transport#-1}{zJ52yLDcR82UUQ7j-oxm6w}{127.0.0.1}{127.0.0.1:9300}]]
You want to connect to an elasticsearch via Java, right?
I suggest to use the HTTP transport (port 9200) rather than 9300
You enabled "sniffing", that means Java client will try to connect to each nodes directly, be sure communication is possible
Be sure you can curl your ES node from where you run the Java client

how two spring boot applications communicate over https having self SSL certificate?

I have two spring boot applications running on two different ports.Basically two micro-services. In both the applications i have created self SSL certificate and able to send request over HTTPS through browser.
Now, When one micro-service trying to communicate to other micro-service over HTTPS i am getting below exception.
Code Snippet- to connect from one micro service to another
strURL = "http://" + ipAddress + ":" + portNumber + "/" + contextPath;
URL url = new URL(strURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", "text/plain");
int responseCode = conn.getResponseCode();
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
while ((output = br.readLine()) != null) {
sb.append(output).append(" ");
}
conn.disconnect();
****javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
Is there any configuration needs to be done for two micro-services to communicate with each other?
The above error is caused because of the alternative names missing in your certificates. I believe you are running your application on localhost so
Add localhost entry in subject alt name
OR
Run the application on the same 'CN', as defined on your certificates.
Read Here -How to resolve the SSLHandshakeException

Login with domain/user/account not working with imap on exchange server using javamail

I'm trying to connect to an exchange mailserver (not sure what version) using javamail.
I have the username and password of an account that can impersonate all other users.
I'm trying to open the store of one of the users. (password unknown)
I did find this question How to use Javamail for accessing additional mailboxes (IMAP, Exchange 2010). It's using [domain]/[user]/[sharedaccount] as login.
The connection is made if I only use [domain]/[user], but with the name of the second account behind it [domain]/[user]/[impersonatedaccount] it won't work.
If I use the same credentials in Thunderbird it does make the connection.
Example:
domain: abc
known username with password: admin
mailbox to connect to: wverleur#abc.com (logs in with wverleur)
Working:
abc/admin
not working:
abc/admin/wverleur
credentials contains the following:
rootUrl: mailserver.abc.com
username: admin
password: password
domain: abc
impersonation: wverleur
getImapUsername() returns domain/username/impersonation
My connection code:
private void login() throws MessagingException {
// connection properties
Properties properties = new Properties();
// TLS & SSL
properties.setProperty("mail.imaps.starttls.enable", "true");
properties.setProperty("mail.imaps.ssl.enable", "true");
properties.setProperty("mail.imaps.ssl.trust", credentials.getRootUrl()); // self signed certificate
// login settings
properties.setProperty("mail.imaps.auth.ntlm.disable", "true");
properties.setProperty("mail.imaps.auth.plain.disable", "true");
properties.setProperty("mail.imaps.auth.gssapi.disable", "true");
// retrieve a session
session = Session.getInstance(properties);
// retrieve and open a store
store = session.getStore("imap");
try {
store.connect(credentials.getRootUrl(), credentials.getImapUsername(), credentials.getPassword());
} catch (MessagingException messagingException) {
throw new MessagingException("Error in storeConnect: " + store.toString(),
messagingException);
}
}
Javamail Debug shows the following:
DEBUG IMAP: protocolConnect login, host=[rooturl], user=[domain]\[user]\[impersonate], password=<non-null>
Am I missing something?
Is it even possible at all?
As per request of Bill Shannon I hereby post my answer to the question:
I placed the required certificate in the cacerts file of Java (be sure that you know what you are doing)
I changed my properties to:
please note that they are now imap and not imaps
// TLS & SSL
properties.setProperty("mail.imap.starttls.enable", "true");
properties.setProperty("mail.imap.ssl.enable", "false"); // is now false
// removed the trust for ssl
// login settings
properties.setProperty("mail.imap.auth.ntlm.disable", "true");
properties.setProperty("mail.imap.auth.plain.disable", "true");
properties.setProperty("mail.imap.auth.gssapi.disable", "true");
properties.setProperty("mail.user", credentials.getImapUsername());
properties.setProperty("mail.host", credentials.getRootUrl());
And, for me, it works.
As stated before. This is a very server specific answer and question. I hope it can help other people in their effort to connect their program to their exchange server.
EDIT:
Due to the requirement for support of other mail-servers the code changed:
String protocol = "mail.imap";
switch (encryption){
case SSL:
protocol = protocol + "s";
properties.setProperty(protocol + ".starttls.enable", "false");
properties.setProperty(protocol + ".ssl.enable", "true");
break;
case TLS:
properties.setProperty(protocol + ".starttls.enable", "true");
properties.setProperty(protocol + ".ssl.enable", "false");
break;
case NONE:
properties.setProperty(protocol + ".starttls.enable", "false");
properties.setProperty(protocol + ".ssl.enable", "false");
break;
}
properties.setProperty(protocol + ".auth.ntlm.disable", "true");
properties.setProperty(protocol + ".auth.plain.disable", "true");
properties.setProperty(protocol + ".auth.gssapi.disable", "true");
// other properties you want to set
SSL uses the mail.imaps and TLS and NONE use the mail.imap

Resources