Monitor outgoing traffic of UDP and TCP protocols to monitor if all connections are monitored and inform about it in logs
@witx98 what do you think about something like this?
I found some relevant information regarding TCP and UDP support in Spring Integration that might be useful for this issue https://docs.spring.io/spring-integration/reference/ip.html Could you please clarify what exactly we want to know about these connections? @marwin1991
@witx98 I was thinking about something more like this https://stackoverflow.com/a/63197003
The idea is that, application can do some connections, but we don't know about it and this should capture it and print to logs (if it's not monitored by hofund)
The approach mentioned in the Stack Overflow is based on SecurityManager which is deprecated and planned for removal in future Java versions. @marwin1991
@witx98 yes, but maybe we can find something inside JVM or lib that will allow us to do it :)
@marwin1991 maybe this way is the way XD ? https://github.com/slytechs-repos/jnetpcap-wrapper?tab=readme-ov-file
@Athi @witx98
I have made some simple research and jnetpcap-wrapper but it requires Java23.
package abc;
import org.jnetpcap.Pcap;
import org.jnetpcap.PcapException;
import org.jnetpcap.PcapHeader;
import org.jnetpcap.PcapIf;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
public class Test {
void main() throws PcapException {
List<PcapIf> devices = Pcap.findAllDevs();
for(PcapIf device: devices) {
try (Pcap pcap = Pcap.create(device)) {
pcap.activate();
pcap.loop(0, (String msg, PcapHeader header, byte[] packet) -> {
System.out.println(msg + " " + header.toString() + " " + new String(packet));
}, "[" + device.name() + " - Capture Example]");
}
}
}
public static void main(String[] args) throws PcapException {
System.out.println("Przed inicjalizacji");
new Thread(() -> {
try {
new Test().main();
} catch (PcapException e) {
throw new RuntimeException(e);
}
}).start();
System.out.println("Po inicjalizacji");
try {
// Create HttpClient
HttpClient client = HttpClient.newHttpClient();
// Create HttpRequest
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://www.google.com"))
.GET() // Optional, as GET is the default method
.build();
// Send request and receive HttpResponse
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// Print the response
System.out.println("Status Code: " + response.statusCode());
// System.out.println("Response Body: ");
// System.out.println(response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
I don't now yet how to properly capture traffic, because it looks like it capute with delay (i dont see this call, but I see traffic I made from browser).
The second thing to do is to verify how to get url from raw network package
this looks nice and simple:
package pl.com.softnet.jbramka;
import java.net.*;
import java.io.*;
import java.util.*;
public class MonitorOutgoingTraffic {
public static void main(String[] args) {
ProxySelector.setDefault(new LoggingProxySelector(ProxySelector.getDefault()));
// Example outgoing request
try {
URL url = new URL("https://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
System.out.println("Response Code: " + connection.getResponseCode());
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class LoggingProxySelector extends ProxySelector {
private final ProxySelector defaultProxySelector;
public LoggingProxySelector(ProxySelector defaultProxySelector) {
this.defaultProxySelector = defaultProxySelector;
}
@Override
public List<Proxy> select(URI uri) {
System.out.println("Outgoing connection detected: " + uri);
return defaultProxySelector.select(uri);
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
System.err.println("Connection failed to URI: " + uri);
ioe.printStackTrace();
}
}
output:
Outgoing connection detected: socket://127.0.0.1:40563
Outgoing connection detected: https://example.com/
Outgoing connection detected: socket://example.com:443
Response Code: 200
Process finished with exit code 0
Other option is to use AgentBuddy
package abc;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import static net.bytebuddy.matcher.ElementMatchers.named;
public class MonitorSocketTraffic {
public static void main(String[] args) {
// Install ByteBuddyAgent dynamically
ByteBuddyAgent.install();
// Redefine the Socket class using ByteBuddy with reloading strategy
new ByteBuddy()
.redefine(Socket.class)
.visit(Advice.to(SocketAdvice.class).on(named("connect")))
.make()
.load(Socket.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
// Example outgoing request
try {
URL url = new URL("https://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
System.out.println("Response Code: " + connection.getResponseCode());
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
public static class SocketAdvice {
@Advice.OnMethodEnter
public static void onEnter(@Advice.Argument(0) Object address) {
System.out.println("Outgoing connection: " + address);
}
}
}
output:
WARNING: A Java agent has been loaded dynamically (/home/pz2/.m2/repository/net/bytebuddy/byte-buddy-agent/1.15.10/byte-buddy-agent-1.15.10.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
Outgoing connection: example.com/93.184.215.14:443
Response Code: 200
Process finished with exit code 0
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.15.10</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>1.15.10</version>
</dependency>