dan677915
By:
dan677915

Is it really possible for a hacker to break into my DB or Steal My Traffic?

November 26, 2015 3.7k views
MySQL LAMP Stack

It more like a worst practice than a best practice: run mysql with remote access at port 3306 at IP 162.254.27.87.

but it nothing ever happens because in reality, instead rumor, no one can touch it.

3 comments
  • Yes? I am sorry, I am not sure what the yes applies to. Could you please clarify? Believe it or not, I am trying to learn something here. I stated a hypothesis as though it is a solid fact but the truth is, I really don't know.

    If yes is a response to the question that is the topic of this thread, then maybe could how it can be done. I don't it can be. Can you get in there and steal my stuff?

  • @dan677915 Basically, you are giving a point of access. Yes, it is insecure. Writing an answer now.

2 Answers

To simplify, if you need remote database access, you should use a VPN. There are several types. I recommend Tinc or OpenVPN. If you really really can't use a VPN, do not open the DB to the internet. Allow connections from set IP addresses in IPTables for that port. That way traffic to the DB is handled at the kernel level.
Also, you should enabled/setup MySQL/MariaDB's SSL to encrypt traffic between the database.

@jtittle's answer was better than this one though. Heart :)

  • @Zachary_DuBois - Thanks :-).

    Security is something I take very seriously. I've been the target of attacks and have had to help many control and mitigate others over the past 15 years. It's a PITA sometimes and even more so when someone doesn't bother setting things up right the first time (i.e they deploy an open server with a software firewall that isn't even turned on).

    With the advances in Cloud Hosting, deploying is easier than it ever has been though security, at the same time, is worse than it has ever been. The vast majority deploy with the mindset that whatever they deploy is going to be secure, require zero effort and will "just work" (pre-made images don't help as it furthers the assumption), when that's far from the case.

    Such a mindset may hold for a short while, especially on small instances that receive very very little traffic, though as long as it's open to the public, it should be labeled a target and instead of assuming it's secure, one should assume it will be attacked. Going in with that mindset gives you a whole new perspective when it comes to security :-).

    That said, I completely agree with @Zachary_DuBois - where possible, connect with a VPN. Unless the desktop/laptop you're connecting from is using other security measures to ensure outside connections are secure, assume they aren't and connect through a secure server (and I would recommend using your own VPN over a service unless said service allows you to connect from a local point, otherwise you'll be connecting from wherever they choose, which could be China, UK etc). If you use a service, ideally, you also want to make sure they aren't logging your traffic.

    • Zachary, I assume every possible attack will happen. What I am trying to find out what is really possible. I also am trying to blow the whistle on BS that everybody passes on to everyone else because everyone is saying it, so repeating it makes you part of the crowd.

      Your comments are not like that. Those attacks you had to deal with were real and their agony has generated a focus and sure knowledge this is easy to spot

      Regarding port 3306 where mysql is working as a remote server, can you think of a practical way to hack it?

      • @dan677915

        Regarding port 3306 where mysql is working as a remote server, can you think of a practical way to hack it?

        Sure :-), though out of respect for DigitalOcean, I'm not going to go over every last detail as I don't want someone actually trying this on another customer. If you'd like to discuss this further, feel free to shoot me an e-mail privately.

        hello -[at]- habanero.io
        

        Just remove the -[at]- and spaces and replace -[at]- with @ (small attempt at keeping the junk mail at bay).

        --

        That said, anyone could use NMAP, a network discovery & security auditing utility, to discover open ports, running services, OS version and quite a bit more. Toss a port in, get some information out (i.e. let's confirm what ports you have open).

        Combined with NMAP, one could use Metasploit, which can do a number of things ranging from scanning to attempting a brute force attack, all automated with very few configuration options needed to get it running (an attacker most likely would already have preset configurations ready to fire).

        Metasploit also has the ability to generate password lists, so it can fill it's own BF attack seamlessly. Beyond that, it can attempt to bypass MySQL authentication. If this is successful, the attacker would be able to gather up usernames and encrypted passwords. Yes, they are encrypted, but that doesn't really matter. They now have a username which is 50% of the equation.

        Once they have hashes, they can use other tools (that I'm not going to mention here as they can actually cause some real issues and I don't want others going after this for petty attempts at hacking someone else's Droplet). These tools will attempt to crack those hashes using a wide number of other tools, or functions in the primary tool.

        --

        Needless to say, given and hour or less, if you're not properly locking things down, you could be in trouble. As with anything requiring authentication, the smaller the password, the faster it'll be to crack.

        For this very reason, I would never rely on a password that you yourself can generate in a few seconds. Leave the password generation to something that can generate a somewhat secure password. OpenSSL for example.

        Using OpenSSL from the CLI, we could use:

        openssl rand -base64 64 | tr -d .=\+/
        

        To first generate a 64-Character string and then strip instances of =, /, \ and + out (which can sometimes cause issues, especially if you're automating this from a bash script).

        Sample Output:

        jLTYFg7SBOzmxxH8jLsA8zMs4hdDqEenBeETKqFqpGsZrfQ8dhXLmjuAWwbalU9B8FlnQopeF1zGW3dY6vQ
        
      • Well, for one, bots attempt to brute 3306 as it is the default MySQL/MariaDB port. Two, @jtittle just explained, brute forcing. You never open a database to the internet. And that is just standard security measures. There are unfixed CVE's in many packages distributed in repositories and anyone could use one to gain unauthorized access. You always prepare for the worst.

        About my answer, it was a shorter version of @jtittle for people that wanted a quick answer as you might not be the only one asking.

@dan677915

Opening up Port 3306 to the public is, indeed, asking for trouble. It's another port being exposed and it's another port that can be attacked (port 3306 is the default MySQL port - it's well know and it will be a port listed in any automated attack).

You can, however, use a firewall to limit who can connect (i.e. limit connections from only your local IP and your web server(s)), though ultimately, you should simply use a tool, such as phpMyAdmin or Adminer to manage database access (and limit access to this as well -- don't rely on basic password authentication through the script, use .htaccess to only allow your IP and then setup a username and password).

Even better, don't use a public IP or localhost to connect to MySQL, use a Private Network IP (which would be provided by DigitalOcean). You'll still need to setup firewall restrictions on the Private IP as well, though.

Ideally, you want to setup your firewall to deny all connections by default and then add rules that allow certain ports through, thus resulting in all connections being denied except to those which you specifically allow.

The most common ports you'll need to keep open are:

80 - TCP - for HTTP
443 - TCP - for HTTPS
22 - TCP - for SSH (swap 22 for your SSH port number if you've modified it)
53 - UDP - for DNS
53 - TCP - for DNS if you're running Bind (i.e. a DNS server)

This excludes mail server ports. I didn't list those simply because they often vary.

  • This is a great response with lots of detail. Let's stick with port 3306. I think it's a good idea to allow access only from certain IPs. I think it is a good idea to use a VPN intead of a remote connection from my app to the database on another server. Currently I am launching a custom membership app. It uses mysql for a lot of stuff. It's helpful to run mysql on a server that is separate from where the php files forming the app run, because then we can move it to any server without moving the database, and the membership software always calls home to the database. It's really nice to be able to copy and run a php app without having to reconfigure it everytime it's directory or server address changes

    I don't see how phpmyadmin comes into this

    Regarding ports that have to be kept open, what good does it do to close all the ports with a firewall when you are not using the ports anyway? And since some ports are let open, why can't hackers break in through them?

    • @dan677915

      I mentioned phpMyAdmin and Adminer as they are database management tools that are written in PHP (and you've tagged this post as LAMP). With these tools, you can access a database on a local or remote MySQL server and modify the contents of a database as it is needed. Of course, you could do this without either and opt for a direct route with PHP only (connect via PDO, execute the queries needed, etc).

      In regards to ports, much like Windows, whatever you don't lock down is wide open by default. OS's are designed for general purpose, so there's no way for an OS, by default, to know what ports you do and do not need open, or which ports you want to restrict access to. That's where solutions such as iptables come in to play and, as a result of the rather complex state of iptables, that's why ufw was created (as a wrapper around iptables to provide more simplified ways of modifying rules). Of course, these are only two solutions; there's dozens more.

      --

      For instance, let's take a standard Debian 8.x installation. If I deploy Debian 8.x to a fresh Droplet, all ports are open by default. There are no limitations in place and as long as I know how, I can connect to any of them in some way, shape or form. This is far from ideal, especially on a public facing server (i.e. a server that will allow the public to access and connect).

      Since I don't want the public to be able to connect wherever they'd like, I want to use a firewall to block access to all ports except those that I specifically allow. Why? There's no need to allow anyone to be able to connect to any port they'd like and further more, it is a security issue as there's always someone out there that's smarter than me.

      To lock down the server, thus preventing access to any and all ports, I'll first start by allowing my IP through and allowing SSH's Port (by default, Port 22), this way I won't be blocked and my connection won't drop in the midst of me working to add my rules. If I didn't whitelist my IP and the current SSH Port, should my connection drop, I'm locked out.

      Once these rules are in place, I'll implement a deny all rule and then proceed to only add allow rules indicating the ports that I specifically want others to be able to access.

      --

      For simplicity, I'll use UFW as an example here. UFW is pre-installed on Ubuntu, but not on Debian, so since I'm using Debian in this example, I need to install UFW.

      apt-get install -y ufw
      

      UFW is now installed, but not active (which is a good thing, we don't want to turn it on right now). So, as mentioned above, I'll add SSH first.

      ufw allow 22/tcp
      

      This tells UFW to allow connections on Port 22 using TCP, which is how we'd normally be connecting using Terminal, PuTTy etc.

      Now I need to add my IP address:

      ufw insert 1 allow from 0.0.0.0
      

      This tells UFW to allow connections from my IP (you'd replace 0.0.0.0 with your local IP, of course) and to place this rule at the very top of the list. Why? If this rule, for example, is at the bottom of the list and we've already set up our deny all rule, I'll still be denied as UFW (and iptables) follows rule order.

      Now that I'm safe and SSH is allowed, I'll now implement my deny all rule.

      ufw default deny incoming
      

      This tells UFW to set the default policy to deny all incoming connections, thus, connections on other ports will now be denied unless it's Port 22 and the connection is from my IP. Since this isn't ideal on a public server, and I plan on serving web content, and I need to be able to connect to update packages and software, I'll need to add ports that I want to allow connections to and from. This is where those Ports I mentioned above come in to play.

      I need to allow HTTP & HTTPS (for basic requests and secure requests).

      ufw allow 80/tcp
      ufw allow 443/tcp
      

      I also need to allow DNS to resolve from requests made internally. By this, I mean when we run apt-get update and apt-get upgrade. If we're blocking DNS, requests to repo's are not going to resolve. For internal connections, we need to allow DNS using UDP instead of TCP.

      ufw allow 53/udp
      

      Now, if we happen to be running a DNS server, such as Bind, on our Droplet, we'd also want to allow TCP for DNS.

      ufw allow 53/tcp
      

      With these rules in place, we're now allowing HTTP, HTTPS, SSH and DNS while denying access to anything else. Now I simply need to enable UFW.

      service ufw start
      

      You can now use

      ufw status
      

      To view which rules you've set and:

      ufw --help
      

      to view other actions that can be taken.

    • @dan677915

      In regards to some ports being open and the question of why can't hackers break through, it's not that they can't, it's a matter of how effective would it be to try and what happens when they try.

      A firewall is not the only solution. Ideally, you would also implement connection limits that prevent a single client from being able to make more than X connections per second. If they do, the client is flagged and added to a list that either blocks further connections for X minutes/hours or implements rate limiting (i.e. throttling, which then slows the rate of connections until they are under a threshold).

      This means that if I, as a client, attempt to connect to any server with such rules in place at a rate of 99 requests per second and server X is limiting connections to 10 connections per second, after I hit #10, the rest of my connections are either going to be blocked or heavily limited in terms of success rate, speed etc.

      For example, let's take a basic Brute Force attack as an example. These are automated attacks (as no one in their right mind would sit and try to do this manually). When a BF attack hits, it's trying to guess a password using a predefined list of commonly used and commonly exploited passwords. If these fail, it then tries a smarter approach to guessing based on whatever tables it's provided with. This can effectively kill connections to your server if you don't have something in place to block the overload as more than likely, the person(s) attacking are going to attempt to connect as quick and as often as possible, far surpassing the 99/CPS that I mentioned.

      If they are allowed to run their attack (even if they never successfully get in), you're going to run out of resources to serve additional requests. If you're on a HA setup, then all of your servers are going to end up being flooded as the HA proxy begins to serve from the next server in line until it runs out of servers to switch over to.

      Now you're down and they're just waiting for you to come back up to try again (and it will happen).

      You can either allow it, or do something about it. Of course, more than likely, they will be connecting from multiple IP's, so your block list is going to grow, though it's better to deal with a huge list of IP's in a table than it is to allow your service(s) to cause major issues for clients.

      --

      That said, if you do become the target of an attack, beyond these solutions, I'd get in touch with DigitalOcean ASAP. Since you do not have control over the hardware end, software solutions are what you're limited to. DigitalOcean could, however, work with you to implement something more effective in the short term.

      • Wow, this is quite the tutorial you have provided here, thank you!

        Regarding my question, what I am seeing mostly is a common sense perspective that says there are more secure connections than native mysql@port 3306, so anyone who is not a moron is going to use those other approaches because they are safer

Have another answer? Share your knowledge.