May 06, 2015

Application Servers and MySQL

Securely connect your application server to a remote MySQL server! We'll cover firewalls, networking binding and user security within MySQL.

This will explain the parts you need to know about MySQL to connect remotely without sacrificing security.

^ Ad space to help offset hosting costs :D

Securely connect your application server to a remote MySQL server! We'll cover firewalls, networking binding and user security within MySQL.

This will explain the parts you need to know about MySQL to connect remotely without sacrificing security.Here's the basic things standing in our way of connecting to a remote MySQL server:

  • AWS security Rules, if you're using AWS
  • Firewall rules on both servers (Notably the INPUT chain on the MySQL server)
  • MySQL's Bind Address (what network it's listening on)
  • MySQL User allowed to be used for remote connections

Firewalls

Assuming AWS rules are all set (that's shown in the video but outside the scope of it), let's start with the Firewalls.

We need to ensure the MySQL server allows incoming connections on MySQL's port 3306. Let's open up port 3306 to allow those connections through.

Here are the commands used to create the current firewall rules on the MySQL server:

sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -j DROP

To add onto this rules and allow incoming requests on port 3306, we can do the following:

sudo iptables -I INPUT 4 -p tcp --dport 3306 -j ACCEPT

However, let's make this more secure and only allow these incoming requests from a specific IP address (our application server):

sudo iptables -I INPUT 4 -p tcp -s 173.10.0.22 --dport 3306 -j ACCEPT

Where -s is the --source IP address (your application server).

See the Security series to learn more about Firewalls

MySQL Bind Address

MySQL needs to listen on the network being connected to. This means editing the bind-address parameter in the my.cnf file (/etc/mysql/my.cnf in Ubuntu/Debian).

By default, bind-address will default to localhost or 127.0.0.1. To allow remote connections, we can have MySQL do a few things:

Listen on all network interfaces

; Comment bind-address out, as it defaults to 0.0.0.0
; bind-address = 'localhost'

; Or set bind-address to 0.0.0.0 explicitly
bind-address = '0.0.0.0'

Listen on specific network interface

bind-address 192.168.33.10

If you bind to a specific address, you'll need to connect to it using that host when connecting from a remote server:

mysql -h 192.168.33.10 -u some_user -p

MySQL User

Lastly we need a user that can be connected to. MySQL users are created per host. The host can be a wildcard (any host) % or a specific host, such as localhost or perhaps the IP address of your application server at 192.169.33.11. We'll create a user that can be connected from a remote host - our application server.

Note, I'll grant all privileges to his user when connected from all hosts. You may want to be more restrictive.

Here's what it would look like if creating a user who can be connected to from anywhere:

CREATE USER 'your_user'@'%' IDENTIFIED BY 'some_secure_password';
GRANT ALL PRIVILEGES on your_db.* TO 'your_user'@'%';

Here's what it would look like if creating a user who can be connected to from a specific host, and with specific [grant permissions](https://dev.mysql.com/doc/refman/5.6/en/grant.html:

CREATE USER 'your_user'@'192.168.33.11' IDENTIFIED BY 'some_secure_password';
GRANT SELECT, DELETE, UPDATE, INSERT, INDEX, LOCK TABLES on your_db.* TO 'your_user'@'192.168.33.11';

In our case, we'll do a mix:

CREATE USER 'your_user'@'192.168.33.11' IDENTIFIED BY 'some_secure_password';
GRANT  ALL PRIVILEGES on your_db.* TO 'your_user'@'192.168.33.11';

Here's more information on grants needed for mysqldump here.

We should be all set after these changes. We can now log into our application server and attempt to login to the MySQL server!

Side note, If you're interested in a service to help you manage MySQL-optimized, backup and (eventually) replication-enabled database servers, sign up here to let me know! The idea is to allow you to better manage your MySQL servers, taking advantage of many of MySQL's more advanced options, especially around backup and recovery.

All Topics