RMI passing firewalls

I hope anyone can help me with this:
I am trying to call a RMI server from a Client passing to natting firewalls, meaning my client has a private IP address and the server is installed on a node with a private ip address.
On the server side the firewall is set up to forward all calls on port 1099 to the private ip address of the server node.
So when I call the server from the client I use the public ip address of the firewall
I have done some network tracing and I can see first this stream:
TCP local ip:2002->public ip:1099 [SYN]
TCP public ip:1099->local ip:2002 [SYN, ACK]
TCP local ip:2002->public ip:1099 [ACK]
RMI local ip:2002->public ip:1099 JRMI, Version: 2, StreamProtocal
RMI public ip:1099->local ip:2002 JRMI, ProtocolAck
RMI local ip:2002->public ip:1099 Continuation
RMI local ip:2002->public ip:1099 JRMI, Call
RMI public ip:1099->local ip:2002 JRMI, ReturnData
TCP local ip:2002->public ip:1099 [ACK]
TCP local ip:2002->public ip:1099 [FIN, ACK]
TCP public ip:1099->local ip:2002 [ACK]
TCP public ip:1099->local ip:2002 [FIN, ACK]
TCP local ip:2002->public ip:1099 [ACK]
The connection is ended and the RMI client tries again on another port (this is build into the program).
No data is ever returned.
In the Protocol Ack I can see that the EndPointIdentifier is pointing to the public ip address of the client side firewall. In the continuation I see the client nodes private ip address.
Now, if I open a vpn connection to the remote network (the vpn ip address of my host is listed in the hosts file of the server node) then data is returned. Obviously they are returned on the vpn connection, but why?
The client vpn ip address is not on the same network as the client private ip address.
A network trace produces the same stream as above except for the connection being closed.
Can anyone explain the behaviour and - hopefully - point me in a direction how to solve this.
All help is most appreciated.
cwolfhagen

I found the solution myself.
Reason being that I hadn't quite understood the intricacies of RMI and data communication (I could blame my english - it's not my mother tongue).
But in order for anyone else who may have the same problem, I will post my solution.
First it is important to understand that RMI is using two ports - the RMI port to the registry (default 1099 - but you can pass a port number to the contructor) and a 'data' port, the ServerSocket, which is default picked randomly (port 0).
This port must be fixed so that you can define this to your firewall. You can either do this be modifying the createServerSocket method in your SocketFactory or by (in the newer JSKs) giving the port number as an argument to the exportObject methods or to the UnicastRemoteObject constructors.
If your firewall/router is using Network Address Translation there is another little trick:
Specify the public ip address/hostname of the firewall as a parameter to the JVM (-Djava.rmi.server.hostname=public hostname) when you are starting your server application and have your firewall forwarding all requests on your defined RMI port and serverSocket port to the private IP address of the server application machine.
Of course your outgoing firewall from the client has to allow communication on the same ports.
AND VOILA - you can connect.
I hope this can be of assistance to others.
Happy brewing.
cwolfhagen

