Chapter 8. MySQL Cluster Security Issues
Table of Contents
This section discusses security considerations to take into account when setting up and running MySQL Cluster.
Topics to be covered in this chapter include the following:
MySQL Cluster and network security issues
Configuration issues relating to running MySQL Cluster securely
MySQL Cluster and the MySQL privilege system
MySQL standard security procedures as applicable to MySQL Cluster
In this section, we discuss basic network security issues as they relate to MySQL Cluster. It is extremely important to remember that MySQL Cluster “out of the box” is not secure; you or your network administrator must take the proper steps to insure that your cluster cannot be compromised over the network.
Cluster communication protocols are inherently insecure, and no encryption or similar security measures are used in communications between nodes in the cluster. Because network speed and latency have a direct impact on the cluster's efficiency, it is also not advisable to employ SSL or other encryption to network connections between nodes, as such schemes will effectively slow communications.
It is also true that no authentication is used for controlling API node access to a MySQL Cluster. As with encryption, the overhead of imposing authentication requirements would have an adverse impact on Cluster performance.
In addition, there is no checking of the source IP address for either of the following when accessing the cluster:
SQL or API nodes using “free slots” created by empty
[mysqld]or[api]sections in theconfig.inifileThis means that, if there are any empty
[mysqld]or[api]sections in theconfig.inifile, then any API nodes (including SQL nodes) that know the management server's host name (or IP address) and port can connect to the cluster and access its data without restriction. (See Section 8.2, “MySQL Cluster and MySQL Privileges”, for more information about this and related issues.)Note
You can exercise some control over SQL and API node access to the cluster by specifying a
HostNameparameter for all[mysqld]and[api]sections in theconfig.inifile. However, this also means that, should you wish to connect an API node to the cluster from a previously unused host, you need to add an[api]section containing its host name to theconfig.inifile.More information is available elsewhere in this chapter about the
HostNameparameter. Also see Section 3.3, “Quick Test Setup of MySQL Cluster”, for configuration examples usingHostNamewith API nodes.Any ndb_mgm client
This means that any cluster management client that is given the management server's host name (or IP address) and port (if not the standard port) can connect to the cluster and execute any management client command. This includes commands such as
ALL STOPandSHUTDOWN.
For these reasons, it is necessary to protect the cluster on the network level. The safest network configuration for Cluster is one which isolates connections between Cluster nodes from any other network communications. This can be accomplished by any of the following methods:
Keeping Cluster nodes on a network that is physically separate from any public networks. This option is the most dependable; however, it is the most expensive to implement.
We show an example of a MySQL Cluster setup using such a physically segregated network here:

This setup has two networks, one private (solid box) for the Cluster management servers and data nodes, and one public (dotted box) where the SQL nodes reside. (We show the management and data nodes connected using a gigabit switch since this provides the best performance.) Both networks are protected from the outside by a hardware firewall, sometimes also known as a network-based firewall.
This network setup is safest because no packets can reach the cluster's management or data nodes from outside the network — and none of the cluster's internal communications can reach the outside — without going through the SQL nodes, as long as the SQL nodes do not allow any packets to be forwarded. This means, of course, that all SQL nodes must be secured against hacking attempts.
Important
With regard to potential security vulnerabilities, an SQL node is no different from any other MySQL server. See Making MySQL Secure Against Attackers, for a description of techniques you can use to secure MySQL servers.
Using one or more software firewalls (also known as host-based firewalls) to control which packets pass through to the cluster from portions of the network that do not require access to it. In this type of setup, a software firewall must be installed on every host in the cluster which might otherwise be accessible from outside the local network.
The host-based option is the least expensive to implement, but relies purely on software to provide protection and so is the most difficult to keep secure.
This type of network setup for MySQL Cluster is illustrated here:

Using this type of network setup means that there are two zones of MySQL Cluster hosts. Each cluster host must be able to communicate with all of the other machines in the cluster, but only those hosting SQL nodes (dotted box) can be permitted to have any contact with the outside, while those in the zone containing the data nodes and management nodes (solid box) must be isolated from any machines that are not part of the cluster. Applications using the cluster and user of those applications must not be permitted to have direct access to the management and data node hosts.
To accomplish this, you must set up software firewalls that limit the traffic to the type or types shown in the following table, according to the type of node that is running on each cluster host computer:
Type of Node to be Accessed Traffic to Allow SQL or API node It originates from the IP address of a management or data node (using any TCP or UDP port).
It originates from within the network in which the cluster resides and is on the port that your application is using.
Data node or Management node It originates from the IP address of a management or data node (using any TCP or UDP port).
It originates from the IP address of an SQL or API node.
Any traffic other than that shown in the table for a given node type should be denied.
The specifics of configuring a firewall vary from firewall application to firewall application, and are beyond the scope of this Manual. iptables is a very common and reliable firewall application, which is often used with APF as a front end to make configuration easier. You can (and should) consult the documentation for the software firewall that you employ, should you choose to implement a MySQL Cluster network setup of this type, or of a “mixed” type as discussed under the next item.
It is also possible to employ a combination of the first two methods, using both hardware and software to secure the cluster — that is, using both network-based and host-based firewalls. This is between the first two schemes in terms of both security level and cost. This type of network setup keeps the cluster behind the hardware firewall, but allows incoming packets to travel beyond the router connecting all cluster hosts in order to reach the SQL nodes.
One possible network deployment of a MySQL Cluster using hardware and software firewalls in combination is shown here:

