I have an applet that connects back to a service running on the same host. The webserver that hosts the applet listens on both IPv4 and IPv6 as does the service that the applet wants to connect to.
The problem is that from the with in the applet all I can get is the page URL or the Codebase URL. From the the URL I can't detect if it was resolved to a IPv4 or IPv6 by the browser so when the applet was loaded via IPv6 and I use the URL to tell the applet which server to look for the service on it fails the Sandbox rules as it defaults to resolving to the IPv4 address.
The only solution that comes to mind is to sign the applet so it can request to connect to arbitrary servers, but I was hoping for a simpler solution (that doesn't involve buying certs or adding my custom CA to the truststore on all systems accessing the site).
Anybody got a better solution.
Use InetAddress.getAllByName(). The order of the results will tell you which you should use (namely, you should try to use result[0] first).
The important question is not "how was the applet loaded", but "how should I connect to the host".
Related
I am testing and debugging a system where application A submits a POST request to a URL when some event occurs. One of my programs, application B, must react to this event.
Application A requires that the URL uses HTTPS. I don't want to use a self-signed certificate because it may cause problems (curl complains about the self-signed certificate when I test it locally).
Letsencrypt can create a SSL certificate for free, but requires a domain. This is a problem for me because application B runs on a virtual machine. Whenever the machine is restarted, it gets a different IP address. Currently, there is no domain associated with that machine (i. e. you can only access it via a URL like http://aaa.bbb.ccc.ddd/).
Is there a way to use a non-self-signed certificate for an application without domain (i. e. one that runs on a URL like http://aaa.bbb.ccc.ddd/)? If not, what is the easiest way to make a Spring boot application (application B) support a non-self-signed SSL certificate?
There is one answer suggesting to create one's own certificate authority and installing it on all machines that access the URL. This is not an option for me because I have no control over application A.
Update 1: Application B runs on an EC2 instance in AWS.
Letsencrypt can create a SSL certificate for free, but requires a domain. This is a problem for me because application B runs on a virtual machine. Whenever the machine is restarted, it gets a different IP address.
It does not matter if the IP changes since all what is checked is the domain name. Thus, if the machine gets a new IP address you need to update the DNS to point to this new domain name.
In general the client will check if the subject/SAN of the certificate matches the domain in the URL. It is not possible to get a certificate which is generic enough to cover all the IP addresses you could get. Thus, having your own fixed domain name with a dynamic IP address behind it is the way to go if you want to use normal clients to access the site.
My issue is a protocol that identifies terminals by it's sending IP. I want to manage the connections of several terminals to this server using some kind of proxy that implements that protocol.
So I have Terminal A which is identified by the server by the IP 1.2.3.4 and Terminal B which is identified by the server using the IP 5.6.7.8. Now the proxy will be in a local network with Terminal A and B.
When Terminal A wants to reach the server, it will query the proxy and the proxy needs to send the request on behalf of Terminal A using IP 1.2.3.4 to the server
When Terminal B wants to reach the server, it will query the proxy and the proxy needs to send the request on behalf of Terminal A using IP 5.6.7.8 to the server
Is it even possible to solve that issue in Java or do I have to do network voodoo on the router to achieve this?
Edit: to make things clear. I know what a network proxy is and what a router does. I also know how to solve my problem on a network level using advanced network voodoo if required. What I want to know is if my guess that the problem can't be solved using Java is correct. So the bottom line question is: can I use Java to send traffic using a specific network interface to which a specific IP has been assigned or do I have to rely on what the operating system does to route my traffic (in which case the advanced network voodoo would be required)?
Edit2: If routing of network traffic can be done in java, I'd just like a quick pointer where to look into. My own googling didn't return any useful results.
1) You already have some implementations for tcp tunelling with java. Below are some examples:
http://jtcpfwd.sourceforge.net/
http://sourceforge.net/projects/jttt/
2) Even with these existing implementations, you can still do you own by forwarding packets arriving in the proxy using java.net.Socket.
3) I still think that a better option would be a specific implementation using java.lang.Runtime.exec() and socat linux command. socat is just like the Netcat but with security and chrooting support and works over various protocols and through a files, pipes, devices, TCP sockets, Unix sockets, a client for SOCKS4, proxy CONNECT, or SSL etc. To redirect all port 80 conenctions to ip 202.54.1.5:
$ socat TCP-LISTEN:80,fork TCP:202.54.1.5:80
Is it possible to write a Java applet that can be a server on the client machine within the client's local network?
To be more specific, what I am looking to do is tunnel non-web traffic over the web. The sender would send to the applet, which would then forward the received data back to the server.
Is this sort of thing possible? What are the restrictions that might get in the way?
Note: I know that the applet can connect back to the server, that isn't an issue. The issue is whether or not an applet can listen for a connection / data on a local, client-side port.
An unsigned applet can only connect the host they come from.
A signed applet can do any connection you want and can listen on tcp-ip ports.
Source : http://docs.oracle.com/javase/tutorial/deployment/applet/security.html
Server does not connect to anywhere. Server opens server socket and is listening.
In past as far as I remember the server socket was restricted in MSIE and was permitted in Netscape (do you remember such browser?) :)
I personally have not been writing applets for the last 10 years, so I have no idea what happens now with currently existing browsers, but it is very easy to check. Just write the shortest applet you can and put code new ServerSocket(1234).accept(); into its init() or start() method. If no exception was thrown you can write applet that functions as a server. Otherwise you cannot.
Just try it with all available browsers. 20 minutes work and you are done. Good luck. I'd will be glad to know about the results.
Generally, it cannot.
One reason why is that applets tend to be ran within security constrained environments, which means that they are denied the ability to open server sockets.
There are ways around such a restriction, basically you can specify a special security policy for the applet, or run it in a special unconstrained container; but why bother when you can just port the contents of your application into a standard servlet, or even a stand-alone server?
I have a java application that runs on client machines that receives ajax requests from web applications. Some of these web applications that would like to use the service are served only under https.
I have the java app now accepting and handling SSL requests just fine, but I must first navigate to the server in a browser and accept the cert.
What is the best method of having a 'real cert' installed as part of this java app that listens on https://localhost:my_port?
On windows, it seems I can have an installer add a self signed cert to the machines accepted list. I had also thought about getting a verified cert for thisApp.myDomain.com and then changing host files to point that address to 127.0.0.1, but changing host files seems malicious and I worry about that being picked up by anti-virus.
The 'main' application is a web based system. Some users of this web based system would like to be able to print to special printers on designated computers. The java app is to be installed on those computers, the web application then sends ajax requests to the java app, which interacts with the printers. End users need to be able to install this java service with an easy, one-click type of installer. The web app is run from a browser on the machines doing the printing, hence localhost.
As stated earlier, the web apps need to connect to the web server (currently residing with amazon) via https. The connection to the localhost print server does not need to be https for any reason other than Chrome complains about insecure content, and chrome is currently the most widely used browser by our users.
Any thoughts or suggestions?
If by "real" cert, you mean one that signed by a trusted CA, then I think that the answer is that you probably can't. I don't think a trusted CA will issue one for you.
The answer I linked to above suggests that you set up your own CA by getting a CA cert. The other alternatives are a self-signed cert for 127.0.0.1, or tweaking your DNS resolution (e.g. via the client machines' "hosts" files) so that some name with a valid cert resolves to a loopback address on your client machines.
BTW - turning off certificate verification is not the way to go. It is better to add a self-signed certificate to the trusted cert list of (for instance) the user's browser.
If I was in your situation, I think I'd change whatever it is that requires HTTPS for requests on 127.0.0.1. Either don't require HTTPS for the requests, or change the IP address to the client's own IP address.
I try to install self signet certificate on client machine - but fails. Don't remember what was the issue. So I turn off verification for certificate in client code.
You can read about it here.
I just set up a MySQL server on my PC for testing Java with JDBC.
At the moment "localhost" works perfectly as hostname for my applications, when running them on the same system.
However what would be the hostname for my MySQL server for applications that are running on different computers? Something like "my_ip:port" would work? I was thinking of writing an applet, which I could upload on a web server and try to connect to my database here. Is it possible to achieve that?
Something like "my_ip:port" would work?
If the MySQL instance has bound to your public interface, and if your firewall allows it, yes. If you connect to the 'net via a router that does NAT (for instance, a combined DSL modem and wireless router allowing you to connect multiple computers), you'll have to set up forwarding rules in the router to tell it which of the local machines to forward requests to.
You don't have to use an IP address. Your machine will also probably have a host name of some kind (either one you've assigned or, if you connect through an ISP, more likely one they've assigned). That would work too.
I was thinking of writing an applet, which I could upload on a web server and try to connect to my database here. Is it possible to achieve that?
With a signed Java applet, yes; otherwise, no. That's because the security sandbox that Java applets run in doesn't let them access servers other than the one they were loaded from (the web server).
A much better approach is to have your client-side code (Java applet, or just DHTML+Ajax stuff) talk to server-side code on the web server, which in turn talks to your DB. That way, the DB is never directly exposed to the outside world, and you don't have to do things like signed applets.
You can always use the ip address of the server running mysql as the hostname or its fully qualified domain name.
That should work, but you also should consider port-forwarding through your firewall.
Go here to get your IP: http://www.whatsmyip.org/
The port is the port mysql is setup on.