-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Research how to send commands back to the Wazuh Server #73
Comments
After internal discussion, it was determined we are to use the Apache HttpCore library to perform outgoing HTTP requests. I've built a PoC plugin with a class following the examples from apache's documentation. The PoC mostly boils down to the following class (at the moment of writing):
|
It looks like the issue lied in the double quotes symbol used in the grant {
permission java.net.SocketPermission "*:80", "connect,resolve";
}; $ curl http://localhost:9200/_plugins/http-requests
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}fede@tyner:~/src/opensearch-plugin-template-java (main *+)
$ |
Understood. The approach looks great, although the chosen example seems to be a bit messy and over-complicated for our current use case. While investigating the Apache HTTP library, I stumped upon this other example that achieves the same goal, executing an asynchronous HTTP request. Although the code is quite similar, it's much shorter, direct and simple to read and understand. Comparing the examples, I noticed that the example referred here comes from the Apache HttpCore library, while the one posted in this comment comes from Apache HttpClient library. I assume the differences between both is that HttpCore contains the building blocks of the library while the HttpClient one already places some of these pieces in place, so using Apache's Http library is easier and more straightforward to use. That assumption is confirmed here. I therefore think that we should go for the HttpClient example as the base building block for our Http service, instead of HttpCore's example, which adds advanced mechanism such as thread's synchronization ( A version of the example extended with a POST HTTP request is attached: implementation("org.apache.httpcomponents.client5:httpclient5:5.4") /*
* ====================================================================
* 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.example;
import java.util.concurrent.Future;
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.io.CloseMode;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.util.Timeout;
/**
* Example of asynchronous HTTP/1.1 request execution.
*/
public class AsyncClientHttpExchange {
public static void main(final String[] args) throws Exception {
final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
.setSoTimeout(Timeout.ofSeconds(5))
.build();
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setIOReactorConfig(ioReactorConfig)
.build();
client.start();
final HttpHost target = new HttpHost("http", "localhost", 5000);
final String[] requestUris = new String[] {"/orders"};
for (final String requestUri: requestUris) {
// GET
final SimpleHttpRequest getRequest = SimpleRequestBuilder.get()
.setHttpHost(target)
.setPath(requestUri)
.build();
System.out.println("Executing request " + getRequest);
final Future<SimpleHttpResponse> future = client.execute(
SimpleRequestProducer.create(getRequest),
SimpleResponseConsumer.create(),
getCallback(getRequest));
future.get();
// POST
String message = "{\"message\" : \"Hello world!\" }";
final SimpleHttpRequest postRequest = SimpleRequestBuilder.post()
.setHttpHost(target)
.setPath(requestUri)
.setBody(message, ContentType.APPLICATION_JSON)
.build();
System.out.println("Executing request " + postRequest);
final Future<SimpleHttpResponse> future2 = client.execute(
SimpleRequestProducer.create(postRequest),
SimpleResponseConsumer.create(),
getCallback(postRequest));
future2.get();
}
System.out.println("Shutting down");
client.close(CloseMode.GRACEFUL);
}
private static FutureCallback<SimpleHttpResponse> getCallback(SimpleHttpRequest request) {
return new FutureCallback<SimpleHttpResponse>() {
@Override
public void completed(final SimpleHttpResponse response) {
System.out.println(request + "->" + new StatusLine(response));
System.out.println(response.getBody().getBodyText());
}
@Override
public void failed(final Exception ex) {
System.out.println(request + "->" + ex);
}
@Override
public void cancelled() {
System.out.println(request + " cancelled");
}
};
}
} Result of this code execution:
|
Description
The Command Manager will send the processed commands back to the Wazuh Server for their delivery to the final target.
We need to explore how to send this information to the Management API on the Wazuh Server (outbound HTTP traffic) from the Command Manager. If possible, we should investigate OpenSearch has this kind of functionality of its core or any of its plugins, and reuse any Java dependency already part of it.
The text was updated successfully, but these errors were encountered: