Logging network connections

C

Chris Smith

Hello,

I'm struggling with a problem. In a new feature for an application I'm
maintaining, user-defined code is uploaded to a web application, and run
in a security manager. The code is permitted to make network
connections to most addresses (excluding those inside the corporate
firewall), but our IT department has insisted that we keep a log of all
outgoing connections originating from such unprivileged code, so that we
can deal with abuse of the network by terminating accounts, etc.

How would I go about this? Using the security manager, I can allow or
disallow connections, but not log them. Could this be done with
SocketFactory somehow?

I know I can disallow network connections in the security policy, and
then provide a custom interface to make network connections using
doPrivileged and put the logging there. I'd rather avoid this if
possible.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Ross Bamford

Hello,

I'm struggling with a problem. In a new feature for an application I'm
maintaining, user-defined code is uploaded to a web application, and run
in a security manager. The code is permitted to make network
connections to most addresses (excluding those inside the corporate
firewall), but our IT department has insisted that we keep a log of all
outgoing connections originating from such unprivileged code, so that we
can deal with abuse of the network by terminating accounts, etc.

How would I go about this? Using the security manager, I can allow or
disallow connections, but not log them. Could this be done with
SocketFactory somehow?

I know I can disallow network connections in the security policy, and
then provide a custom interface to make network connections using
doPrivileged and put the logging there. I'd rather avoid this if
possible.

I'd define this as NMP (not my problem). If the admins want to log
network traffic then they log the traffic. Simple as that ;)

Cheers,
Ross
 
C

Chris Smith

Ross Bamford said:
I'd define this as NMP (not my problem). If the admins want to log
network traffic then they log the traffic. Simple as that ;)

Ah yes, but outside the application they have no way of distinguishing
"normal" network traffic from traffic originating in an unprivileged
code module provided by a customer. The point, here, is to know not
just that network traffic exists, but that it came from a certain JAR
file that was loaded and run on behalf of a certain customer.

That way, if the logs indicate that the module is using our application
as a staging point for malicious attempts to compromise other systems
(or send bulk email, etc.) then we can identify the customer and module
at fault, and take some action to stop it.

Thanks for the reply,

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
B

ByteCoder

Ah yes, but outside the application they have no way of distinguishing
"normal" network traffic from traffic originating in an unprivileged
code module provided by a customer. The point, here, is to know not
just that network traffic exists, but that it came from a certain JAR
file that was loaded and run on behalf of a certain customer.

That way, if the logs indicate that the module is using our application
as a staging point for malicious attempts to compromise other systems
(or send bulk email, etc.) then we can identify the customer and module
at fault, and take some action to stop it.

Thanks for the reply,

If no easy solution is available you could write your own. Create a class
that controls the log-file. The class would have a synchronized (maybe
static) public (or protected) method that accepts a rule or a set of
strings about the JAR and what it does.

Anyway, you can think of something that isn't very difficult to write.
 
R

Ross Bamford

Ah yes, but outside the application they have no way of distinguishing
"normal" network traffic from traffic originating in an unprivileged
code module provided by a customer. The point, here, is to know not
just that network traffic exists, but that it came from a certain JAR
file that was loaded and run on behalf of a certain customer.

That way, if the logs indicate that the module is using our application
as a staging point for malicious attempts to compromise other systems
(or send bulk email, etc.) then we can identify the customer and module
at fault, and take some action to stop it.

Thanks for the reply,

oic. I would /still/ suggest looking for external solutions first. As
you touched on, Socket[Impl]Factory would be a good way to go to do it
in the program, but what I'd suggest is leave your program general and
fit the environment to it.

Without going into too much detail (ot), your options are many:

Start by looking for the easy solution. E.g. is it always HTTP
connections? So add a header, and filter for that in your logger.

After that there are many other options, from simple masquerade setups
to virtual interfaces and tunnels, all of which could do the job you
need. Packet sniffing and logging is quite advanced nowadays, and most
systems can filter on anything from protocol-specific metadata to
outbound port...

It does of course depend on the architecture available to you as to the
solution you would choose, and if none of the above appeals the I'm sure
it would be a relatively easy task to subclass SocketImpl and provide a
custom SocketImplFactory. It's the performance issues you'd then need to
watch though I guess. My experience with pure Socket programming (in
Java at least) is minimal (which I consider a language feature ;)) ...

(Curiously, I seem to recall something within one of TCP/IP that
provides for exactly this, but can't find any reference so perhaps I
made it up :))

Ross
 
C

Chris Smith

ByteCoder said:
If no easy solution is available you could write your own. Create a class
that controls the log-file. The class would have a synchronized (maybe
static) public (or protected) method that accepts a rule or a set of
strings about the JAR and what it does.

Anyway, you can think of something that isn't very difficult to write.

Either you've missed the problem, or your response went over my head.
The problem is getting some piece of my code called whenever someone
else's code attempts to create an object of either of the classes
java.net.Socket or java.net.DatagramSocket. I'm not concerned with how
the logging itself actually occurs.

It's starting to look like there is a solution with SocketImplFactory
somewhere. I'll look into it further and summarize the results once
I've got it figured out.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
B

ByteCoder

Either you've missed the problem, or your response went over my head.
The problem is getting some piece of my code called whenever someone
else's code attempts to create an object of either of the classes
java.net.Socket or java.net.DatagramSocket. I'm not concerned with
how the logging itself actually occurs.

It's starting to look like there is a solution with SocketImplFactory
somewhere. I'll look into it further and summarize the results once
I've got it figured out.

Ah, OK. I thought you had more control over the programs. I Can't really
help you with that. Good luck, tough and please post it when you know.
 
C

castillo.bryan

Chris said:
write.

Either you've missed the problem, or your response went over my head.
The problem is getting some piece of my code called whenever someone
else's code attempts to create an object of either of the classes
java.net.Socket or java.net.DatagramSocket. I'm not concerned with how
the logging itself actually occurs.

It's starting to look like there is a solution with SocketImplFactory
somewhere. I'll look into it further and summarize the results once
I've got it figured out.

What about using JBoss AOP and introduce (is pointcut the proper term?)
pointcuts to intercept code creating socket connections.
 
C

castillo.bryan

I don't know if this will really work. I tried to do this by using
caller pointcuts instead of execution pointcuts using the JBoss
generated classloader. The samples in jboss aop show caller pointcuts
using the aop precompiler. I would rather have the interceptors attach
to the bytecode when the class is loaded. You have to use caller
pointcuts since you are trying to hook constructors and methods on
system classes.

I'm wondering if I can run the precompiler on a jar and modify the
classes inside it.

How does the code get uploaded and ran?

I assume:
1. A jar is downloaded or a set of jars
2. They are stored on disk
3. A custom class loader is used or (a new URLClassLoader)
4. Some class is then invoked through reflection.
 
C

castillo.bryan

I figured out my problem and I have a working project which logs
connection information for constructing new java.net.Socket objects and
calls to the connect method. I can get the calling class,
method|constructor and the jar the class comes from. The test also
works under a new URLClassLoader where I load the class for a jar
dynamically.

If anyone wants the example project, email me and I'll send it to you.

The project does hook some basic stuff, however for production purposes
I would have to hook a lot more, SSLSocket, opening a URL connection,
UDP sockets, etc...

Its probably less work to go the route of the SocketImplFactory, since
its a lot of work to parse the proper information you need from the
Invocations.

Given the following class......

package bcc.custom;

import java.net.*;

public class SocketCreator {

public SocketCreator() {
try {
Socket s = new Socket("localhost", 8080);
}
catch (Exception e) {
}
}

private static void test() {
try {
Socket s = new Socket();
s.connect(new InetSocketAddress("localhost", 8080));
}
catch (Exception e) {
}
}

public static void main(String[] args) {
try {
new SocketCreator();
test();
Socket s = new Socket("localhost", 8080);
}
catch (Exception e) {
}
}

}


I get this output.....

test2:
[java] ModuleRunner.run.......
[java] MainClass = bcc.custom.SocketCreator
[java] ClassPath = [file:/C:/bryanc/dev/aop/dist/testrun.jar]
[java] Arguments = []
[java] Socket: host=localhost port=8080 calledFrom='public
bcc.custom.SocketCreator()'
codeSource=file:/C:/bryanc/dev/aop/dist/testrun.jar
[java] Socket.connect: address=localhost/127.0.0.1:8080
calledFrom='private static void bcc.custom.SocketCreator.test()'
codeSource=file:/C:/bryanc/dev/aop/dist/testrun.jar
[java] Socket: host=localhost port=8080 calledFrom='public static
void bcc.custom.SocketCreator.main(java.lang.String[])'
codeSource=file:/C:/bryanc/dev/aop/dist/testrun.jar
 
C

Chris Uppal

Chris said:
How would I go about this? Using the security manager, I can allow or
disallow connections, but not log them. Could this be done with
SocketFactory somehow?

I've never tried this, but java.net.Socket.setSocketImplFactory() looks like a
good place to start. It looks (to a casual glance) as if it'd be pretty
straightforward from there to create a logging wrapper. The only problem might
be finding a general way to discover the underlying/real SocketImplFactory, but
since this sounds like a special installation, you might not need a general
solution.

-- chris
 
J

John C. Bollinger

Chris said:
Chris Smith wrote:




I've never tried this, but java.net.Socket.setSocketImplFactory() looks like a
good place to start. It looks (to a casual glance) as if it'd be pretty
straightforward from there to create a logging wrapper. The only problem might
be finding a general way to discover the underlying/real SocketImplFactory, but
since this sounds like a special installation, you might not need a general
solution.

I think I've looked into this before, and decided that there was no
general way within a program to obtain the SocketImplFactory currently
in use in the VM. That makes it a pretty good trick to decorate the
thing instead of writing a whole one from scratch.

It's not immediately clear to me, however, why the security manager
cannot be hooked to provide the logging. You can map Threads to context
information in a way that the security manager can find, and the
security manager can always get the relevant Thread instance via
Thread.currentThread(). In that way you should be able to feed the
security manager all the information necessary to perform the logging
you want. Or is there some other barrier to using the security manager?
 
A

Abhijat Vatsyayan

You might also want to look at AspectJ. It should be pretty simple to write
interceptors for all socket constructors (and/or other methods). AspectJ
(AOP in general) is pretty good for enforcing this kind of security. There
are other Java/AO solutions out there but I have not tried those.
Abhijat
 
A

Abhijat Vatsyayan

I should have mentioned this - I am not quite sure how the licensing works when
you start changing byte code of one of java.xxx classes but I would definitely
look into the licensing issue if I were to change byte code for lets say
java.net.Socket .
 
C

castillo.bryan

If you use JBoss AOP, you can change the byte code of the calling class
for the matched pointcut. So you can Instrument classes which create
new Sockets without modifying the bytecode for java.net.Socket.
 
C

Chris Smith

John C. Bollinger said:
It's not immediately clear to me, however, why the security manager
cannot be hooked to provide the logging. You can map Threads to context
information in a way that the security manager can find, and the
security manager can always get the relevant Thread instance via
Thread.currentThread(). In that way you should be able to feed the
security manager all the information necessary to perform the logging
you want. Or is there some other barrier to using the security manager?

Nope, the only barrier was just my mental block! I was stuck on doing
things the policy way instead of overriding SecurityManager methods, and
I missed the fact that this requirement isn't a policy. Thanks!

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top