I'm currently working on a messaging program in java, and I planned on using UDP to send messages from the user to a central server, and I planned on using possibly TCP for messages from the server going back to the user. My main question is, how can I achieve this without requiring the client to port forward?
P2P clients like skype use subtle tricks to connect peers behind firewalls. The different techniques used are outlined here:
http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html
Very simply, the client has to establish the TCP connection to the server, even if the primary (indeed if not only) data flow is in the opposite direction.
Programs like skype either use a common port that is open (port 80) or put a rule in the firewall to allow another port to communicate. Additionally a program can open ports above 1024 without adminisrative permissions although depending on the type of connection it may need to set up UPnP or keep an active channel to a server open.
Related
I am trying to make a two-way instant messaging app over two different networks. One of these networks is mine, which has port forwarding enabled(sends traffic on certain port to specific ip address). My problem is that I need a two way connection(sockets can only send to serverSockets, serverSockets can't send to sockets). Is there a way to connect to a computer via a pre-existing connection? Is there a library for this? ie. socket.connect(serverSocket.getConnection, 5001); (I have made my own classes which handle all the Input/Output Streams and sockets, I just need a library for a function I can put in the class).
If what you're asking for is to have a computer exposed to the internet to directly connect to a computer behind a NAT, you might get your app working if you are able to implement something similar to reverse ssh tunneling. See here and here, for a java library.
But I would recommend some sort of client-server approach for this, in which everyone connects to the server, and through the server they connect to each other.
I have java programs for my client and server, and they work fine within the same wifi network. But I need the clients to be able to connect to the server from the open internet. In questions like these
How to connect client and server with the help of ip address which are connected to internet through different wifi?
https://coderanch.com/t/667020/java/Socket-connections-networks
the solution is to manually reroute a port to the server from the router, making it open to connections from the outside. Is there a way to do this with just software on the server? I don't understand why manually dedicating ports is necessary since of course other applications on my computer (like games) that I install communicate with their servers back and forth without me having to manually go in and flip switches.
How can I achieve this with just software running on my server?
If there isn't another way, how do other applications communicate openly without manual router changes, and will opening up ports through my router result in security issues?
You would need to change the architecture of your application. Currently, your server is behind a firewall which blocks connections from the internet - you want this! If you allowed all traffic from the internet to connect indiscriminately to your server, it would be very vulnerable to attack.
Other applications install and communicate without port-forwarding because the developer provides a server on the internet to act as a proxy between clients. The client connects out to the internet which is generally not blocked on home networks. Internal connections going out are considered less harmful than connections coming in.
I want to be able to connect (java)clients to each other without opening ports in their router or forwarding on their local network. I want to mimic the behavior of webtrc but in java, using a server for signaling. The server will have to receive session keys from both clients that wants to connect to each other, sending the first clients key to the second client and vice versa. After the signaling, the both clients can connect to each other using this key, and the packets will find their way through the router without opening ports and forwarding.
The goal is to make a framework out of this to be able to write applications that don't require a server with huge bandwidth that can read from one client and write to the other, for every pair of clients that wants to send data to each other. What I'm asking for is simply guidelines for this could be implemented.
TLDR: I want to be able to directly connect two clients, in two completely different networks, with the help of a public server and without any router configuration for the clients.
This technique is called Hole punching
"Hole punching is a computer networking technique for establishing communications between two parties in separate organizations who are both behind restrictive firewalls. Used for applications such as online gaming, P2P and VoIP, both clients establish a connection with an unrestricted third-party server that uncovers external and internal address information for them. Since each client initiated the request to the server, the server knows their IP addresses and port numbers assigned for that session, which it shares one to the other." from wikipedia
also take a look on this answer
I'm wondering if there is a way to setup connection between a client and a server over the internet and have both of them programmatic setup all needed router/firewall configuration changes to open needed external ports to communicate.
Assuming both server and client have known ip addresses and a DNS is not needed in this example to find the IP addresses. How might one have a server that when started configures access past the firewall and tells the router how to route proper communication to the server. I would assume the client may not need anything like this as it should only need to know the external IP address and port number of the server. If i'm wrong about my assumption please let me know.
Example if I have two houses house (A) has a server and house (B) has a client and both sites know what the other house external IP address is and know what port they will be using how may a Java application do all the configuration or at least do as much as possible on say windows,mac,ubuntu. The idea is the user of the server and client should not have to do a bunch of firewall/router configurations to get the application running. It would also be nice if in the example it shows how to release the connections when the server is terminated. Example when the java server is turned off it should close up port settings on the firewall and router. security and clean house.
There is no easy way of doing that as it will depend on the OS and on the many possible firewall application running on the machine. Plus, if your app crash, you will never set back the original parameters, which can be problematic when talking about security. Instead of trying to set up custom configuration, you should try to use standard communication template/protocol like http. This will gives you a high probability of your app running without additional configuration almost anywhere (since there is almost no point of having an internet connection if you don't allow http port).
What I mean is like servers on video games. You can run an application and it will set up a server on your computer with an IP and a port.
For example, how would you make an application where one host application sets up a thing where it has an IP and a port, and another computer that has access to the internet as well can type in the IP and port and it would be able to communicate with the host? I mean simple communication, like sending a boolean or String.
And would there be any security problems that would be needed to fix?
I guess I grasp the concept of your question...
You want two computers to connect via internet right? If that is the case, then you will have to use a thing called "sockets" that do connections between computers. About the server thing, well, for starters the client must always know what IP the server as (direct IP or by a DNS), and then you can connect your client to your server. There is a tutorial for sockets at the java pages: http://download.oracle.com/javase/tutorial/networking/sockets . About security issues, well, you must make sure that your server can handle anything that comes from the client (i really mean everything), i mean, accepting every type of data that is supposed to receive and deny everything that is not (trash per say). If you have that in mind then there is no problem (and of course, the server must have a firewall also to control the sockets, but that's not up to you).
Here is an example of how to use sockets to send a string from a server to a client.
http://www.java2s.com/Code/Java/Network-Protocol/StringbasedcommunicationbetweenSocket.htm
The site has about 20 examples of how to do what you are trying to do. In general I find this site to be the best JAVA resource that I know.
In general, the thing you probably want is a Socket. Sockets allow you to send bytes to an endpoint via TCP or UDP. This is very low-level, though, and are somewhat tricky because you have to design your own application protocol. You may want to use something that offers more abstraction.
Java sockets expose a stream interface so you could just encode integers as strings, for instance, and send them line by line, or you could do something fancier and more efficient like using a DataOutputStream to wrap it.
Handling the following issues can improve security.
If you have router ,set different ports for routing.
Example: If you are running server say on port 6001, map a virtual port say 9001 , which would be exposed to public.
DDos
IP Restriction - Not every user can access your machine !
Enabling router firewall does handle most of the issues.