Solved The best server <-> server communication method?

Discussion in 'Plugin Development' started by CrystalxNeth, Nov 2, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    CrystalxNeth

    I have a project which will require me to securely communicate with other bukkit servers in a network. I do not want to use the plugin message system as that only works if a player is online the server.

    I did a bit of research and found out a good option may be to use Netty. The problem is I have absolutely 0 experience with netty, and the user guide on the github is pretty difficult to understand after a certain point as a netty beginner.

    So, is my best option to use netty, or are there other secure ways of doing so?
    If not, can someone who understands netty please tell me how they learned it? Because the userguide literally throws everything at me at once and it is really difficult to understand.

    Thank you, and any help will be really appreciated!
     
  2. Offline

    mcdorli

    There is no really safe way to communicate between two servers safely, if they are on different ips. It would be a bit more safe if it was bungeecoord, but it probably isn't. Your best choice is netty in this situation.
     
  3. Offline

    mythbusterma

    @mcdorli

    Can you please cite that ridiculously incorrect information? There are are plethora of ways to "safely" communicate between two servers, and IP has very little to do with network topology, for example one computer may have 10 IP addresses, and localhost communication is still pretty secure. Even if they are different physical hosts (quite unlikely, anyway), using SSL forms a pretty secure connection between the computers.


    @CrystalxNeth

    Why are you placing so much emphasis on being "secure?" What exactly are you trying to defend against? Are you worried about traffic sniffing? Worried about someone impersonating one of your servers? I don't really get your concern.
     
    DoggyCode™, rbrick and CrystalxNeth like this.
  4. Offline

    CrystalxNeth

    I will be sending information such as rank change updates, currency change updates, etc. between servers.
    Therefore, I want to prevent against attacks which may intercept and modify the data being sent. I understand that there is such thing called SSL in Java which encrypts the data being sent, but I'm sure one could un-encrypt that if they really wanted.

    I also want to prevent against attacks which inject data into the connections. A theory I thought of to prevent this would be that each server has a randomly generated key, and anytime another server tries to send data to that server it must precede the data with the key in order for the other server to accept that data. If the key is incorrect I would block connections from wherever the data was sent. Also, this method would require me to somehow hopefully prevent people viewing what data is sent between servers, because if they find out a key for the server they may be able to inject data.

    ^^This is all theoretical since I don't know Netty yet, but I'm sure these types of attacks are possible somehow and I want to make sure the network is close to 100% secure
     
  5. Offline

    mythbusterma

    @CrystalxNeth

    I don't have time to respond properly right now, but I will.
     
    Last edited: Nov 3, 2015
    DoggyCode™ and CrystalxNeth like this.
  6. Offline

    CrystalxNeth

    Alright, take your time! I found a place to start learning the Netty basics so I'll be doing that for now. Thanks a lot though :D
     
  7. Offline

    CoolDude53

    @CrystalxNeth Another way, aside from netty, would be to use a shared database, the only issue with that is the change would not be immediate, so you would have to figure out the best way for you to sync the data to the server (i.e. every player login/logout or every two minutes or something like that).
     
  8. Offline

    CrystalxNeth

    I use a MySQL but I want to change to be pretty much instant. The current feature of the project I'm working on that requires the need for this is ranks. If a user were to add a rank via a command I want to notify the other servers to check the database right away rather than constantly checking for new ranks.

    @mythbusterma Before you reply;

    So I did some research and I think I understand the basics of Netty. Now that I understand, I've been thinking of how to establish a secure connection. Here is what I think may work:

    My network's proxy would contain a Netty server (Since there is only one proxy for my network), and all bukkit servers would be the "clients". In order to connect, the bukkit servers, aka clients would need to first retrieve a SSL self signed certificate from a MySQL database. This certificate would change and be randomized every 30 seconds (or a different amount of time), therefore increasing the security hopefully. The 'clients' would then attempt to connect to my 'server', AKA the proxy for my network. The proxy would check the database for the SSL certificate, and if they don't match then it would reject the connection. If it failed again, it would block that connection permanently until the proxy was rebooted.

    Would this be pretty much 100% secure? (Considering I be smart and ensure my MySQL password is extremely intricate and never leaked). Or would retrieving the SSL from the database be insecure? Also, I should mention I don't have any experience with SSL, nor do I fully understand it, so this theory could be completely absurd so I apologize if it is.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Nov 3, 2015
  9. Offline

    mythbusterma

    @CrystalxNeth

    Netty is a framework built on top of simple sockets in Java, all it provides is a simple way of sending information between two computers, as implementing your own network code is tedious, repetitive, and error-prone.

    The particular attack you're describing is called a Man in the Middle Attack (MITM Attack). Assuming your servers are running on the same physical machine (quite likely), and the network topology is correctly configured, for this to be possible someone has already compromised your box (you're well beyond fucked at this point). If the servers are not on the same machine (unlikely, but still probable), then someone would have to have not only a tap but the ability to inject packets somewhere along the path between the servers. This would imply that someone has seriously compromised either your datacenter or an ISP (or a dishonest ISP or datacenter), which is extremely improbable not only because of the difficulty, but if someone had done something like that, their first target would probably something a lot more interesting than a Minecraft server.

    As for using SSL, there's no real reason to have the self signed certificates or whatever that convoluted set up was. I've already shown how pointless encryption for this would be, and as for host verification (the other function of SSL): You can simply use TCP's nature to ensure that the host on the other end is valid. If both the client and the server are aware of the other's global IP, all you have to do is verify the IP when the client connects. The fact that a TCP connection is established between the two computers ensures that the globally visible IP of the server and client are in fact what you expected them to be [1].

    If you really want encryption (I'm not sure why you would need it), you can simply use a symmetric cipher on both the client and server server (that's a weird sentence). There's no reason to use something irrecoverable (something like the SSL scheme), as the information as is simply control information (e.g. no credit cards, personal details, etc.), and it's much simpler to implement. The stereotypical candidate for this would be AES, the current encryption standard used by pretty much everyone. You would simply store a password on both the client and server, and encrypt before sending and decrypt after receiving the information back. This would be way more than enough security for you, as for someone to find the password, they would again have to pwn your box.



    [1]: A quick caveat to this statement, it is possible to fake this, however this means that either: (1) someone has messed with your hosts.conf file (again, implying your box has been pwned) or (2) someone has messed with BGP tables in either your ISP or server host (again, implying the ISP has been pwned)
     
  10. Offline

    CrystalxNeth

    @mythbusterma

    Wow, thanks for that amazing reply man. I'd give you 10 likes if possible lmao.

    So I guess I'll avoid SSL. I'll use an API I'll create for my network which will allow me to check if a server with the ip and port exists within the network or not, and I'll probably use AES if possible for objects, which I don't see why it wouldn't be if the object is serializable.

    I do have a few simple questions if you don't mind, since you seem to know your stuff really well:
    1) Is the data sent via Netty pretty much instantaneous (i.e. a few milliseconds)?
    2) Can Netty get backed up if a lot of data is being sent to the server and the server will be sending a lot of data to the clients? Or will it take an unrealistic amount to do so?
    3) Is there a way to deny incoming connections to a Netty server from a client? Or do I need to just ignore all of the data received from bogus clients. (I couldn't yet find a way to block incoming connections, and I fear if someone does get connected they could spam a ton of data and just back up the threads regardless if I do nothing with the data).
     
  11. Offline

    mythbusterma

    @CrystalxNeth

    AES can only be applied to raw data, it takes in a chunk of data. If you're just sending Strings, this is fine. If you're serialising Objects in some fashion, you'd have to turn them into Strings or byte arrays (or equivalent). Once that's done, you can then apply AES.

    1. It is the same as any TCP socket between the servers. Approximately 2-2.5x the latency between the devices (this is the "ping"). You can use the ping utility to find this number. If they are on the same box, this latency should be <1ms, and on any sort of decent host, this should never be more than 300ms (even if they're on opposite sides of the world).

    2. Again, it's just a TCP socket. The backing up of your TCP buffer depends on the rate of your uplink. If you have a 30mbps link to the internet, and start sending 50mbps of data, you're obviously going to have a problem. As far as I know, using Netty doesn't incur any additional bandwidth overhead, but TCP is about 10% overhead (this varies hugely depending on your traffic, but tends to decrease with the amount of data sent). This being said, what the hell could you be sending that would inundate the link between two servers?
    3. Netty has a built in utility for the server called an IpFilterHandler, this can be used to filter based on IP. This is one of the many handlers you will have to learn about to use Netty. Note this SO question: http://stackoverflow.com/questions/9026090/how-to-refuse-incoming-connections-in-netty and the relevant documentation here: http://netty.io/3.5/api/org/jboss/netty/handler/ipfilter/package-summary.html
     
    DoggyCode™ and CrystalxNeth like this.
  12. Offline

    CrystalxNeth

    Okay, thanks for everything! I really appreciate it all :).
     
    DoggyCode™ likes this.
Thread Status:
Not open for further replies.

Share This Page