In this case, you can set the rules in the hardware firewall to deny any external traffic except to SQL nodes and API nodes, and then allow traffic to them only on the ports required by your application.
Whatever network configuration you use, remember that your objective from the viewpoint of keeping the cluster secure remains the same — to prevent any unessential traffic from reaching the cluster while ensuring the most efficient communication between the nodes in the cluster.
Because MySQL Cluster requires large numbers of ports to be open for communications between nodes, the recommended option is to use a segregated network. This represents the simplest way to prevent unwanted traffic from reaching the cluster.
Note
If you wish to administer a MySQL Cluster remotely (that is, from outside the local network), the recommended way to do this is to use ssh or another secure login shell to access an SQL node host. From this host, you can then run the management client to access the management server safely, from within the Cluster's own local network.
Even though it is possible to do so in theory, it is not recommended to use ndb_mgm to manage a Cluster directly from outside the local network on which the Cluster is running. Since neither authentication nor encryption takes place between the management client and the management server, this represents an extremely insecure means of managing the cluster, and is almost certain to be compromised sooner or later.
In this section, we discuss how the MySQL privilege system works in relation to MySQL Cluster and the implications of this for keeping a MySQL Cluster secure.
Standard MySQL privileges apply to MySQL Cluster tables. This
includes all MySQL privilege types
(SELECT privilege,
UPDATE privilege,
DELETE privilege, and so on)
granted on the database, table, and column level. As with any
other MySQL Server, user and privilege information is stored in
the mysql system database. The SQL statements
used to grant and revoke privileges on
NDB tables, databases containing such
tables, and columns within such tables are identical in all
respects with the GRANT and
REVOKE statements used in
connection with database objects involving any (other) MySQL
storage engine. The same thing is true with respect to the
CREATE USER and
DROP USER statements.
It is important to keep in mind that the MySQL grant tables use
the MyISAM storage engine. Because of this,
those tables are not duplicated or shared among MySQL servers
acting as SQL nodes in a MySQL Cluster. By way of example, suppose
that two SQL nodes A and
B are connected to the same MySQL
Cluster, which has an NDB table named
mytable in a database named
mydb, and that you execute an SQL statement on
server A that creates a new user
jon@localhost and grants this user the
SELECT privilege on that table:
mysql>GRANT SELECT ON mydb.mytable->TO jon@localhost IDENTIFIED BY 'mypass';
This user is not created on server B. In order for this to take place, the statement must also be run on server B. Similarly, statements run on server A and affecting the privileges of existing users on server A do not affect users on server B unless those statements are actually run on server B as well.
In other words, changes in users and their privileges do not automatically propagate between SQL nodes. Synchronization of privileges between SQL nodes must be done either manually or by scripting an application that periodically synchronizes the privilege tables on all SQL nodes in the cluster.
Conversely, because there is no way in MySQL to deny privileges
(privileges can either be revoked or not granted in the first
place, but not denied as such), there is no special protection for
NDB tables on one SQL node from users
that have privileges on another SQL node. The most far-reaching
example of this is the MySQL root account,
which can perform any action on any database object. In
combination with empty [mysqld] or
[api] sections of the
config.ini file, this account can be
especially dangerous. To understand why, consider the following
scenario:
The
config.inifile contains at least one empty[mysqld]or[api]section. This means that the Cluster management server performs no checking of the host from which a MySQL Server (or other API node) accesses the MySQL Cluster.There is no firewall, or the firewall fails to protect against access to the Cluster from hosts external to the network.
The host name or IP address of the Cluster's management server is known or can be determined from outside the network.
If these conditions are true, then anyone, anywhere can start a
MySQL Server with --ndbcluster
--ndb-connectstring=
and access the Cluster. Using the MySQL management_hostroot
account, this person can then perform the following actions:
Execute a
SHOW DATABASESstatement to obtain a list of all databases that exist in the clusterExecute a
SHOW TABLES FROMstatement to obtain a list of allsome_databaseNDBtables in a given databaseRun any legal MySQL statements on any of those tables, such as:
SELECT * FROMto read all the data from any tablesome_tableDELETE FROMto delete all the data from a tablesome_tableDESCRIBEorsome_tableSHOW CREATE TABLEto determine the table schemasome_tableUPDATEto fill a table column with “garbage” data; this could actually cause much greater damage than simply deleting all the datasome_tableSETcolumn1=any_value1Even more insidious variations might include statements like these:
UPDATE
some_tableSETan_int_column=an_int_column+ 1or
UPDATE
some_tableSETa_varchar_column= REVERSE(a_varchar_column)Such malicious statements are limited only by the imagination of the attacker.
The only tables that would be safe from this sort of mayhem would be those tables that were created using storage engines other than
NDB, and so not visible to a “rogue” SQL node.Note
A user who can log in as
rootcan also access theINFORMATION_SCHEMAdatabase and its tables, and so obtain information about databases, tables, stored routines, scheduled events, and any other database objects for which metadata is stored inINFORMATION_SCHEMA.It is also a very good idea to use different passwords for the
rootaccounts on different cluster SQL nodes.
In sum, you cannot have a safe MySQL Cluster if it is directly accessible from outside your local network.
Important
Never leave the MySQL root account password empty. This is just as true when running MySQL as a MySQL Cluster SQL node as it is when running it as a standalone (non-Cluster) MySQL Server, and should be done as part of the MySQL installation process before configuring the MySQL Server as an SQL node in a MySQL Cluster.
You should never convert the system tables in the
mysql database to use the
NDB storage engine. There are a
number of reasons why you should not do this, but the most
important reason is this: Many of the SQL statements
that affect mysql tables storing information
about user privileges, stored routines, scheduled events, and
other database objects cease to function if these tables are
changed to use any storage engine other than
MyISAM. This is a consequence of
various MySQL Server internals which are not expected to change in
the foreseeable future.
If you need to synchronize mysql system tables
between SQL nodes, you can use standard MySQL replication to do
so, or employ a script to copy table entries between the MySQL
servers.
Summary. The two most important points to remember regarding the MySQL privilege system with regard to MySQL Cluster are:
Users and privileges established on one SQL node do not automatically exist or take effect on other SQL nodes in the cluster.
Conversely, removing a user or privilege on one SQL node in the cluster does not remove the user or privilege from any other SQL nodes.
Once a MySQL user is granted privileges on an
NDBtable from one SQL node in a MySQL Cluster, that user can “see” any data in that table regardless of the SQL node from which the data originated.
In this section, we discuss MySQL standard security procedures as they apply to running MySQL Cluster.
In general, any standard procedure for running MySQL securely also
applies to running a MySQL Server as part of a MySQL Cluster.
First and foremost, you should always run a MySQL Server as the
mysql system user; this is no different from
running MySQL in a standard (non-Cluster) environment. The
mysql system account should be uniquely and
clearly defined. Fortunately, this is the default behavior for a
new MySQL installation. You can verify that the
mysqld process is running as the system user
mysql by using the system command such as the
one shown here:
shell> ps aux | grep mysql
root 10467 0.0 0.1 3616 1380 pts/3 S 11:53 0:00 \
/bin/sh ./mysqld_safe --ndbcluster --ndb-connectstring=localhost:1186
mysql 10512 0.2 2.5 58528 26636 pts/3 Sl 11:53 0:00 \
/usr/local/mysql/libexec/mysqld --basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/var --user=mysql --ndbcluster \
--ndb-connectstring=localhost:1186 --pid-file=/usr/local/mysql/var/mothra.pid \
--log-error=/usr/local/mysql/var/mothra.err
jon 10579 0.0 0.0 2736 688 pts/0 S+ 11:54 0:00 grep mysql
If the mysqld process is running as any other
user than mysql, you should immediately shut it
down and restart it as the mysql user. If this
user does not exist on the system, the mysql
user account should be created, and this user should be part of
the mysql user group; in this case, you should
also make sure that the MySQL DataDir on this
system is owned by the mysql user, and that the
SQL node's my.cnf file includes
user=mysql in the [mysqld]
section. Alternatively, you can start the server with
--user=mysql on the command line, but it is
preferable to use the my.cnf option, since
you might forget to use the command-line option and so have
mysqld running as another user unintentionally.
The mysqld_safe startup script forces MySQL to
run as the mysql user.
Important
Never run mysqld as the system root user. Doing so means that potentially any file on the system can be read by MySQL, and thus — should MySQL be compromised — by an attacker.
As mentioned in the previous section (see Section 8.2, “MySQL Cluster and MySQL Privileges”), you should always set a root password for the MySQL Server as soon as you have it running. You should also delete the anonymous user account that is installed by default. You can accomplish these tasks via the following statements:
shell>mysql -u rootmysql>UPDATE mysql.user->SET Password=PASSWORD('->secure_password')WHERE User='root';mysql>DELETE FROM mysql.user->WHERE User='';mysql>FLUSH PRIVILEGES;
Be very careful when executing the
DELETE statement not to omit the
WHERE clause, or you risk deleting
all MySQL users. Be sure to run the
FLUSH PRIVILEGES
statement as soon as you have modified the
mysql.user table, so that the changes take
immediate effect. Without
FLUSH PRIVILEGES,
the changes do not take effect until the next time that the server
is restarted.
Note
Many of the MySQL Cluster utilities such as
ndb_show_tables, ndb_desc,
and ndb_select_all also work without
authentication and can reveal table names, schemas, and data. By
default these are installed on Unix-style systems with the
permissions wxr-xr-x (755), which means they
can be executed by any user that can access the
mysql/bin directory.
See Chapter 6, MySQL Cluster Programs, for more information about these utilities.
