I've got a web service which may be bound either to ssl or plain http. The java clients configured to know the server host and port. When client connects, I construct the server end point like http://host:port/service. Clients don't have a knowledge whether the server is using ssl - server always binds to a single port so that it's either secure or not. Now, the question is how to make a client to discover this without introducing another parameter? Can I challenge plain http request and then fall back to ssl (or vice verse) on a certain exception? Or I must explicitly introduce new connection parameter for the clients?
On the server side, you could use a mechanism like Grizzly's port unification implementation. This can be used to serve HTTP and HTTPS on the same port. This relies on the fact that in both cases, the client talks first and either sends an HTTP request or an SSL/TLS Client Hello message. It's quite handy for this on the server side (although I'm not sure I'd recommend running two protocols on the same port in general).
From the client's point of view (which is what you're asking about), the consequences of that are:
The fact that the client talks first means that it will always have to try first. Expect an exception of some sort if you try to talk SSL/TLS to a plain HTTP service and vice versa.
If the server uses port unification, there is no way you're going to be able to find out reliably.
Port unification aside (this is a rare case after all), you could try to cache results of past attempts.
More fundamentally, from a security point of view, not knowing which protocol should be used introduces a vulnerability: your system will be open to downgrade attacks (in a similar way as blindly relying on automatic redirects would). If your user-agent supports HSTS, it would be worth looking into that (although it would require the user-agent to remember which sites are to be used with HTTPS).
Either way, if you're concerned about security, you must configure the client to know when to use https://.
Related
I'm looking for a secure way to tunnel RMI traffic.
In My application(java Webstart) i must assume that the only port that is open is port 80.
I have the looked att socketfactories for rmi but do i really need a proxy then.
I need to do all my tunneling on the client side.
The only firewall i am trying to get past is on the client side.
I'm not able to open 1099 with port ranges above.
Would be nice to see some implementations.
Thanks!
Port 1099 was reserved for RMI at IANA in about 1995. There is no reason for it not to be open for outbound access in the client-side firewall.
RMI can be made to use fixed port numbers by supplying a port number when constructing (super(port)) or exporting (exportObject(object, port)). Better still, if you create the Registry within the server JVM via LocateRegistry.createRegistry(), all subequently exported remote objects will use that port unless they specify a different port or they use a server socket factory.
BUT ... RMI already includes HTTP tunneling 'out of the box'. No external solution required. You have to deploy the RMI-Servlet provided with the JDK, at the server end.
(a)
although not the newest fashion, exposing remote services with Hessian and Burlap seems to be a simple solution to avoid problem working across firewalls: http://hessian.caucho.com/doc/
see sample code for the server and client side:
http://www.javatpoint.com/spring-remoting-by-hessian-example
(b) or consider using Spring HttpInvokder (see some sample code here: http://www.javatpoint.com/spring-remoting-by-http-invoker-example)
HttpInvokder provides more customization options through the RemoteInvocationFactory, RemoteInvocationExecutor and HttpInvokerRequestExecutor strategies (for example, to add custom context information (such as user credentials) to the remote invocation, or using java’s built-in object serialization etc.), see:
http://docs.spring.io/spring-framework/docs/2.0.x/api/org/springframework/remoting/support/RemoteInvocationFactory.html
I have a situation and not sure if it has possible solution.
I have a Java Server with SSL Socket and certificates "A" & "B". I also have 2 types of clients - one with certificate "A" and another with certificate "B". However only one certificate is loaded on a server side and therefore either clients with cert. "A" can connect or only clients with cert. "B" can connect.
Is it possible to modify Java Server such that up on a connection from any client, it will determine which certificate is used ( A vs. B ) and use appropriate cert?
P.S: Please pardon my security ignorance.
Thank you.
Being able to use two server certificates on the same IP address and port is possible via the Server Name Indication (SNI) extension, which must be supported by the client and the server.
Java supports this on the client side since Java 7.
Unfortunately, this is not supported on the server side yet. This is planned for Java 8.
Meanwhile, if you do need SNI support on your server, you may be able to use another server to handle the SSL/TLS connection and forward the plain text connection to your application. Typically, this can be done with Apache Httpd (with a reverse proxy) for HTTP(S).
Alternatively, it looks like the HTTPS-SNI-Proxy project may be more flexible for other protocols (despite having HTTPS in its name). I haven't tried it, but according to its README, it looks for the SNI extension in the initial Client Hello and then forwards the entire SSL/TLS connection (without deciphering it) to another server, depending on what is configured. In your example, you would have to set up two SSLServerSockets on distinct ports (not the one you really want to listen to) and forward connections from this tool to either port depending on what the client requests with its SNI extension.
I am working on a java project where we have a server and a client application. The server accepts a connection and sends requested data to a client through socket programming.
Everything works fine but when uploaded and working on server I get connections from unknown ip's. And this application will be used from many countries so there wont be specific ip's to whitelist.
Is there a way to ban / reject these ip's so that only connections from my application should be accepted by the server using sockets. Is it possible to send custom data when requesting connections to the server so that it will tell the server to accept only these connections.
The selective acceptance you describe falls within the scope of authentication and authorization. You will want connecting clients to:
Identify themselves to you, so you can determine wether they are allowed access to the server. This can be accomplished by many means, ie IP or MAC address whitelisting, client side certificates, basic/digest authentication, or some other custom a uthentication scheme.
Once allowed access, you can further scope down what the connecting client can do in the system via authorization rules.
I recommend taking a look at libraries like Apache Shiro, that will do some of the heavy lifting for you.
After accepting the inbound connection you can use Socket.getInetAddress() on the returned Socket to retrieve and subsequently validate the IP.
If the IP is not allowed, then use Socket.close() to close the unwanted connection.
Edit:
Validation can of course be based on things beyond just IP. Once the connection is open you can use its streams to transfer arbitrary data to identify the client for instance closing the connection following an authentication failure.
Doing this you should, however, consider the possibility of someone being able to intercept your communications. In other words using a secure connection would make sense.
I'm not aware of a way in which you can authenticate clients in Java prior to opening (accepting) the connection.
If your server and client should be validated, you should think about using certificates also.
Here are some more information :
the java class
another SO question
I'm working on a WSDL-based web service and using Apache Axis 2. I'm not an expert on web services, and the person I'm working with claims that in order for this particular web service to work two calls have to be made on the same connection, i.e. using http keep-alive (There's basically a "commit transaction" method that needs to be called after the "save" method). This seems like it would be a pretty common issue, but I haven't found anything on Google.
I'm wondering if there's a way to explicitly tell Axis to do this. Also, how could I verify whether or not two calls are indeed being made on the same connection. I imagine some HTTP monitoring software like wireshark might be able to tell me this, but I haven't installed it yet.
The person you are working with is wrong. Even if HTTP can be optimized by using keep-alive to process multiple requests over a single TCP connection, this optimization should be transparent to the caller or callee, e.g. it should not matter if a client make two requests after each other on a keep-alive connection or if it's using two separate connections.
Java libraries (HttpURLConnection on the client side and the servlet API on the server side) do not even offer access to this information, so that the using software cannot know how the HTTP requests are actually performed.
You can use nmaplink text to see what is actually running on each port.
But if you are making 2 calls at same time, axis2 will throw port is already binded error. Any port can't handle 2 requests at the same time (my opinion). Maybe you can queue it and do it consecutively. But just confirm with other sources as well.
I have written a TCP IP socket program which works fine.
But my socket program did not work if my server or client is behind proxy.
So how to overcome from this type of issue.
Thanks
Bapi
Well there's two issues to consider:
Behind a proxy; and
Behind a firewall.
Firewall tends to be easier: you simply use port 80 (HTTP) or 443 (HTTPS). Proxy is harder because direct network communication tends to be disabled from normal PCs.
This is why you often find people using HTTP and/or SSL as their transport mediums because they bypass these kinds of security issues. You can do push content (with long-lived connections aka Comet techniques) so there's typically no real technical reason not to.
But it's hard to say one way or the other if that's a good idea or not without knowing more about your application and any pertinent requirements.
Proxies usually work at the application level, not at the transport level.
Here is some information about Java and proxies.
Depending on the proxy, there may be little that you can do. If the Proxy is designed to block all traffic that it does not directly handle, then you have to either go through the proxy, somehow working with it, or you have to find a way to sneak through the proxy.
For example, many applications are built on top of HTTP precisely because it is commonly allowed through firewalls and is commonly proxy-friendly. Thus, it's a pretty safe way of communicating when you know that you'll be installing the application in environments where proxies may exist.
In your case, it depends on what port(s) your application uses, on whether these ports are commonly handled by a proxy for any existing protocol, on whether or not you're using a standard (commonly known) protocol or have invented your own, and so on.
Is this proxy a transparent proxy? (That is, do web browsers have to be configured to see it, or not?) The kind of proxy it is determines part of how your application needs to work with it. Is the proxy controlled by your organization?
You say you are using port 5018. Just as an experiment, can you try using port 80? Just because you're using port 80 doesn't mean you have to use HTTP. This is worth a try to see if it helps.