Similar Messages

  • RMI Callbacks & Firewalls

    I am developing a java application where the client initiates a request to the server, then passes a remote object to the server, so that the server may do call backs.
    the problem is that the client is behind a firewall, and thusly when the server attempts to create a connection back to the client it fails.
    is it possible to have the client call back go through the existing socket, rather than creating a new one?
    the existing socket is the one the client opened to the server to connect in the first place?
    I have seen third party apps(rmi doves, rmiproxy) but i am wondering if this can be implemented easily with out the use of third party software?
    Thanks,
    dan

    Hi Dan,
    There are very easy ways to do this, and very complicated, depending on how many users your expecting. If the number is not too large, (<1000 or so) here is, quite likely, the very simplest method:
    Have clients call a getData method on the server object, it would be implemented something like this: public synchronized Data getData() {
       wait();
       return data;
    }Now clients would create a separate thread to call this function, since it will block until there is a callback from the server.
    Next the server object has a corresponding internal method:synchronized void setData(Data data) {
       this.data = data;
       notifyAll();
    }This will cause all blocked clients to return with the callback data via their outbound socket. When the thread is finished processing the callback functionality, it simply calls getData again.
    This is fast, simple, and easy; its problem is its potential to create a large number of blocked threads at the server. These do not consume a lot of compute cycles, but definitely memory.
    If you would like some other options, I host a free project for simple yet powerful RMI interoperation, at java.net:
    https://cajo.dev.java.net
    It should give you even more ideas!
    Good luck,
    John

  • RMI and Firewalls

    Hi folks,
    I have a sun cluster on which I put my RMI server, clients connect to server through a firewall. My problem, since it's a clustered environment we get physical IP addresses and logical IP addresses, clients if they ahve to connect to the server without firewall they have to see only logical IP addresses and not the physical. That works fine, but when there is a firewall the setting is different. If my logical IP is, say 120.30.40.10 and my physical IPs are 120.30.40.6, 120.30.40.7 .... The firewall is configured to let clients connect to, say IP 180.70.40.4 and it transltes that to the logical IP address. When client is trying to make a lookup it connects to 180.70.40.4 which will be translated to 120.30.40.10. It passes this step and manages to get a reference to the server, but when it tries to invoke a method on that server it 's rejected by the Firewall. The cleint is getting RMI exception connection refused to 120.30.40.6, which is the physical IP of the server. After discussion with security team they said that the client is trying to initiate another connection to that physical IP which is not allowed by firewall.
    My question is how to avoid the client connecting to the physical IP address. it seems that it's done internally in the RMI protocol.

    I solved that problem by setting the property java.rmi.server.hostname=external_IP_address which solved the external client problem. But that raised anothe rproblem, since I have internal clients as well they couldn't connect to the sever becasue it's on an external ip adress it's giving me connection refused to that IP.
    What's the solution in this case, I need somebody to help me ...
    Thanx

  • RMI Through Firewalls

    Its possible make RMI calls Through Firewall if the ports 1099 and 1098 are open???
    or its necessary applies the tunneling solution to pass through the firewall??

    well well... rmi is really bad for this. But this can be achieved...
    problem is, i think, that this server behind the firewall has private IP. So, when You register your server object, then registry knows, that it locates on private IP... and registry tells this information also to clients from outside networks (who connected originally to public ip).
    I did a nasty hack, using custom client socket factory. I ignore ip address, that is passed to the createSocket method. There I just use my preferred IP. Being more exact: cause this createSocket method is invoked on client side, I ask this IP from client's static method (and this method returns me IP, where client originally connected). So, now my server is available from everywhere, cause createSocket uses that IP, which was used looking up registri at the beginning.
    I am not happy with this, but... what else can I do? Most servers are behind firewall and does not have public IP... unfortunately, RMI developers don't get it :(

  • Question about argument marshalling with RMI.

    Hello guys,
    I recently started an RMI-related project and successfully implemented this technology, but at some point I created this interface on the server
    package xyz;
    import somePackage.SomeClass ;
    public interface A extends Remote{
    public void methodA( SomeClass x ) throws RemoteEx; //SomeClass is implementing interface A
    and exported it to the RemoteReg folowing standard RMI procedure.
    The problem came when i tried to pass a instance of SomeClass to methodA from the corresponding object retrived from the registry, got myself a nice
    java.rmi.MarshalException: error marshalling arguments; nested exception is:
         java.io.NotSerializableException: somePackage.SomeClass
    The question is: can't RMI pass arguments as shown previously or it's my implementation faulty?
    //ofc i could send the vars needed and create the SomeClass instance on the server but maybe it can be done this way too.

    Well the .class on the client implemented Serialize, while the .class from the server didn't(this being the only difference).So in other words 'yes, I had different versions of the .class file at the server and the client'.
    So in theory they might get different serialVersionsUID due to this discrepancyNo, in theory one of them isn't Serializable, so either the sender or the receiver is going to throw an exception of some kind.
    You have to deploy the same .class file at both ends (until you get into Versioning), and they certainly both have to implement Serializable. They also both have to have the same serialVersionUID, which you should hard-code into the class now.

  • How far Web service is better than RMI??

    Hi buddies,
    can anyone pls tell me *"How far Web Services are more preferable than RMI?"*
    i am totally confused of various kind of answers?
    thanx in advance.
    bye,
    subbu

    RMI transmits objects via Serialization so is much more space and time efficient over a LAN.
    Web Services transmits XML over HTTP so it can generally negotiate firewalls, which can be a major problem with RMI systems.
    Web Services don't support callbacks or small transactions very well, where RMI does (firewalls permitting).
    The security features built into Web Services or available via XML are superior to RMI over SSL in a number of ways.
    Basically RMI is best where you want to export an extensive API via a LAN. Web Services are best when you want to export a few simple transactions via the Web.

  • Problems passing std::vector char by reference

    I'm currently developing an InDesign Server plug-in off the CS5 SDK (Build 335).
    I've written some code that attempts to return the image bytes of a JPEG via a function
         bool CJPEGImage::Copy( std::vector<char>& Data );
    The typical usage is...
         std::vector<char> ImageData;
         if (ptrJPEGImage->Copy( ImageData ))
              // Do something with the data
    Having created the vector, the debugger shows the value to be [0x00000000](), which is correct as it is empty. On passing it to the function, vector now has a value of [0xffd55784](0xfd,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x6a ..................). I resize the vector to the number of bytes in the file, create a read stream and then use XferByte( (uchar *)&Data[0], FileSize ) to copy the image data into the vector.
    The contents of the vector are not changed and any attempt to use the buffer will lead to a crash elsewhere in the code. It's clearly wrong, as it is a reference and the value should be [0x00000000](0). It's as if the vector is pointing at some random memory. If you pass by copy the new vector is set up correctly.
    The same error occurs for <unsigned char>. But switch to <int> and everything behaves as expected. So what is it about std::vector<char>& that InDesign SDK has changed?
    I know that InDesign has its own K2Vector implementation. However I have a number of static libs that expect a std::vector<char>& and if so I'd like to use that.
    Has anyone seen this before and know a way to work around it?
    Thanks in advance,
    Andrew

    You cannot pass anything "by reference".
    no you are wrong. While invoking remote methods, RMI passes primitive types and abject types by value and remote objects by reference. "Pass by value" is implemented by deep copy. Pass by reference for remote objects is implemented by remote references- remote stubs. So to be more excat they are passed by remote reference. Thats why u extend unicastRemoteObject, remoteServer or remoteObject etc.
    Both the Client and the Server are two separate Java
    Virtual Machines. In order to pass anything, the RMI
    Runtime must serialize the data into a byte stream and
    pass the byte stream to the other machine using a
    network. This is why everything you need to pass
    either way must implement Serializable. Yes I agree with this part.

  • Making choice between socket and RMI

    I never use RMI, but i am familiar to socket programming. i want to write an online game, I know that use RMI will easy than use socket, could anyone tell me what factors will affect the choice between using socket and RMI if don't consider which one i am familiar ?
    thanks
    jacky

    I would consider the amount of traffic your online game is going to be generating. Obviously, if the traffic is the bottleneck, you will want to optimize it as much as possible.
    I can see that if you are familiar with sockets and socket programming, where this is very appealing because after all, you can't get much faster than raw sockets. Also, the Java APIs around sockets are much easier than the equivalent BSD Socket C/C++ libraries.
    Still, RMI has much more to offer.
    o It is relatively easy to set up a connection
    o exceptions will be thrown when problems occur
    o serializing classes is so easy it's laughable
    o If performance becomes an issue, you can (as the previous poster suggests) create your own custom socket factory which optimizes the used bandwidth. Options here include compression if you have the CPU cycles to spare.
    o There are mechanisms in place for working RMI over firewalls
    Many of the things that RMI offers, you might find yourself re-writing in your own socket-based API. Personally, I would choose RMI.

  • Security between two jvm using JNDI

    Hi ,
       I want to access the UME service of the SAP J2EE Container using a stanalone client application.
    So the client would be running on remote JVM.
    Here we use the JNDI service to communicate between the client and server.
    p.put(Context.INITIAL_CONTEXT_FACTORY,"com.sap.engine.services.jndi.InitialContextFactoryImpl");
                        p.put(Context.PROVIDER_URL, providerURL.trim());
                        p.put(Context.SECURITY_PRINCIPAL, securityPrinciple.trim());
                        p.put(Context.SECURITY_CREDENTIALS, securityCredentials.trim());
                        Context ctx = (Context) new InitialContext(p);
                        Object objRef = ctx.lookup(ejbName.trim());
    I want to know that is the communication between the client and server secured in this scenario
    Best Regards
    Manoj

    Hi,
    Java Remote Method Invocation by default does not support authenticated and encrypted transport.
    That is, objects sent over the network are not encrypted.
    A firewall can be used to secure a Java RMI application. Here, the firewall must allow access to specifically known ports. That is, these ports cannot be denied access by the firewall. SOCKS provides a partial solution to the use of RMI through firewalls in that it protects outgoing RMI calls, but incoming RMI calls as well as RMI call-backs are not protected.
    This may be overcome by using bi-directional RMI implementation through the firewalls. However, it requires the use of specific settings that can relax the security or application level proxy servers, thus increasing the administrative overheads. Also, changing the security policy to allow bi directional RMI traffic should only be done with extreme care. A better solution towards securing RMI is by means of supporting authenticated and encrypted transport, so that a network attacker cannot alter data on communication. This can be achieved by running RMI on SSL.
    regards
    Vivek Nidhi

  • Distributed Trx in diferents JVM

    Hi,
    I would like to know if is possible this situation:
    My application RMI client:
    1- get the XAResource xaR1
    2- create Xid1
    3- xaR1.start(Xid1)
    4-doAnyThingDB1("insert into table_Client ...")
    5- xaR1.end(Xid1)
    6- call the method of app Server RMI passing the Xid
    and the appSever RMI:
    1- get the XAResource xaR1 (same the appClient)
    2- create Xid2
    3- xaR1.start(Xid2)
    4-doAnyThingDB2("insert into table_Server ...")
    5- xaR1.end(Xid2)
    6- prepare(Xid2)
    7- commit(Xid2)
    After the conclution of method remote, There will register in the table_Server and table_Client or only on table_Server ?
    I need that the fisrt result is the correct, else what I can do to control transaction distributes in diferent VMs.
    thanks

    You could configure cache coordination (synchronization) in this scenario, it should be mainly the same as configuring it between servers. However you may wish to reexamine why you need an XA versus non -XA session. You may be able to accomplish the same requirement using a single server session and configuring two different connection pools.

  • RMI - doubt with Firewalls using RMI

    Hello everybody,
    We're running a client-server RMI application and we have a NAT enviroment, so we need to know if there is a problem or a limitant if the client's request pass by many firewalls, because we have firewalls in both sides.
    We have read about this and we found it is not possible when there are firewalls at the server side. [http://www.telekinesis.com.au/files/114/file/22/RMIProxy_Guide.pdf]
    So please somebody help me I have a really really big problem with this.
    Thanks in advance.

    We have read about this and we found it is not possible when there are firewalls at the server side. [http://www.telekinesis.com.au/files/114/file/22/RMIProxy_Guide.pdf]
    You could always buy the product. Disclaimer: I wrote and own it.
    You can also arrange for port forwarding at the server-side firewall.

  • Automatic Passing of parameters with every RMI Call

    We need the ability to automatically pass a couple of objects, both Strings in this case, with every RMI call we make from our clients (multiple clients) to the servers (multiple servers). Currently I'm using some code that Rickard �berg wrote a while ago that uses UnicastRef.marshalCustomCallData() and UnicastServerRef.unmarshalCustomCallData() so do this. I extended these 2 classes and rolled my own UnicastRemoteObject. This has worked out great but now I need to also use Custom Socket Factories, to get through the firewalls that our customer has. So I thought I could just extend UnicastRef2 and UnicastServerRef2 but when I do the servers never get
    bound to the RmiRegistry.
    We don't want to explicitly add these arguments to all our remote interfaces because we have a bunch of remote object classes and don't want to rely on the programmer sending the correct values or when writing new remote methods making sure that they these arguments are included.
    We're using 1.4.1, but this also fails with 1.3.1.
    The only thing I see in the logs is:
    Oct 2, 2002 1:53:39 PM sun.rmi.server.UnicastServerRef logCall
    FINER: RMI TCP Connection(1)-216.100.254.188: [216.100.254.188: sun.rmi.registry
    .RegistryImpl[0:0:0, 0]: void rebind(java.lang.String, java.rmi.Remote)]
    Oct 2, 2002 1:53:50 PM sun.rmi.server.UnicastServerRef logCall
    FINER: RMI TCP Connection(2)-216.100.254.188: [216.100.254.188: sun.rmi.registry
    .RegistryImpl[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
    Oct 2, 2002 1:53:50 PM sun.rmi.server.UnicastServerRef logCallException
    FINE: RMI TCP Connection(2)-216.100.254.188: [216.100.254.188] exception:
    java.rmi.NotBoundException: FileManager
    at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:106)
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:342
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:207)
    at sun.rmi.transport.Transport$1.run(Transport.java:148)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:4
    60)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport
    .java:701)
    at java.lang.Thread.run(Thread.java:536)
    So anyone know why this doesn't work when I supply the SocketFactories?
    Is there a better way to accomplish this than extending sun.rmi.server classes (which was really easy)? I can supply the source for my classes if it helps, though my UnicastServerRef2 and UnicastRef2 classes are pretty simple.
    Mark.

    First, did you really bind the servers?
    Second, does it work with the socket factories but without your custom Ref classes? I would suspect the socket factories here. Do they have a reasonable override for the Object.equals() method?
    EJP

  • Over technologies rather than RMI to pass remote objects

    Hi,
    Just a general question about remote objects. Currently I am familiar with RMI, IIOP and JMS to pass remote objects. What other technologies are available? in particular, technologies for passing remote objects between different software systems?
    Just a simple response detailing the names would be great, gives me something to research then.
    thanks

    ofcourse passing over socket is always an option. Sure in that case you will have to serialize the object yourself or make a mini-protocol of some kind.
    In our project we also use XML to pass object between C++ and Java world, instead of using CORBA.

  • Error passing a remote object in a rmi function call

    Hi,
    I've a problem passing an UnicastRemoteObject extended object in a rmi function call. I get the following error
    java.lang.IllegalArgumentException: argument type mismatch
    I've 2 Remote Objects: GalaxyRegistration and Station. I want to pass a Station Object as argument in a function from GalaxyRegistration. Does anyone know what the problem is?
    Here is the code:
    public class GalaxyRegistration
    extends UnicastRemoteObject
    implements GalaxyRegistrationInterface, Galaxy {
         public GalaxyRegistration() throws RemoteException {
         public void add(Station station) throws RemoteException {
              stations.addElement(station);
              System.out.println("Add Station " + station.getName());
    public class Station
    extends UnicastRemoteObject
    implements StationInterface {
         SystemInfo system;
         public Station(String name, String description, Coordinate position, Profile profile)
    throws RemoteException {
              system = new SystemInfo(name, description, position, profile);
    public class StationServer {
         Station station;
         public void run() {
              // create new Station
              System.out.println("Create new Station:");
              // register and bind new station
              try     {
                   station = new Station(name, descr, location, profile);
                   System.out.println("Station created ...");
                   GalaxyRegistrationInterface registry =
                             (GalaxyRegistrationInterface)
                             Naming.lookup
    ("//localhost/GalaxyRegistration");
                   System.out.println("Registry looked up ...");               
                   // >>>>>>>> NEXT LINE IS THE ERROR LINE <<<<<<<<<<<<<<     
                   registry.add(station);
              } catch(Exception e) {
                   System.out.println(e);
    }

    regardless of any other problems in your code, neither of the objects which you are subclassing from UnicastRemoteObject call the superclass constructor, which is a pretty basic flaw - in this case, it will lead to neither of these objects being exported properly.

  • RMI Codebase Passing Arguments

    I'm new to RMI and Java.How do you pass arguments using serialization in RMI? I'll be passing the arguments from a servlet. for example if i want to pass a string object from a servlet to the calling client service. Thanks

    Can you please provide me with a better direction in terms of developments (i.e examples)? thank you

Maybe you are looking for

  • Firefox 14.0.1 Won't Start in Full Screen Mode

    Firefox 14.0.1 for Mac doesn't appear to retain the full screen mode setting on shut down. It starts in "non-full screen" mode on start. I've tried safe mode startup, set to full and shut down, but it still doesn't keep the setting. Help appreciated

  • Firefox Looks Messed Up

    So I just bought a new computer, installed Windows 8 then installed Firefox. Upon loading it, this happens: http://imgur.com/BndEiGV I tried uninstalling then reinstalling and it didn't make any difference. I even tried to redownload it but still not

  • Grid with a detail field

    Hello all.. I have a gridControl which displays a certain view object. The view object also includes an Id field which is a FK to another view object (Id,Name). I want to display the Name which is translated from the other table in the grid as well..

  • Wlappc error

    Hi Gurus, when i am running my ant for build.xml, i am getting into the following wlappc, even though everything is in classpath. I'll appreciate if anyone could help me out. thanks, kuru error: BUILD FAILED D:\build.xml:75: Could not create task or

  • Clarification while uploading bank statement MT940

    Hi, While uploading the bank statement in SAP thru FF_5, how does the system check in SAP can any one expalin in brief how it behaves in mapping the bank statement to the SAP. Its urgent plz. Thanks SH