Table of Contents
This section describes how to set up accounts for clients of your MySQL server. It discusses the following topics:
The meaning of account names and passwords as used in MySQL and how that compares to names and passwords used by your operating system
How to set up new accounts and remove existing accounts
How to change passwords
Guidelines for using passwords securely
How to use secure connections
See also Account Management Statements, which describes the syntax and use for all user-management SQL statements.
MySQL stores accounts in the user table of the
mysql system database. An account is defined in
terms of a user name and the client host or hosts from which the
user can connect to the server. For information about account
representation in the user table, see
Section 4.2, “Grant Tables”.
The account may also have a password. MySQL supports authentication plugins, so it is possible that an account authenticates using some external authentication method. See Section 5.8, “Pluggable Authentication”.
There are several distinctions between the way user names and passwords are used by MySQL and your operating system:
User names, as used by MySQL for authentication purposes, have
nothing to do with user names (login names) as used by Windows
or Unix. On Unix, most MySQL clients by default try to log in
using the current Unix user name as the MySQL user name, but
that is for convenience only. The default can be overridden
easily, because client programs permit any user name to be
specified with a -u or
--user option. This means that anyone can
attempt to connect to the server using any user name, so you
cannot make a database secure in any way unless all MySQL
accounts have passwords. Anyone who specifies a user name for
an account that has no password is able to connect
successfully to the server.
MySQL user names can be up to 32 characters long (16 characters before MySQL 5.7.8). Operating system user names may be of a different maximum length. For example, Unix user names typically are limited to eight characters.
The limit on MySQL user name length is hardcoded in MySQL
servers and clients, and trying to circumvent it by
modifying the definitions of the tables in the
mysql database does not
work.
You should never alter the structure of tables in the
mysql database in any manner whatsoever
except by means of the procedure that is described in
mysql_upgrade — Check and Upgrade MySQL Tables. Attempting to redefine
MySQL's system tables in any other fashion results in
undefined (and unsupported!) behavior. The server is free to
ignore rows that become malformed as a result of such
modifications.
To authenticate client connections for accounts that use MySQL
native authentication (implemented by the
mysql_native_password authentication
plugin), the server uses passwords stored in the
user table. These passwords are distinct
from passwords for logging in to your operating system. There
is no necessary connection between the “external”
password you use to log in to a Windows or Unix machine and
the password you use to access the MySQL server on that
machine.
If the server authenticates a client using some other plugin,
the authentication method that the plugin implements may or
may not use a password stored in the user
table. In this case, it is possible that an external password
is also used to authenticate to the MySQL server.
Passwords stored in the user table are
encrypted using plugin-specific algorithms. For information
about MySQL native password hashing, see
Section 2.2.4, “Password Hashing in MySQL”.
If the user name and password contain only ASCII characters,
it is possible to connect to the server regardless of
character set settings. To connect when the user name or
password contain non-ASCII characters, the client should call
the mysql_options() C API
function with the MYSQL_SET_CHARSET_NAME
option and appropriate character set name as arguments. This
causes authentication to take place using the specified
character set. Otherwise, authentication will fail unless the
server default character set is the same as the encoding in
the authentication defaults.
Standard MySQL client programs support a
--default-character-set option that causes
mysql_options() to be called
as just described. In addition, character set autodetection is
supported as described in
Connection Character Sets and Collations. For programs that use a
connector that is not based on the C API, the connector may
provide an equivalent to
mysql_options() that can be
used instead. Check the connector documentation.
The preceding notes do not apply for ucs2,
utf16, and utf32, which
are not permitted as client character sets.
The MySQL installation process populates the grant tables with an
initial root account, as described in
Section 3.4, “Securing the Initial MySQL Accounts”, which also discusses how to
assign passwords to it. Thereafter, you normally set up, modify,
and remove MySQL accounts using statements such as
CREATE USER,
DROP USER,
GRANT, and
REVOKE. See
Account Management Statements.
To connect to a MySQL server with a command-line client, specify user name and password options as necessary for the account that you want to use:
shell> mysql --user=finley --password db_name
If you prefer short options, the command looks like this:
shell> mysql -u finley -p db_name
If you omit the password value following the
--password or -p
option on the command line (as just shown), the client prompts for
one. Alternatively, the password can be specified on the command
line:
shell>mysql --user=finley --password=shell>passworddb_namemysql -u finley -ppassworddb_name
If you use the -p option, there must be
no space between -p and the
following password value.
Specifying a password on the command line should be considered insecure. See Section 2.2.1, “End-User Guidelines for Password Security”. You can use an option file or a login path file to avoid giving the password on the command line. See Using Option Files, and mysql_config_editor — MySQL Configuration Utility.
For additional information about specifying user names, passwords, and other connection parameters, see Connecting to the MySQL Server.
You can create MySQL accounts two ways:
By using account-management statements intended for creating
accounts and establishing their privileges, such as
CREATE USER and
GRANT. These statements cause
the server to make appropriate modifications to the underlying
grant tables.
By manipulating the MySQL grant tables directly with
statements such as INSERT,
UPDATE, or
DELETE.
The preferred method is to use account-management statements because they are more concise and less error-prone than manipulating the grant tables directly. All such statements are described in Account Management Statements. Direct grant table manipulation is discouraged, and is not described here. The server is free to ignore rows that become malformed as a result of such modifications.
Another option for creating accounts is to use the GUI tool
MySQL Workbench. Also, several third-party programs offer capabilities
for MySQL account administration. phpMyAdmin is
one such program.
The following examples show how to use the
mysql client program to set up new accounts.
These examples assume that privileges have been set up according
to the defaults described in Section 3.4, “Securing the Initial MySQL Accounts”.
This means that to make changes, you must connect to the MySQL
server as the MySQL root user, which has the
CREATE USER privilege.
First, use the mysql program to connect to the
server as the MySQL root user:
shell> mysql --user=root mysql
If you have assigned a password to the root
account, you must also supply a --password or
-p option.
After connecting to the server as root, you can
add new accounts. The following example uses
CREATE USER and
GRANT statements to set up four
accounts:
mysql>CREATE USER 'finley'@'localhost' IDENTIFIED BY 'some_pass';mysql>GRANT ALL PRIVILEGES ON *.* TO 'finley'@'localhost'->WITH GRANT OPTION;mysql>CREATE USER 'finley'@'%' IDENTIFIED BY 'some_pass';mysql>GRANT ALL PRIVILEGES ON *.* TO 'finley'@'%'->WITH GRANT OPTION;mysql>CREATE USER 'admin'@'localhost' IDENTIFIED BY 'admin_pass';mysql>GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';mysql>CREATE USER 'dummy'@'localhost';
The accounts created by those statements have the following properties:
Two accounts have a user name of finley and
a password of some_pass. Both are superuser
accounts with full privileges to do anything. The
'finley'@'localhost' account can be used
only when connecting from the local host. The
'finley'@'%' account uses the
'%' wildcard for the host part, so it can
be used to connect from any host.
The 'finley'@'localhost' account is
necessary if there is an anonymous-user account for
localhost. Without the
'finley'@'localhost' account, that
anonymous-user account takes precedence when
finley connects from the local host and
finley is treated as an anonymous user. The
reason for this is that the anonymous-user account has a more
specific Host column value than the
'finley'@'%' account and thus comes earlier
in the user table sort order.
(user table sorting is discussed in
Section 4.4, “Access Control, Stage 1: Connection Verification”.)
The 'admin'@'localhost' account has a
password of admin_pass. This account can be
used only by admin to connect from the
local host. It is granted the
RELOAD and
PROCESS administrative
privileges. These privileges enable the
admin user to execute the
mysqladmin reload, mysqladmin
refresh, and mysqladmin
flush-xxx commands, as
well as mysqladmin processlist . No
privileges are granted for accessing any databases. You could
add such privileges using GRANT
statements.
The 'dummy'@'localhost' account has no
password (which is insecure and not recommended). This account
can be used only to connect from the local host. No privileges
are granted. It is assumed that you will grant specific
privileges to the account using
GRANT statements.
To see the privileges for an account, use
SHOW GRANTS:
mysql> SHOW GRANTS FOR 'admin'@'localhost';
+-----------------------------------------------------+
| Grants for admin@localhost |
+-----------------------------------------------------+
| GRANT RELOAD, PROCESS ON *.* TO 'admin'@'localhost' |
+-----------------------------------------------------+
To see nonprivilege properties for an account, use
SHOW CREATE USER:
mysql> SHOW CREATE USER 'admin'@'localhost'\G
*************************** 1. row ***************************
CREATE USER for admin@localhost: CREATE USER 'admin'@'localhost'
IDENTIFIED WITH 'mysql_native_password'
AS '*67ACDEBDAB923990001F0FFB017EB8ED41861105'
REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK
The next examples create three accounts and grant them access to
specific databases. Each of them has a user name of
custom and password of
obscure:
mysql>CREATE USER 'custom'@'localhost' IDENTIFIED BY 'obscure';mysql>GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP->ON bankaccount.*->TO 'custom'@'localhost';mysql>CREATE USER 'custom'@'host47.example.com' IDENTIFIED BY 'obscure';mysql>GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP->ON expenses.*->TO 'custom'@'host47.example.com';mysql>CREATE USER 'custom'@'%.example.com' IDENTIFIED BY 'obscure';mysql>GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP->ON customer.*->TO 'custom'@'%.example.com';
The three accounts can be used as follows:
The first account can access the
bankaccount database, but only from the
local host.
The second account can access the expenses
database, but only from the host
host47.example.com.
The third account can access the customer
database, from any host in the example.com
domain. This account has access from all machines in the
domain due to use of the “%”
wildcard character in the host part of the account name.
To remove an account, use the DROP
USER statement, which is described in
DROP USER Syntax. For example:
mysql> DROP USER 'jeffrey'@'localhost';
One means of restricting client use of MySQL server resources is
to set the global
max_user_connections system
variable to a nonzero value. This limits the number of
simultaneous connections that can be made by any given account,
but places no limits on what a client can do once connected. In
addition, setting
max_user_connections does not
enable management of individual accounts. Both types of control
are of interest to MySQL administrators.
To address such concerns, MySQL permits limits for individual accounts on use of these server resources:
The number of queries an account can issue per hour
The number of updates an account can issue per hour
The number of times an account can connect to the server per hour
The number of simultaneous connections to the server by an account
Any statement that a client can issue counts against the query limit, unless its results are served from the query cache. Only statements that modify databases or tables count against the update limit.
An “account” in this context corresponds to a row in
the mysql.user table. That is, a connection is
assessed against the User and
Host values in the user
table row that applies to the connection. For example, an account
'usera'@'%.example.com' corresponds to a row in
the user table that has User
and Host values of usera and
%.example.com, to permit
usera to connect from any host in the
example.com domain. In this case, the server
applies resource limits in this row collectively to all
connections by usera from any host in the
example.com domain because all such connections
use the same account.
Before MySQL 5.0.3, an “account” was assessed against
the actual host from which a user connects. This older method of
accounting may be selected by starting the server with the
--old-style-user-limits option. In
this case, if usera connects simultaneously
from host1.example.com and
host2.example.com, the server applies the
account resource limits separately to each connection. If
usera connects again from
host1.example.com, the server applies the
limits for that connection together with the existing connection
from that host.
To establish resource limits for an account at account-creation
time, use the CREATE USER
statement. To modify the limits for an existing account, use
ALTER USER. (Before MySQL 5.7.6,
use GRANT, for new or existing
accounts.) Provide a WITH clause that names
each resource to be limited. The default value for each limit is
zero (no limit). For example, to create a new account that can
access the customer database, but only in a
limited fashion, issue these statements:
mysql>CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank'->WITH MAX_QUERIES_PER_HOUR 20->MAX_UPDATES_PER_HOUR 10->MAX_CONNECTIONS_PER_HOUR 5->MAX_USER_CONNECTIONS 2;
The limit types need not all be named in the
WITH clause, but those named can be present in
any order. The value for each per-hour limit should be an integer
representing a count per hour. For
MAX_USER_CONNECTIONS, the limit is an integer
representing the maximum number of simultaneous connections by the
account. If this limit is set to zero, the global
max_user_connections system
variable value determines the number of simultaneous connections.
If max_user_connections is also
zero, there is no limit for the account.
To modify limits for an existing account, use an
ALTER USER statement. The following
statement changes the query limit for francis
to 100:
mysql> ALTER USER 'francis'@'localhost' WITH MAX_QUERIES_PER_HOUR 100;
The statement modifies only the limit value specified and leaves the account otherwise unchanged.
To remove a limit, set its value to zero. For example, to remove
the limit on how many times per hour francis
can connect, use this statement:
mysql> ALTER USER 'francis'@'localhost' WITH MAX_CONNECTIONS_PER_HOUR 0;
As mentioned previously, the simultaneous-connection limit for an
account is determined from the
MAX_USER_CONNECTIONS limit and the
max_user_connections system
variable. Suppose that the global
max_user_connections value is 10
and three accounts have individual resource limits specified as
follows:
ALTER USER 'user1'@'localhost' WITH MAX_USER_CONNECTIONS 0; ALTER USER 'user2'@'localhost' WITH MAX_USER_CONNECTIONS 5; ALTER USER 'user3'@'localhost' WITH MAX_USER_CONNECTIONS 20;
user1 has a connection limit of 10 (the global
max_user_connections value)
because it has a MAX_USER_CONNECTIONS limit of
zero. user2 and user3 have
connection limits of 5 and 20, respectively, because they have
nonzero MAX_USER_CONNECTIONS limits.
The server stores resource limits for an account in the
user table row corresponding to the account.
The max_questions,
max_updates, and
max_connections columns store the per-hour
limits, and the max_user_connections column
stores the MAX_USER_CONNECTIONS limit. (See
Section 4.2, “Grant Tables”.)
Resource-use counting takes place when any account has a nonzero limit placed on its use of any of the resources.
As the server runs, it counts the number of times each account uses resources. If an account reaches its limit on number of connections within the last hour, the server rejects further connections for the account until that hour is up. Similarly, if the account reaches its limit on the number of queries or updates, the server rejects further queries or updates until the hour is up. In all such cases, the server issues appropriate error messages.
Resource counting occurs per account, not per client. For example, if your account has a query limit of 50, you cannot increase your limit to 100 by making two simultaneous client connections to the server. Queries issued on both connections are counted together.
The current per-hour resource-use counts can be reset globally for all accounts, or individually for a given account:
To reset the current counts to zero for all accounts, issue a
FLUSH
USER_RESOURCES statement. The counts also can be
reset by reloading the grant tables (for example, with a
FLUSH
PRIVILEGES statement or a mysqladmin
reload command).
The counts for an individual account can be reset to zero by setting any of its limits again. Specify a limit value equal to the value currently assigned to the account.
Per-hour counter resets do not affect the
MAX_USER_CONNECTIONS limit.
All counts begin at zero when the server starts. Counts do not carry over through server restarts.
For the MAX_USER_CONNECTIONS limit, an edge
case can occur if the account currently has open the maximum
number of connections permitted to it: A disconnect followed
quickly by a connect can result in an error
(ER_TOO_MANY_USER_CONNECTIONS or
ER_USER_LIMIT_REACHED) if the
server has not fully processed the disconnect by the time the
connect occurs. When the server finishes disconnect processing,
another connection will once more be permitted.
Required credentials for clients that connect to the MySQL server can include a password. This section describes how to assign passwords for MySQL accounts.
MySQL stores passwords in the user table in the
mysql system database. Operations that assign
or modify passwords are permitted only to users with the
CREATE USER privilege, or,
alternatively, privileges for the mysql
database (INSERT privilege to
create new accounts, UPDATE
privilege to modify existing accounts). If the
read_only system variable is
enabled, use of account-modification statements such as
CREATE USER or
SET PASSWORD additionally requires
the SUPER privilege.
The discussion here summarizes syntax only for the most common password-assignment statements. For complete details on other possibilities, see CREATE USER Syntax, ALTER USER Syntax, GRANT Syntax, and SET PASSWORD Syntax.
MySQL hashes passwords stored in the mysql.user
table to obfuscate them. For most statements described here, MySQL
automatically hashes the password specified. An exception is
SET PASSWORD ... =
PASSWORD(', for
which you use the auth_string')PASSWORD()
function explicitly to hash the password. There are also syntaxes
for CREATE USER,
ALTER USER,
GRANT, and SET
PASSWORD that permit hashed values to be specified
literally; for details, see the descriptions of those statements.
MySQL uses plugins to perform client authentication; see Section 5.8, “Pluggable Authentication”. The authentication plugin associated with an account determines the algorithm used to hash passwords for that account.
To assign a password when you create a new account, use
CREATE USER and include an
IDENTIFIED BY clause:
mysql>CREATE USER 'jeffrey'@'localhost'->IDENTIFIED BY 'mypass';
For this CREATE USER syntax, MySQL
automatically hashes the password before storing it in the
mysql.user table.
CREATE USER also supports syntax
for specifying the account authentication plugin. See
CREATE USER Syntax.
To assign or change a password for an existing account, use one of the following methods:
Use the ALTER USER statement
with an IDENTIFIED BY clause:
mysql>ALTER USER 'jeffrey'@'localhost'->IDENTIFIED BY 'mypass';
If you are not connected as an anonymous user, you can change your own password without naming your own account literally:
mysql>ALTER USER USER()->IDENTIFIED BY 'mypass';
For these ALTER USER syntaxes,
MySQL automatically hashes the password before storing it in
the mysql.user table.
ALTER USER syntax for changing
passwords is available as of MySQL 5.7.6.
Use SET PASSWORD with the
PASSWORD() function:
mysql>SET PASSWORD FOR->'jeffrey'@'localhost' = PASSWORD('mypass');
If you are not connected as an anonymous user, you can change
your own password by omitting the FOR
clause:
mysql> SET PASSWORD = PASSWORD('mypass');
The PASSWORD() function hashes
the password using the hashing method determined by the value
of the old_passwords system
variable value. If SET PASSWORD
rejects the hashed password value returned by
PASSWORD() as not being in the
correct format, it may be necessary to change
old_passwords to change the
hashing method. See SET PASSWORD Syntax.
Use of SET
PASSWORD ... =
PASSWORD('
for password modification is deprecated as of MySQL 5.7.6.
Use auth_string')ALTER USER instead.
Use SET PASSWORD without the
PASSWORD() function:
For this syntax, the meaning differs in MySQL 5.7.6 and higher from earlier versions:
As of MySQL 5.7.6, SET
PASSWORD interprets the string as a cleartext
string and hashes it appropriately for the account
authentication plugin before storing it in the
mysql.user account row.
mysql>SET PASSWORD FOR->'jeffrey'@'localhost' = 'mypass';
Before MySQL 5.7.6, SET
PASSWORD interprets the string as a hashed
password value to be stored directly.
mysql>SET PASSWORD FOR->'jeffrey'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';
The string must be hashed in the format required by the
account authentication plugin. A string not hashed
appropriately causes client connections for the account to
fail with an Access denied error.
Use a GRANT
USAGE statement at the global level (ON
*.*) to change an account password without affecting
the account's current privileges:
mysql>GRANT USAGE ON *.* TO 'jeffrey'@'localhost'->IDENTIFIED BY 'mypass';
For this GRANT syntax, MySQL
automatically hashes the password before storing it in the
mysql.user table.
Use of GRANT for password
modification is deprecated as of MySQL 5.7.6. Use
ALTER USER instead.
To change an account password from the command line, use the mysqladmin command:
shell> mysqladmin -u user_name -h host_name password "new_password"
The account for which this command sets the password is the
one with a mysql.user table row that
matches user_name in the
User column and the client host
from which you connect in the
Host column.
For password changes made using mysqladmin,
MySQL automatically hashes the password before storing it in
the mysql.user table.
MySQL enables database administrators to expire account passwords manually, and to establish a policy for automatic password expiration.
To expire a password manually, the database administrator uses the
ALTER USER statement:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;
This operation marks the password expired in the corresponding
mysql.user table row.
Automatic password expiration is available in MySQL 5.7.4 and
later. The mysql.user table indicates for each
account when its password was last changed, and the server
automatically treats the password as expired at client connection
time if it is past its permitted lifetime. This works with no
explicit manual password expiration.
The default_password_lifetime
system variable defines the global automatic password expiration
policy. It applies to accounts that use MySQL built-in
authentication methods (accounts that use an authentication plugin
of mysql_native_password,
mysql_old_password, or
sha256_password).
The default
default_password_lifetime value
is 0, which disables automatic password expiration. If the value
of default_password_lifetime is a
positive integer N, it indicates the
permitted password lifetime; passwords must be changed every
N days.
From MySQL 5.7.4 to 5.7.10, the default
default_password_lifetime value
is 360 (passwords must be changed approximately once per year).
For those versions, be aware that, if you make no changes to the
default_password_lifetime
variable or to individual user accounts, all user passwords will
expire after 360 days, and all user accounts will start running
in restricted mode when this happens. Clients (which are
effectively users) connecting to the server will then get an
error indicating that the password must be changed:
ERROR 1820 (HY000): You must reset your password using
ALTER USER statement before executing this statement.
However, this is easy to miss for clients that automatically connect to the server, such as connections made from scripts. To avoid having such clients suddenly stop working due to a password expiring, make sure to change the password expiration settings for those clients, like this:
ALTER USER 'script'@'localhost' PASSWORD EXPIRE NEVER
Alternatively, set the
default_password_lifetime
variable to 0, thus disabling automatic
password expiration for all users.
Examples:
To establish a global policy that passwords have a lifetime of approximately six months, start the server with these lines in an option file:
[mysqld] default_password_lifetime=180
To establish a global policy such that passwords never expire,
set default_password_lifetime
to 0:
[mysqld] default_password_lifetime=0
default_password_lifetime can
also be changed at runtime (this requires the
SUPER privilege):
SET GLOBAL default_password_lifetime = 180; SET GLOBAL default_password_lifetime = 0;
No matter the global policy, it can be overridden for individual
accounts with ALTER USER:
Require the password to be changed every 90 days:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
Disable password expiration:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
Defer to the global expiration policy:
ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;
These ALTER USER statements update
the corresponding mysql.user table row.
When a client successfully connects, the server determines whether the account password is expired:
The server checks whether the password has been manually expired and, if so, restricts the session.
Otherwise, the server checks whether the password is past its lifetime according to the automatic password expiration policy. If so, the server considers the password expired and restricts the session.
A restricted client operates in “sandbox mode,”, which limits the operations permitted to the client (see Section 5.7, “Password Expiration and Sandbox Mode”). Operations performed by a restricted client result in an error until the user establishes a new account password:
mysql>SELECT 1;ERROR 1820 (HY000): You must SET PASSWORD before executing this statement mysql>ALTER USER USER() IDENTIFIED BY 'Query OK, 0 rows affected (0.01 sec) mysql>new_password';SELECT 1;+---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec)
This restricted mode of operation permits
SET
statements, which is useful before MySQL 5.7.6 if
SET PASSWORD must be used instead
of ALTER USER and the account
password has a hashing format that requires
old_passwords to be set to a
value different from its default.
It is possible for an administrative user to reset the account password, but any existing sessions for that account remain restricted. A client using the account must disconnect and reconnect before statements can be executed successfully.
It is possible to “reset” a password by setting it to its current value. As a matter of good policy, it is preferable to choose a different password.
MySQL provides password-expiration capability to enable database administrators to expire account passwords and require users to reset their password. This section describes how password expiration works.
To expire an account password, use the ALTER
USER statement. For example:
ALTER USER 'myuser'@'localhost' PASSWORD EXPIRE;
This statement modifies the row of the
mysql.user table associated with the named
account, setting the password_expired column to
'Y'. This does not affect any current
connections the account has open. For each subsequent connection
that uses the account, the server either disconnects the client or
handles the client in “sandbox mode,” in which the
server permits to the client only those operations necessary to
reset the expired password. The action taken by the server depends
on both client and server settings.
If the server disconnects the client, it returns an
ER_MUST_CHANGE_PASSWORD_LOGIN
error:
shell>mysql -u myuser -pPassword:******ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords.
If the server puts the client in sandbox mode, these operations are permitted within the client session:
The client can reset the account password with
ALTER USER or
SET PASSWORD. This modifies the
row of the mysql.user table associated with
the current account, setting the
password_expired column to
'N'. After the password has been reset, the
server restores normal access for the session, as well as for
subsequent connections that use the account.
It is possible to “reset” a password by setting it to its current value. As a matter of good policy, it is preferable to choose a different password.
The client can use
SET
statements, which is useful before MySQL 5.7.6 if
SET PASSWORD must be used
instead of ALTER USER and the
account password has a hashing format that requires
old_passwords to be set to a
value different from its default.
For any operation not permitted within the session, the server
returns an ER_MUST_CHANGE_PASSWORD
error:
mysql>USE performance_schema;ERROR 1820 (HY000): You must SET PASSWORD before executing this statement mysql>SELECT 1;ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
For noninteractive invocations of the mysql
client (for example, in batch mode), the server normally
disconnects the client if the password is expired. To permit
mysql to stay connected so that the password
can be changed (using the statements just described), add the
--connect-expired-password option to
the mysql command.
As mentioned previously, whether the server disconnects an expired-password client or puts it in sandbox mode depends on a combination of client and server settings. The following discussion describes the relevant settings and how they interact.
On the client side, a given client indicates whether it can handle sandbox mode for expired passwords. For clients that use the C client library, there are two ways to do this:
Pass the
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS flag
to mysql_options() prior to
connecting:
arg = 1;
result = mysql_options(mysql,
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, &arg);
The mysql client enables
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS if
invoked interactively or the
--connect-expired-password
option is given.
Pass the
CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS flag to
mysql_real_connect() at
connection time:
mysql = mysql_real_connect(mysql,
host, user, password, "test",
port, unix_socket,
CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS);
Other MySQL Connectors have their own conventions for indicating readiness to handle sandbox mode. See the relevant Connector documentation.
On the server side, if a client indicates that it can handle expired passwords, the server puts it in sandbox mode.
If a client does not indicate that it can handle expired passwords
(or uses an older version of the client library that cannot so
indicate), the server action depends on the value of the
disconnect_on_expired_password
system variable:
If
disconnect_on_expired_password
is enabled (the default), the server disconnects the client
with an
ER_MUST_CHANGE_PASSWORD_LOGIN
error.
If
disconnect_on_expired_password
is disabled, the server puts the client in sandbox mode.
The preceding client and server settings apply only for accounts with expired passwords. If a client connects using a nonexpired password, the server handles the client normally.
When a client connects to the MySQL server, the server uses the
user name provided by the client and the client host to select the
appropriate account row from the mysql.user
table. The server then authenticates the client, determining from
the account row which authentication plugin applies for the
client:
If the account row specifies a plugin, the server invokes it to authenticate the user. If the server cannot find the plugin, an error occurs.
If the account row specifies no plugin name, the server
authenticates the account using either the
mysql_native_password or
mysql_old_password plugin, depending on
whether the password hash value in the
Password column used native hashing or the
older pre-4.1 hashing method. Clients must match the password
in the Password column of the account row.
As of MySQL 5.7.2, the server requires the plugin value to be
nonempty, and as of 5.7.5, support for
mysql_old_password is removed.
The plugin returns a status to the server indicating whether the user is permitted to connect.
Pluggable authentication enables two important capabilities:
External authentication:
Pluggable authentication makes it possible for clients to
connect to the MySQL server with credentials that are
appropriate for authentication methods other than native
authentication based on passwords stored in the
mysql.user table. For example, plugins can
be created to use external authentication methods such as PAM,
Windows login IDs, LDAP, or Kerberos.
Proxy users: If a user is permitted to connect, an authentication plugin can return to the server a user name different from the name of the connecting user, to indicate that the connecting user is a proxy for another user. While the connection lasts, the proxy user is treated, for purposes of access control, as having the privileges of a different user. In effect, one user impersonates another. For more information, see Section 5.9, “Proxy Users”.
Several authentication plugins are available in MySQL:
Plugins that perform native authentication that matches the
password against the Password column of the
account row. The mysql_native_password
plugin implements authentication based on the native password
hashing method. The mysql_old_password
plugin implements native authentication based on the older
(pre-4.1) password hashing method (and is deprecated and
removed in MySQL 5.7.5). See
Section 6.1.1, “The Native Authentication Plugin”, and
Section 6.1.2, “The Old Native Authentication Plugin”. Native
authentication using mysql_native_password
is the default for new accounts, unless the
default_authentication_plugin system
variable is set otherwise.
A plugin that performs authentication using SHA-256 password
hashing. This plugin matches the password against the
authentication_string column of the account
row. This is stronger encryption than that available with
native authentication. See
Section 6.1.4, “The SHA-256 Authentication Plugin”.
A plugin prevents all client connections to any account that uses it. Use cases for such a plugin includes accounts that must be able to execute stored programs and views with elevated privileges without exposing those privileges to ordinary users, and proxy accounts that should never permit direct login. See Section 6.1.7, “The No-Login Authentication Plugin”.
A client-side plugin that sends the password to the server without hashing or encryption. This plugin can be used by server-side plugins that require access to the password exactly as provided by the client user. See Section 6.1.8, “The Cleartext Client-Side Authentication Plugin”.
A plugin that authenticates clients that connect from the local host through the Unix socket file. See Section 6.1.9, “The Socket Peer-Credential Authentication Plugin”.
A test plugin that authenticates using MySQL native authentication. This plugin is intended for testing and development purposes, and as an example of how to write an authentication plugin. See Section 6.1.10, “The Test Authentication Plugin”.
For information about current restrictions on the use of pluggable authentication, including which connectors support which plugins, see Restrictions on Pluggable Authentication.
Third-party connector developers should read that section to determine the extent to which a connector can take advantage of pluggable authentication capabilities and what steps to take to become more compliant.
If you are interested in writing your own authentication plugins, see Writing Authentication Plugins.
This section provides general instructions for installing and using authentication plugins.
In general, pluggable authentication uses corresponding plugins on the server and client sides, so you use a given authentication method like this:
On the server host, install the library containing the appropriate server plugin, if necessary, so that the server can use it to authenticate client connections. Similarly, on each client host, install the library containing the appropriate client plugin for use by client programs.
Create MySQL accounts that specify use of the plugin for authentication.
When a client connects, the server plugin tells the client program which client plugin to use for authentication.
The instructions here use an example authentication plugin included in MySQL distributions (see Section 6.1.10, “The Test Authentication Plugin”). The procedure is similar for other authentication plugins; substitute the appropriate plugin and file names.
The example authentication plugin has these characteristics:
The server-side plugin name is
test_plugin_server.
The client-side plugin name is
auth_test_plugin.
Both plugins are located in the shared library file named
auth_test_plugin.so in the plugin
directory (the directory named by the
plugin_dir system variable).
The file name suffix might differ on your system.
Install and use the example authentication plugin as follows:
Make sure that the plugin library is installed on the server and client hosts.
Install the server-side test plugin at server startup or at runtime:
To install the plugin at startup, use the
--plugin-load option. With
this plugin-loading method, the option must be given each
time you start the server. For example, use these lines in
a my.cnf option file:
[mysqld] plugin-load=test_plugin_server=auth_test_plugin.so
To install the plugin at runtime, use the
INSTALL PLUGIN statement:
INSTALL PLUGIN test_plugin_server SONAME 'auth_test_plugin.so';
This installs the plugin permanently and need be done only once.
Verify that the plugin is installed. For example, use
SHOW PLUGINS:
mysql> SHOW PLUGINS\G
...
*************************** 21. row ***************************
Name: test_plugin_server
Status: ACTIVE
Type: AUTHENTICATION
Library: auth_test_plugin.so
License: GPL
For other ways to check the plugin, see Obtaining Server Plugin Information.
To specify that a MySQL user must be authenticated using a
specific server plugin, name the plugin in the
IDENTIFIED WITH clause of the
CREATE USER statement that
creates the user:
CREATE USER 'testuser'@'localhost' IDENTIFIED WITH test_plugin_server;
Connect to the server using a client program. The test plugin
authenticates the same way as native MySQL authentication, so
provide the usual --user and
--password options that you
normally use to connect to the server. For example:
shell> mysql --user=your_name --password=your_pass
For connections by testuser, the server
sees that the account must be authenticated using the
server-side plugin named test_plugin_server
and communicates to the client program which client-side
plugin it must use—in this case,
auth_test_plugin.
In the case that the account uses the authentication method
that is the default for both the server and the client
program, the server need not communicate to the client which
plugin to use, and a round trip in client/server negotiation
can be avoided. This is true for accounts that use native
MySQL authentication
(mysql_native_password).
The
--default-auth=
option can be specified on the mysql
command line as a hint about which client-side plugin the
program can expect to use, although the server will override
this if the user account requires a different plugin.
plugin_name
If the client program does not find the plugin, specify a
--plugin-dir=
option to indicate where the plugin is located.
dir_name
If you start the server with the
--skip-grant-tables option,
authentication plugins are not used even if loaded because the
server performs no client authentication and permits any client
to connect. Because this is insecure, you might want to use
--skip-grant-tables in
conjunction with
--skip-networking to prevent
remote clients from connecting.
Authentication to the MySQL server occurs by means of authentication plugins. The plugin that authenticates a given connection may request that the connecting (external) user be treated as a different user for privilege-checking purposes. This enables the external user to be a proxy for the second user; that is, to have the privileges of the second user:
The external user is a “proxy user” (a user who can impersonate or become known as another user).
The second user is a “proxied user” (a user whose identity can be taken on by a proxy user).
This section describes how the proxy user capability works. For general information about authentication plugins, see Section 5.8, “Pluggable Authentication”. For information about specific plugins, see Section 6.1, “Authentication Plugins”. For information about writing authentication plugins that support proxy users, see Implementing Proxy User Support in Authentication Plugins.
For proxying to occur for a given authentication plugin, these conditions must be satisfied:
A proxy user account must be set up to be authenticated by the
plugin. Use the CREATE USER
statement to associate an account with a plugin, or
ALTER USER to change its
plugin.
For a client connecting to the proxy account to be treated as a proxy user, the plugin must return a user name different from the client user name, to indicate the user name for the proxied account.
The proxy user account must have the
PROXY privilege for the proxied
account. Use the GRANT
statement for this.
The proxy mechanism permits mapping only the client user name to the proxied user name. There is no provision for mapping host names. When a connecting client matches a proxy account, the server attempts to find a match for a proxied account using the user name returned by the authentication plugin and the host name of the proxy account.
Consider the following definitions:
-- create proxy user CREATE USER 'employee_ext'@'localhost' IDENTIFIED WITH my_auth_plugin AS 'my_auth_string'; -- create proxied user CREATE USER 'employee'@'localhost' IDENTIFIED BY 'employee_pass'; -- grant PROXY privilege for proxy user to proxied user GRANT PROXY ON 'employee'@'localhost' TO 'employee_ext'@'localhost';
When a client connects as employee_ext from the
local host, MySQL uses my_auth_plugin to
perform authentication. Suppose that
my_auth_plugin returns a user name of
employee to the server, based on the content of
'my_auth_string' and perhaps by consulting some
external authentication system. The name
employee differs from
employee_ext, so returning
employee serves as a request to the server to
treat the employee_ext client, for purposes of
privilege checking, as the employee local user.
In this case, employee_ext is the proxy user
and employee is the proxied user.
The server verifies that proxy authentication for
employee is possible for the
employee_ext user by checking whether
employee_ext (the proxy user) has the
PROXY privilege for
employee (the proxied user). If this privilege
has not been granted, an error occurs.
When proxying occurs, the USER() and
CURRENT_USER() functions can be used to see the
difference between the connecting user (the proxy user) and the
account whose privileges apply during the current session (the
proxied user). For the example just described, those functions
return these values:
mysql> SELECT USER(), CURRENT_USER();
+------------------------+--------------------+
| USER() | CURRENT_USER() |
+------------------------+--------------------+
| employee_ext@localhost | employee@localhost |
+------------------------+--------------------+
In the CREATE USER statement that
creates the proxy user account, the IDENTIFIED
WITH clause that names the authentication plugin is
optionally followed by an AS
' clause
specifying a string that the server passes to the plugin when the
user connects. If present, the string provides information that
helps the plugin determine how to map the external client user
name to a proxied user name. It is up to each plugin whether it
requires the auth_string'AS clause. If so, the format of
the authentication string depends on how the plugin intends to use
it. Consult the documentation for a given plugin for information
about the authentication string values it accepts.
The PROXY privilege is needed to
enable an external user to connect as and have the privileges of
another user. To grant this privilege, use the
GRANT statement. For example:
GRANT PROXY ON 'proxied_user' TO 'proxy_user';
The statement creates a row in the
mysql.proxies_priv grant table.
At connection time, proxy_user must
represent a valid externally authenticated MySQL user, and
proxied_user must represent a valid
locally authenticated user. Otherwise, the connection attempt
fails.
The corresponding REVOKE syntax
is:
REVOKE PROXY ON 'proxied_user' FROM 'proxy_user';
MySQL GRANT and
REVOKE syntax extensions work as
usual. For example:
GRANT PROXY ON 'a' TO 'b', 'c', 'd'; GRANT PROXY ON 'a' TO 'd' WITH GRANT OPTION; GRANT PROXY ON 'a' TO ''@''; REVOKE PROXY ON 'a' FROM 'b', 'c', 'd';
In the preceding example, ''@'' is the
default proxy user and means “any user.” Default
proxy user are discussed in
Default Proxy Users.
The PROXY privilege can be
granted in these cases:
By a user that has GRANT PROXY ... WITH GRANT
OPTION for
proxied_user.
By proxied_user for itself: The
value of USER() must exactly match
CURRENT_USER() and
proxied_user, for both the user
name and host name parts of the account name.
The initial root account created during MySQL
installation has the
PROXY ... WITH GRANT
OPTION privilege for ''@'', that
is, for all users and all hosts. This enables
root to set up proxy users, as well as to
delegate to other accounts the authority to set up proxy users.
For example, root can do this:
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'test'; GRANT PROXY ON ''@'' TO 'admin'@'localhost' WITH GRANT OPTION;
Those statements create an admin user that
can manage all GRANT PROXY mappings. For
example, admin can do this:
GRANT PROXY ON sally TO joe;
To specify that some or all users should connect using a given
authentication plugin, create a “blank” MySQL user,
associate it with that plugin for authentication, and let the
plugin return the real authenticated user name (if different
from the blank user). For example, suppose that there exists a
plugin named ldap_auth that implements LDAP
authentication and maps connecting users onto either a developer
or manager account. To set up proxying of users onto these
accounts, use the following statements:
-- create default proxy user CREATE USER ''@'' IDENTIFIED WITH ldap_auth AS 'O=Oracle, OU=MySQL'; -- create proxied users CREATE USER 'developer'@'localhost' IDENTIFIED BY 'developer_pass'; CREATE USER 'manager'@'localhost' IDENTIFIED BY 'manager_pass'; -- grant PROXY privilege for default proxy user to proxied users GRANT PROXY ON 'manager'@'localhost' TO ''@''; GRANT PROXY ON 'developer'@'localhost' TO ''@'';
Now assume that a client tries to connect as follows:
mysql --user=myuser --password='myuser_pass' ...
The server will not find myuser defined as a
MySQL user. But because there is a blank user account
(''@''), that matches the client user name
and host name, the server authenticates the client against that
account: The server invokes the ldap_auth
authentication plugin and passes myuser and
myuser_pass to it as the user name and
password.
If the ldap_auth plugin finds in the LDAP
directory that myuser_pass is not the correct
password for myuser, authentication fails and
the server rejects the connection.
If the password is correct and ldap_auth
finds that myuser is a developer, it returns
the user name developer to the MySQL server,
rather than myuser. Returning a user name
different from the client user name of myuser
signals to the server that it should treat
myuser as a proxy. The server verifies that
''@'' can authenticate as
developer (because it has the
PROXY privilege to do so) and
accepts the connection. The session proceeds with
myuser having the privileges of
developer, the proxied user. (These
privileges should be set up by the DBA using
GRANT statements, not shown.) The
USER() and
CURRENT_USER() functions return
these values:
mysql> SELECT USER(), CURRENT_USER();
+------------------+---------------------+
| USER() | CURRENT_USER() |
+------------------+---------------------+
| myuser@localhost | developer@localhost |
+------------------+---------------------+
If the plugin instead finds in the LDAP directory that
myuser is a manager, it returns
manager as the user name and the session
proceeds with myuser having the privileges of
manager.
mysql> SELECT USER(), CURRENT_USER();
+------------------+-------------------+
| USER() | CURRENT_USER() |
+------------------+-------------------+
| myuser@localhost | manager@localhost |
+------------------+-------------------+
For simplicity, external authentication cannot be multilevel:
Neither the credentials for developer nor
those for manager are taken into account in
the preceding example. However, they are still used if a client
tries to connect and authenticate directly as the
developer or manager
account, which is why those accounts should be assigned
passwords.
If you intend to create a default proxy user, check for other existing “match any user” accounts that take precedence over the default proxy user and thus prevent that user from working as intended.
In the preceding discussion, the default proxy user account has
'' in the host part, which matches any host.
If you set up a default proxy user, take care to also check
whether nonproxy accounts exist with the same user part and
'%' in the host part, because
'%' also matches any host, but has precedence
over '' by the rules that the server uses to
sort account rows internally (see
Section 4.4, “Access Control, Stage 1: Connection Verification”).
Suppose that a MySQL installation includes these two accounts:
-- create default proxy user CREATE USER ''@'' IDENTIFIED WITH some_plugin AS 'some_auth_string'; -- create anonymous user CREATE USER ''@'%' IDENTIFIED BY 'some_password';
The first account (''@'') is intended as the
default proxy user, used to authenticate connections for users
who do not otherwise match a more-specific account. The second
account (''@'%') is an anonymous-user
account, which might have been created, for example, to enable
users without their own account to connect anonymously.
Both accounts have the same user part (''),
which matches any user. And each account has a host part that
matches any host. Nevertheless, there is a priority in account
matching for connection attempts because the matching rules sort
a host of '%' ahead of ''.
For accounts that do not match any more-specific account, the
server attempts to authenticate them against
''@'%' (the anonymous user) rather than
''@'' (the default proxy user). The result is
that the default proxy account is never used.
To avoid this problem, use one of the following strategies:
Remove the anonymous account so that it does not conflict with the default proxy user. This might be a good idea anyway if you want to associate every connection with a named user.
Use a more-specific default proxy user that matches ahead of
the anonymous user. For example, to permit only
localhost proxy connections, use
''@'localhost':
CREATE USER ''@'localhost' IDENTIFIED WITH some_plugin AS 'some_auth_string';
In addition, modify any GRANT PROXY
statements to name ''@'localhost' rather
than ''@'' as the proxy user.
Be aware that this strategy prevents anonymous-user
connections from localhost.
Create multiple proxy users, one for local connections and one for “everything else” (remote connections). This can be useful particularly when local users should have different privileges from remote users.
Create the proxy users:
-- create proxy user for local connections CREATE USER ''@'localhost' IDENTIFIED WITH some_plugin AS 'some_auth_string'; -- create proxy user for remote connections CREATE USER ''@'%' IDENTIFIED WITH some_plugin AS 'some_auth_string';
Create the proxied users:
-- create proxied user for local connections CREATE USER 'developer'@'localhost' IDENTIFIED BY 'some_password'; -- create proxied user for remote connections CREATE USER 'developer'@'%' IDENTIFIED BY 'some_password';
Grant the proxy privilege to each proxy user for the corresponding proxied user:
GRANT PROXY ON 'developer'@'localhost' TO ''@'localhost'; GRANT PROXY ON 'developer'@'%' TO ''@'%';
Finally, grant appropriate privileges to the local and remote proxied users (not shown).
Assume that the
some_plugin/'some_auth_string'
combination causes some_plugin to map the
client user name to developer. Local
connections match the ''@'localhost'
proxy user, which maps to the
'developer'@'localhost' proxied user.
Remote connections match the ''@'%' proxy
user, which maps to the 'developer'@'%'
proxied user.
Some authentication plugins implement proxy user mapping for
themselves. As of MySQL 5.7.7, the MySQL server itself can map
proxy users according to granted proxy privileges. If the
check_proxy_users system
variable is enabled, the server performs proxy user mapping for
any authentication plugins that request it:
By default,
check_proxy_users is
disabled, so the server performs no proxy user mapping even
for authentication plugins that request it.
With check_proxy_users
enabled, it may also be necessary to enable plugin-specific
system variables to take advantage of server proxy user
mapping support:
For the mysql_native_password plugin,
enable
mysql_native_password_proxy_users.
For the sha256_password plugin,
enable
sha256_password_proxy_users.
Proxy user mapping performed by the server is subject to some restrictions:
The server will not proxy to or from an anonymous user, even
if the associated PROXY
privilege is granted.
When a single account has been granted proxy privileges for more than one account, server proxy user mapping is nondeterministic. Therefore, granting proxy privileges for multiple accounts to a single account is discouraged.
Two system variables help trace the proxy login process:
proxy_user: This value is
NULL if proxying is not used. Otherwise,
it indicates the proxy user account. For example, if a
client authenticates through the ''@''
proxy account, this variable is set as follows:
mysql> SELECT @@proxy_user;
+--------------+
| @@proxy_user |
+--------------+
| ''@'' |
+--------------+
external_user: Sometimes
the authentication plugin may use an external user to
authenticate to the MySQL server. For example, when using
Windows native authentication, a plugin that authenticates
using the windows API does not need the login ID passed to
it. However, it still uses a Windows user ID to
authenticate. The plugin may return this external user ID
(or the first 512 UTF-8 bytes of it) to the server using the
external_user read-only session variable.
If the plugin does not set this variable, its value is
NULL.
As of version 5.7.6, MySQL supports locking and unlocking user
accounts using the ACCOUNT LOCK and
ACCOUNT UNLOCK clauses for the
CREATE USER and
ALTER USER statements:
When used with CREATE USER,
these clauses specify the initial locking state for a new
account. In the absence of either clause, the account is
created in an unlocked state.
When used with ALTER USER,
these clauses specify the new locking state for an existing
account. In the absence of either clause, the account locking
state remains unchanged.
Account locking state is recorded in the
account_locked column of the
mysql.user table. The output from
SHOW CREATE USER indicates whether
an account is locked or unlocked.
If a client attempts to connect to a locked account, the attempt
fails. The server increments the
Locked_connects status variable
that indicates the number of attempts to connect to a locked
account, returns an
ER_ACCOUNT_HAS_BEEN_LOCKED error,
and writes a message to the error log:
Access denied for user 'user_name'@'host_name'. Account is locked.
Locking an account does not affect being able to connect using a
proxy user that assumes the identity of the locked account. It
also does not affect the ability to execute stored programs or
views that have a DEFINER clause naming the
locked account. That is, the ability to use a proxied account or
stored programs or views is not affected by locking the account.
The account-locking capability depends on the presence of the
account_locked column in the
mysql.user table. For upgrades to MySQL 5.7.6
and later from older versions, run
mysql_upgrade to ensure that this column
exists. For nonupgraded installations that have no
account_locked column, the server treats all
accounts as unlocked, and using the ACCOUNT
LOCK or ACCOUNT UNLOCK clauses
produces an error.
With an unencrypted connection between the MySQL client and the server, someone with access to the network could watch all your traffic and inspect the data being sent or received between client and server.
When you must move information over a network in a secure fashion, an unencrypted connection is unacceptable. To make any kind of data unreadable, use encryption. Encryption algorithms must include security elements to resist many kinds of known attacks such as changing the order of encrypted messages or replaying data twice.
MySQL supports secure (encrypted) connections between clients and the server using the TLS (Transport Layer Security) protocol. TLS is sometimes referred to as SSL (Secure Sockets Layer) but MySQL does not actually use the SSL protocol for secure connections because it provides weak encryption (see Section 5.11.3, “Secure Connection Protocols and Ciphers”).
TLS uses encryption algorithms to ensure that data received over a public network can be trusted. It has mechanisms to detect data change, loss, or replay. TLS also incorporates algorithms that provide identity verification using the X509 standard.
X509 makes it possible to identify someone on the Internet. In basic terms, there should be some entity called a “Certificate Authority” (or CA) that assigns electronic certificates to anyone who needs them. Certificates rely on asymmetric encryption algorithms that have two encryption keys (a public key and a secret key). A certificate owner can present the certificate to another party as proof of identity. A certificate consists of its owner's public key. Any data encrypted using this public key can be decrypted only using the corresponding secret key, which is held by the owner of the certificate.
MySQL can be compiled for secure-connection support using OpenSSL or yaSSL. For a comparison of the two packages, see Section 5.11.1, “OpenSSL Versus yaSSL” For information about the encryption protocols and ciphers each package supports, see Section 5.11.3, “Secure Connection Protocols and Ciphers”.
MySQL performs encryption on a per-connection basis, and use of
encryption for a given user can be optional or mandatory. This
enables you to choose an encrypted or unencrypted connection
according to the requirements of individual applications. For
information on how to require users to use encrypted connections,
see the discussion of the REQUIRE clause of the
CREATE USER statement in
CREATE USER Syntax. See also the description of the
require_secure_transport system
variable at Server System Variables
Several improvements were made to secure-connection support in MySQL 5.7. The following timeline summarizes the changes:
5.7.3: On the client side, an explicit
--ssl option is no longer
advisory but prescriptive. Given a server enabled to support
secure connections, a client program can require a secure
conection by specifying only the
--ssl option. The connection
attempt fails if a secure connection cannot be established.
Other --ssl-
options on the client side mean that a secure connection is
advisory (the connection attempt falls back to an unencrypted
connection if a secure connection cannot be established).
xxx
5.7.5: The server-side --ssl
option value is enabled by default.
For servers compiled using OpenSSL, the
auto_generate_certs and
sha256_password_auto_generate_rsa_keys
system variables are available to enable autogeneration and
autodiscovery of SSL/RSA certificate and key files at startup.
For certificate and key autodiscovery, if
--ssl is enabled and other
--ssl- options
are not given to configure secure connections explicitly, the
server attempts to enable support for secure connections
automatically at startup if it discovers the requisite
certificate and key files in the data directory.
xxx
5.7.6: The mysql_ssl_rsa_setup utility is
available to make it easier to manually generate SSL/RSA
certificate and key files. Autodiscovery of SSL/RSA files at
startup is expanded to apply to all servers, whether compiled
using OpenSSL or yaSSL. (This means that
auto_generate_certs need not
be enabled for autodiscovery to occur.)
If the server discovers at startup that the CA certificate is self-signed, it writes a warning to its error log. (The certificate will be self-signed if created automatically by the server or manually using mysql_ssl_rsa_setup.)
5.7.7: The C client library attempts to establish a secure connection by default whenever the server supports secure connections. This affects client programs as follows:
In the absence of an --ssl
option, the client falls back to an unencrypted connection
if a secure connection cannot be established.
To require a secure connection and fail if one cannot be
established, invoke the client with an explicit
--ssl option or a synonym
(--ssl=1,
--enable-ssl).
To use an unencrypted connection, invoke the client with
an --ssl=0 option or a
synonym
(--skip-ssl,
--disable-ssl).
This change also affects subsequent releases of MySQL Connectors that are based on the C client library: Connector/C, Connector/C++, and Connector/ODBC.
5.7.8: The
require_secure_transport
system variable is available to control whether client
connections to the server must use some form of secure
transport.
5.7.10: TLS protocol support is extended from TLSv1 to also
include TLSv1.1 and TLSv1.2. The
tls_version system variable
on the server side and
--tls-version option on the
client side enable the level of support to be selected. See
Section 5.11.3, “Secure Connection Protocols and Ciphers”.
5.7.11: MySQL client programs support an
--ssl-mode option that enables
you to specify the security state of the connection to the
server. The --ssl-mode option
comprises the capabilities of the client-side
--ssl and
--ssl-verify-server-cert
options. Consequently, both of those options are deprecated
and will be removed in a future MySQL release.
Secure connections are available through the MySQL C API using the
mysql_ssl_set() and
mysql_options() functions. See
mysql_ssl_set(), and
mysql_options().
Replication uses the C API, so secure connections can be used between master and slave servers. See Setting Up Replication to Use Secure Connections.
It is also possible to connect securely from within an SSH connection to the MySQL server host. For an example, see Section 5.13, “Connecting to MySQL Remotely from Windows with SSH”.
MySQL can be compiled using OpenSSL or yaSSL, both of which enable secure conections based on the OpenSSL API:
MySQL Enterprise Edition binary distributions are compiled using OpenSSL. It is not possible to use yaSSL with MySQL Enterprise Edition.
MySQL Community Edition binary distributions are compiled using yaSSL.
MySQL Community Edition source distributions can be compiled using either OpenSSL or yaSSL (see Section 5.11.2, “Building MySQL with Support for Secure Connections”).
OpenSSL and yaSSL offer the same basic functionality, but MySQL distributions compiled using OpenSSL have additional features:
OpenSSL supports a wider range of encryption ciphers from
which to choose for the
--ssl-cipher option. OpenSSL
supports the --ssl-capath,
--ssl-crl, and
--ssl-crlpath options. See
Section 5.11.5, “Command Options for Secure Connections”.
Accounts that authenticate using the
sha256_password plugin can use RSA key
files for secure password exchange over unencrypted
connections. See
Section 6.1.4, “The SHA-256 Authentication Plugin”.
The server can automatically generate missing SSL and RSA certificate and key files at startup. See Section 5.12.1, “Creating SSL and RSA Certificates and Keys using MySQL”.
OpenSSL supports more encryption modes for the
AES_ENCRYPT() and
AES_DECRYPT() functions. See
Encryption and Compression Functions
Certain OpenSSL-related system and status variables are present only if MySQL was compiled using OpenSSL:
auto_generate_certs (added
in MySQL 5.7.5)
sha256_password_auto_generate_rsa_keys
(added in MySQL 5.7.5)
To determine whether your server was compiled using OpenSSL, test the existence of any of those variables. For example, this statement returns a row if OpenSSL was used and an empty result if yaSSL was used:
SHOW STATUS LIKE 'Rsa_public_key';
Such tests assume that your server version is not older than the
first appearance of the variable tested. For example, you cannot
test for auto_generate_certs
before MySQL 5.7.6.
To use SSL connections between the MySQL server and client programs, your system must support either OpenSSL or yaSSL:
MySQL Enterprise Edition binary distributions are compiled using OpenSSL. It is not possible to use yaSSL with MySQL Enterprise Edition.
MySQL Community Edition binary distributions are compiled using yaSSL.
MySQL Community Edition source distributions can be compiled using either OpenSSL or yaSSL.
If you compile MySQL from a source distribution, CMake configures the distribution to use yaSSL by default. To compile using OpenSSL instead, use this procedure:
Ensure OpenSSL 1.0.1 or higher is installed on your system. To obtain OpenSSL, visit http://www.openssl.org.
If the installed OpenSSL version is lower than 1.0.1, CMake produces an error at MySQL configuration time.
To use OpenSSL, add the
-DWITH_SSL=system option to
the CMake command you normally use to
configure the MySQL source distribution. For example:
shell> cmake . -DWITH_SSL=system
That command configures the distribution to use the installed OpenSSL library. Alternatively, to explicitly specify the path name to the OpenSSL installation, use the following syntax. This can be useful if you have multiple versions of OpenSSL installed, to prevent CMake from choosing the wrong one:
shell> cmake . -DWITH_SSL=path_name
Compile and install the distribution.
To check whether a mysqld server supports
secure connections, examine the value of the
have_ssl system variable:
mysql> SHOW VARIABLES LIKE 'have_ssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_ssl | YES |
+---------------+-------+
If the value is YES, the server supports
secure connections. If the value is DISABLED,
the server is capable of supporting secure connections but was
not started with the appropriate
--ssl- options to
enable secure connections to be used; see
Section 5.11.4, “Configuring MySQL to Use Secure Connections”.
xxx
To determine whether a server was compiled using OpenSSL or yaSSL, check the existence of any of the system or status variables that are present only for OpenSSL. See Section 5.11.1, “OpenSSL Versus yaSSL”
To determine which encryption protocol and cipher are in use for
an encrypted connection, use the following statements to check
the values of the Ssl_version
and Ssl_cipher status
variables:
mysql>SHOW SESSION STATUS LIKE 'Ssl_version';+---------------+-------+ | Variable_name | Value | +---------------+-------+ | Ssl_version | TLSv1 | +---------------+-------+ mysql>SHOW SESSION STATUS LIKE 'Ssl_cipher';+---------------+---------------------------+ | Variable_name | Value | +---------------+---------------------------+ | Ssl_cipher | DHE-RSA-AES128-GCM-SHA256 | +---------------+---------------------------+
If the connection is not encrypted, both variables have an empty value.
MySQL supports encrypted connections using TLS protocols:
When compiled using OpenSSL 1.0.1 or higher, MySQL supports the TLSv1, TLSv1.1, and TLSv1.2 protocols.
When compiled using the bundled version of yaSSL, MySQL supports the TLSv1 and TLSv1.1 protocols.
The value of the tls_version
system variable determines which protocols the server is
permitted to use from those that are available. The
tls_version value is a
comma-separated list containing one or more of these protocols
(not case sensitive): TLSv1, TLSv1.1, TLSv1.2. By default, this
variable lists all protocols supported by the SSL library used
to compile MySQL (TLSv1,TLSv1.1,TLSv1.2 for
OpenSSL, TLSv1,TLSv1.1 for yaSSL). To
determine the value of
tls_version at runtime, use
this statement:
mysql> SHOW GLOBAL VARIABLES LIKE 'tls_version';
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| tls_version | TLSv1,TLSv1.1,TLSv1.2 |
+---------------+-----------------------+
To change the value of
tls_version, set it at server
startup. For example, to prohibit connections that use the
less-secure TLSv1 protocol, use these lines in the server
my.cnf file:
[mysqld] tls_version=TLSv1.1,TLSv1.2
To be even more restrict and permit only TLSv1.2 connections,
set tls_version like this
(assuming that your server is compiled using OpenSSL because
yaSSL does not support TLSv1.2):
[mysqld] tls_version=TLSv1.2
For client programs, the
--tls-version option enables
specifying the TLS protocols permitted per client invocation.
The value format is the same as for
tls_version.
By default, MySQL attempts to use the highest TLS protocol
version available, depending on which SSL library was used to
compile the server and client, which key size is used, and
whether the server or client are restricted from using some
protocols; for example, by means of
tls_version/--tls-version:
If the server and client are compiled using OpenSSL, TLSv1.2 is used if possible.
If either or both the server and client are compiled using yaSSL, TLSv1.1 is used if possible.
TLSv1.2 does not work with all ciphers that have a key size
of 512 bits or less. To use this protocol with such a key,
use --ssl-cipher to specify
the cipher name explicitly:
AES128-SHA AES128-SHA256 AES256-SHA AES256-SHA256 CAMELLIA128-SHA CAMELLIA256-SHA DES-CBC3-SHA DHE-RSA-AES256-SHA RC4-MD5 RC4-SHA SEED-SHA
For better security, use a certificate with an RSA key size of of 2048 bits or more.
Prior to MySQL 5.7.10, MySQL supports only TLSv1, for both OpenSSL and yaSSL, and no system variable or client option exist for specifying which TLS protocols to permit.
If the server and client protocol capabilities have no protocol
in common, the server terminates the connection request. For
example, if the server is configured with
tls_version=TLSv1.1,TLSv1.2,
connection attempts will fail for clients invoked with
--tls-version=TLSv1, and for
older clients that do not support the
--tls-version option and
implicitly support only TLSv1.
To determine which ciphers a given server supports, use the
following statement to check the value of the
Ssl_cipher_list status
variable:
SHOW SESSION STATUS LIKE 'Ssl_cipher_list';
The set of available ciphers depends on your MySQL version and whether MySQL was compiled using OpenSSL or yaSSL, and (for OpenSSL) the library version used to compile MySQL.
As of MySQL 5.7.10, order of ciphers passed by MySQL to the SSL library is significant. More secure ciphers are mentioned first in the list, and the first cipher supported by the provided certificate is selected.
MySQL passes this cipher list to OpenSSL:
ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-DSS-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-DSS-AES128-SHA256 DHE-DSS-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-DSS-AES256-SHA256 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES128-SHA DHE-RSA-AES128-SHA TLS_DHE_DSS_WITH_AES_256_CBC_SHA DHE-RSA-AES256-SHA AES128-GCM-SHA256 DH-DSS-AES128-GCM-SHA256 ECDH-ECDSA-AES128-GCM-SHA256 AES256-GCM-SHA384 DH-DSS-AES256-GCM-SHA384 ECDH-ECDSA-AES256-GCM-SHA384 AES128-SHA256 DH-DSS-AES128-SHA256 ECDH-ECDSA-AES128-SHA256 AES256-SHA256 DH-DSS-AES256-SHA256 ECDH-ECDSA-AES256-SHA384 AES128-SHA DH-DSS-AES128-SHA ECDH-ECDSA-AES128-SHA AES256-SHA DH-DSS-AES256-SHA ECDH-ECDSA-AES256-SHA DHE-RSA-AES256-GCM-SHA384 DH-RSA-AES128-GCM-SHA256 ECDH-RSA-AES128-GCM-SHA256 DH-RSA-AES256-GCM-SHA384 ECDH-RSA-AES256-GCM-SHA384 DH-RSA-AES128-SHA256 ECDH-RSA-AES128-SHA256 DH-RSA-AES256-SHA256 ECDH-RSA-AES256-SHA384 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES128-SHA DHE-RSA-AES128-SHA TLS_DHE_DSS_WITH_AES_256_CBC_SHA DHE-RSA-AES256-SHA AES128-SHA DH-DSS-AES128-SHA ECDH-ECDSA-AES128-SHA AES256-SHA DH-DSS-AES256-SHA ECDH-ECDSA-AES256-SHA DH-RSA-AES128-SHA ECDH-RSA-AES128-SHA DH-RSA-AES256-SHA ECDH-RSA-AES256-SHA DES-CBC3-SHA
MySQL passes this cipher list to yaSSL:
DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA AES128-RMD DES-CBC3-RMD DHE-RSA-AES256-RMD DHE-RSA-AES128-RMD DHE-RSA-DES-CBC3-RMD AES256-SHA RC4-SHA RC4-MD5 DES-CBC3-SHA DES-CBC-SHA EDH-RSA-DES-CBC3-SHA EDH-RSA-DES-CBC-SHA AES128-SHA:AES256-RMD
As of MySQL 5.7.10, these cipher restrictions are in place:
The following ciphers are permanently restricted:
!DHE-DSS-DES-CBC3-SHA !DHE-RSA-DES-CBC3-SHA !ECDH-RSA-DES-CBC3-SHA !ECDH-ECDSA-DES-CBC3-SHA !ECDHE-RSA-DES-CBC3-SHA !ECDHE-ECDSA-DES-CBC3-SHA
The following categories of ciphers are permanently restricted:
!aNULL !eNULL !EXPORT !LOW !MD5 !DES !RC2 !RC4 !PSK !SSLv3
If the server is started using a compatible certificate that uses any of the preceding restricted ciphers or cipher categories, the server starts with support for secure connections disabled.
To enable secure connections, the proper options must be used to specify the appropriate certificate and key files. For a complete list of options related to establishment of secure connections, see Section 5.11.5, “Command Options for Secure Connections”.
If you need to create the required certificate and key files, see Section 5.12, “Creating SSL and RSA Certificates and Keys”.
To start the MySQL server so that it permits clients to connect securely, use options that identify the certificate and key files the server uses when establishing a secure connection:
--ssl-ca identifies the
Certificate Authority (CA) certificate.
--ssl-cert identifies the
server public key certificate. This can be sent to the
client and authenticated against the CA certificate that it
has.
--ssl-key identifies the
server private key.
For example, start the server with these lines in the
my.cnf file, changing the file names as
necessary:
[mysqld] ssl-ca=ca.pem ssl-cert=server-cert.pem ssl-key=server-key.pem
Each option names a file in PEM format. If you have a MySQL
source distribution, you can test your setup using the
demonstration certificate and key files in its
mysql-test/std_data directory.
As of MySQL 5.7.5, the server-side
--ssl option value is enabled by
default. Also as of MySQL 5.7.5, MySQL servers compiled using
OpenSSL can generate missing certificate and key files
automatically at startup. See
Section 5.12.1, “Creating SSL and RSA Certificates and Keys using MySQL”.
The server performs certificate and key file autodiscovery as of
MySQL 5.7.5 (for servers compiled using OpenSSL) or 5.7.6 (for
servers compiled using yaSSL). If
--ssl is enabled (possibly along
with --ssl-cipher) and other
--ssl- options
are not given to configure secure connections explicitly, the
server attempts to enable support for secure connections
automatically at startup:
xxx
If the server discovers valid certificate and key files
named ca.pem,
server-cert.pem, and
server-key.pem in the data directory,
it enables support for secure connections by clients. (The
files need not have been autogenerated; what matters is that
they have the indicated names and are valid.)
If the server does not find valid certificate and key files in the data directory, it continues executing but does not enable secure connections.
If the server automatically enables support for secure connections, it writes a message to the error log. As of MySQL 5.7.6, if the server discovers that the CA certificate is self-signed, it writes a warning to the error log. (The certificate will be self-signed if created automatically by the server or manually using mysql_ssl_rsa_setup.)
For any certificate and key files that the server discovers and
uses automatically, it uses the file names to set the
corresponding system variables
(ssl_ca,
ssl_cert,
ssl_key).
For further control over whether clients must connect securely,
use the
require_secure_transport system
variable; see Server System Variables. For
information about permitted encryption protocols and ciphers,
see Section 5.11.3, “Secure Connection Protocols and Ciphers”.
For client programs, options for secure connections are similar
to those used on the server side, but
--ssl-cert and
--ssl-key identify the client
public and private key:
--ssl-ca identifies the
Certificate Authority (CA) certificate. This option, if
used, must specify the same certificate used by the server.
--ssl-cert identifies the
client public key certificate.
--ssl-key identifies the
client private key.
To connect securely to a MySQL server that supports secure
connections, the options that a client must specify depend on
the encryption requirements of the MySQL account used by the
client. (See the discussion of the REQUIRE
clause in CREATE USER Syntax.)
Suppose that you want to connect using an account that has no
special encryption requirements or was created using a
CREATE USER statement that
includes the REQUIRE SSL option. As a
recommended set of secure-connection options, start the server
with at least --ssl-cert and
--ssl-key, and invoke the client
with --ssl-ca. A client can
connect securely like this:
shell> mysql --ssl-ca=ca.pem
To require that a client certificate also be specified, create
the account using the REQUIRE X509 option.
Then the client must also specify the proper client key and
certificate files or the server will reject the connection:
shell>mysql --ssl-ca=ca.pem \--ssl-cert=client-cert.pem \--ssl-key=client-key.pem
To prevent use of encryption and override other
--ssl- options,
invoke the client program with
xxx--ssl-mode=DISABLED,
--ssl=0, or a synonym
(--skip-ssl,
--disable-ssl):
shell> mysql --ssl-mode=DISABLED
As of MySQL 5.7.7, client programs attempt to establish a secure connection by default whenever the server supports secure connections:
In the absence of an
--ssl-mode or
--ssl option, the client
falls back to an unencrypted connection if a secure
connection cannot be established.
To require a secure connection and fail if one cannot be
established, invoke the client with
--ssl-mode=REQUIRED,
--ssl, or a synonym
(--ssl=1,
--enable-ssl).
To use an unencrypted connection, invoke the client with
--ssl-mode=DISABLED,
--ssl=0, or a synonym
(--skip-ssl,
--disable-ssl).
From MySQL 5.7.3 to 5.7.6, --ssl
on the client side is prescriptive (not advisory as before MySQL
5.7.3): With --ssl, connection
attempts fail if a secure connection cannot be established.
Before MySQL 5.7.3, --ssl on the
client side is advisory: --ssl
permits but does not require the client to connect to the server
using encryption. Therefore, this option is not sufficient in
itself to cause a secure connection to be used. For example, if
you specify this option for a client program but the server has
not been configured to support secure connections, the client
falls back to an unencrypted connection.
For information about permitted encryption protocols and ciphers, see Section 5.11.3, “Secure Connection Protocols and Ciphers”.
A client can determine whether the current connection with the
server uses encryption by checking the value of the
Ssl_cipher status variable. If
the value is empty, the connection is encrypted. Otherwise, the
connection is encrypted and the value indicates the encryption
cipher. For example:
mysql> SHOW STATUS LIKE 'Ssl_cipher';
+---------------+--------------------+
| Variable_name | Value |
+---------------+--------------------+
| Ssl_cipher | DHE-RSA-AES256-SHA |
+---------------+--------------------+
For the mysql client, an alternative is to
use the STATUS or \s
command and check the SSL line:
mysql> \s
...
SSL: Cipher in use is DHE-RSA-AES256-SHA
...
Or:
mysql> \s
...
SSL: Not in use
...
The C API enables application programs to use secure connections:
To establish a secure connection, use the
mysql_ssl_set() C API
function to set the appropriate certificate options before
calling
mysql_real_connect(). See
mysql_ssl_set(). To require the use of a
secure connection, call
mysql_options() with the
MYSQL_OPT_SSL_MODE option (use
MYSQL_OPT_SSL_ENFORCE option before MySQL
5.7.11). To establish permitted encryption protocols, call
mysql_options() with the
MYSQL_OPT_TLS_VERSION option.
To determine whether encryption is in use after the
connection is established, use
mysql_get_ssl_cipher(). A
non-NULL return value indicates an
encrypted connection and names the cipher used for
encryption. A NULL return value indicates
that encryption is not being used. See
mysql_get_ssl_cipher().
Replication uses the C API, so secure connections can be used between master and slave servers. See Setting Up Replication to Use Secure Connections.
This section describes options that specify whether to use secure connections and the names of certificate and key files. These options can be given on the command line or in an option file. For examples of suggested use and how to check whether a connection is secure, see Section 5.11.4, “Configuring MySQL to Use Secure Connections”.
Table 5.1 Secure-Connection Option Summary
| Format | Description | Introduced |
|---|---|---|
| --skip-ssl | Do not use secure connection | |
| --ssl | Enable secure connection | |
| --ssl-ca | Path of file that contains list of trusted SSL CAs | |
| --ssl-capath | Path of directory that contains trusted SSL CA certificates in PEM format | |
| --ssl-cert | Path of file that contains X509 certificate in PEM format | |
| --ssl-cipher | List of permitted ciphers to use for connection encryption | |
| --ssl-crl | Path of file that contains certificate revocation lists | |
| --ssl-crlpath | Path of directory that contains certificate revocation list files | |
| --ssl-key | Path of file that contains X509 key in PEM format | |
| --ssl-mode | Security state of connection to server | 5.7.11 |
| --ssl-verify-server-cert | Verify server certificate Common Name value against host name used when connecting to server | |
| --tls-version | Protocols permitted for secure connections | 5.7.10 |
This option has different effects on the server and client sides.
The client-side --ssl
option is deprecated as of MySQL 5.7.11 and will be
removed in a future MySQL release. For client programs, it
is preferable to use
--ssl-mode:
Use
--ssl-mode=REQUIRED
instead of --ssl=1 or
--enable-ssl.
Use
--ssl-mode=DISABLED
instead of --ssl=0,
--skip-ssl,
or
--disable-ssl.
No explicit --ssl-mode
option is equivalent to no explicit
--ssl option.
The server-side --ssl
option is not deprecated.
For the MySQL server, this option specifies that the server permits but does not require secure connections. The option is enabled on the server side by default as of MySQL 5.7.5, and disabled before 5.7.5. Also as of MySQL 5.7.5, MySQL servers compiled using OpenSSL can generate missing certificate and key files automatically at startup. See Section 5.12.1, “Creating SSL and RSA Certificates and Keys using MySQL”.
The server performs certificate and key file autodiscovery
as of MySQL 5.7.5 (for servers compiled using OpenSSL) or
5.7.6 (for servers compiled using yaSSL). If
--ssl is enabled (possibly
along with --ssl-cipher) and
other --ssl-
options are not given to configure secure connections
explicitly, the server attempts to enable support for secure
connections automatically at startup:
xxx
If the server discovers valid certificate and key files
named ca.pem,
server-cert.pem, and
server-key.pem in the data
directory, it enables support for secure connections by
clients. (The files need not have been autogenerated;
what matters is that they have the indicated names and
are valid.)
If the server does not find valid certificate and key files in the data directory, it continues executing but does not enable secure connections.
For MySQL client programs, the
--ssl option is used as
follows:
As of MySQL 5.7.7, client programs attempt to establish a secure connection by default whenever the server supports secure connections:
In the absence of an
--ssl option, the
client falls back to an unencrypted connection if a
secure connection cannot be established.
To require a secure connection and fail if one
cannot be established, invoke the client with
--ssl or a synonym
(--ssl=1,
--enable-ssl).
To use an unencrypted connection, invoke the client
with --ssl=0 or a
synonym
(--skip-ssl,
--disable-ssl).
From MySQL 5.7.3 to 5.7.6,
--ssl is prescriptive
(not advisory as before MySQL 5.7.3): With
--ssl, connection
attempts fail if a secure connection cannot be
established.
Before MySQL 5.7.3,
--ssl is advisory:
--ssl permits but does
not require the client to connect to the server using
encryption. Therefore, this option is not sufficient in
itself to cause a secure connection to be used. For
example, if you specify this option for a client program
but the server has not been configured to support secure
connections, the client falls back to an unencrypted
connection.
--ssl is implied by
other
--ssl-
options, as indicated in the descriptions for those
options.
xxx
If other
--ssl-
options are given in the absence of xxx--ssl,
the client attempts to connect securely. If the server is
configured to support secure connections, the connection
attempt fails if a secure connection cannot be established.
If the server is not configured for secure connections, the
client falls back to an unencrypted connection.
As a recommended set of options to enable secure
connections, use at least
--ssl-cert and
--ssl-key on the server side
and --ssl-ca on the client
side. See Section 5.11.4, “Configuring MySQL to Use Secure Connections”.
The --ssl option in negated
form overrides other
--ssl-
options and indicates that encryption should
not be used. To do this, specify the
option as xxx--ssl=0 or a
synonym
(--skip-ssl,
--disable-ssl).
For example, you might have options specified in the
[client] group of your option file to use
secure connections by default when you invoke MySQL client
programs. To use an unencrypted connection instead, invoke
the client program with
--ssl=0 on
the command line to override the options in the option file.
To require use of secure connections by a MySQL account, use
CREATE USER to create the
account with at least a REQUIRE SSL
clause, or use ALTER USER for
an existing account to add a REQUIRE
clause. Connections for the account will be rejected unless
MySQL supports secure connections and the server and client
have been started with the proper secure-connection options.
The REQUIRE clause permits other
encryption-related options, which can be used to enforce
stricter requirements than REQUIRE SSL.
For additional details about which command options may or
must be specified by clients that connect using accounts
configured using the various REQUIRE
options, see the description of REQUIRE
in CREATE USER Syntax.
The path to a file in PEM format that contains a list of
trusted SSL certificate authorities. This option implies
--ssl when used on the
server side, and on the client side before MySQL 5.7.3.
If you use encryption when establishing a client connection,
to tell the client not to authenticate the server
certificate, specify neither
--ssl-ca nor
--ssl-capath. The server
still verifies the client according to any applicable
requirements established for the client account, and it
still uses any --ssl-ca or
--ssl-capath option values
specified at server startup.
The path to a directory that contains trusted SSL
certificate authority certificates in PEM format. This
option implies --ssl when
used on the server side, and on the client side before MySQL
5.7.3.
If you use encryption when establishing a client connection,
to tell the client not to authenticate the server
certificate, specify neither
--ssl-ca nor
--ssl-capath. The server
still verifies the client according to any applicable
requirements established for the client account, and it
still uses any --ssl-ca or
--ssl-capath option values
specified at server startup.
MySQL distributions compiled using OpenSSL support the
--ssl-capath option (see
Section 5.11.1, “OpenSSL Versus yaSSL”). Distributions
compiled using yaSSL do not because yaSSL does not look in
any directory and does not follow a chained certificate
tree. yaSSL requires that all components of the CA
certificate tree be contained within a single CA certificate
tree and that each certificate in the file has a unique
SubjectName value. To work around this yaSSL limitation,
concatenate the individual certificate files comprising the
certificate tree into a new file and specify that file as
the value of the --ssl-ca
option.
The name of the SSL certificate file in PEM format to use
for establishing a secure connection. This option implies
--ssl when used on the
server side, and on the client side before MySQL 5.7.3.
A list of permissible ciphers to use for connection
encryption. If no cipher in the list is supported, encrypted
connections will not work. This option implies
--ssl when used on the
server side, and on the client side before MySQL 5.7.3.
For greatest portability,
cipher_list should be a list of
one or more cipher names, separated by colons. This format
is understood both by OpenSSL and yaSSL. Examples:
--ssl-cipher=AES128-SHA --ssl-cipher=DHE-RSA-AES256-SHA:AES128-SHA
OpenSSL supports a more flexible syntax for specifying ciphers, as described in the OpenSSL documentation at http://www.openssl.org/docs/apps/ciphers.html. yaSSL does not, so attempts to use that extended syntax fail for a MySQL distribution compiled using yaSSL.
For information about which encryption ciphers MySQL supports, see Section 5.11.3, “Secure Connection Protocols and Ciphers”.
The path to a file containing certificate revocation lists
in PEM format. This option implies
--ssl when used on the
server side, and on the client side before MySQL 5.7.3.
If neither --ssl-crl nor
--ssl-crlpath is given, no
CRL checks are performed, even if the CA path contains
certificate revocation lists.
MySQL distributions compiled using OpenSSL support the
--ssl-crl option (see
Section 5.11.1, “OpenSSL Versus yaSSL”). Distributions
compiled using yaSSL do not because revocation lists do not
work with yaSSL.
The path to a directory that contains files containing
certificate revocation lists in PEM format. This option
implies --ssl when used on
the server side, and on the client side before MySQL 5.7.3.
If neither --ssl-crl nor
--ssl-crlpath is given, no
CRL checks are performed, even if the CA path contains
certificate revocation lists.
MySQL distributions compiled using OpenSSL support the
--ssl-crlpath option (see
Section 5.11.1, “OpenSSL Versus yaSSL”). Distributions
compiled using yaSSL do not because revocation lists do not
work with yaSSL.
The name of the SSL key file in PEM format to use for
establishing a secure connection. This option implies
--ssl when used on the
server side, and on the client side before MySQL 5.7.3.
If the key file is protected by a passphrase, the program prompts the user for the passphrase. The password must be given interactively; it cannot be stored in a file. If the passphrase is incorrect, the program continues as if it could not read the key.
For better security, use a certificate with an RSA key size of of 2048 bits or more.
This option is available only for client programs, not the server. It specifies the security state of the connection to the server. The following option values are permitted:
PREFERRED: Establish a secure
(encrypted) connection if the server supports secure
connections. Fall back to an unencrypted connection
otherwise. This is the default if
--ssl-mode is not
specified.
DISABLED: Establish an unencrypted
connection. This is like the legacy
--ssl=0 option or its
synonyms
(--skip-ssl,
--disable-ssl).
REQUIRED: Establish a secure
connection if the server supports secure connections.
The connection attempt fails if a secure connection
cannot be established.
VERIFY_CA: Like
REQUIRED, but additionally verify the
server TLS certificate against the configured
Certificate Authority (CA) certificates. The connection
attempt fails if no valid matching CA certificates are
found.
VERIFY_IDENTITY: Like
VERIFY_CA, but additionally verify
that the server certificate matches the host to which
the connection is attempted. This is like the legacy
--ssl-verify-server-cert
option.
Use of the --ssl-ca or
--ssl-capath option implies
--ssl-mode=VERIFY_CA, if
--ssl-mode is not explicitly
set otherwise.
If --ssl-mode is explicit,
use of a value other than VERIFY_CA or
VERIFY_IDENTITY with an explicit
--ssl-ca or
--ssl-capath option produces
a warning that no verification of the server certificate
will be done, despite CA certificate options being
specified.
The --ssl-mode option was
added in MySQL 5.7.11.
To require use of secure connections by a MySQL account, use
CREATE USER to create the
account with at least a REQUIRE SSL
clause, or use ALTER USER for
an existing account to add a REQUIRE
clause. Connections for the account will be rejected unless
MySQL supports secure connections and the server and client
have been started with the proper secure-connection options.
The REQUIRE clause permits other
encryption-related options, which can be used to enforce
stricter requirements than REQUIRE SSL.
For additional details about which command options may or
must be specified by clients that connect using accounts
configured using the various REQUIRE
options, see the description of REQUIRE
in CREATE USER Syntax.
This option is deprecated as of MySQL 5.7.11 and will be
removed in a future MySQL release. It is preferable to use
--ssl-mode=VERIFY_IDENTITY.
This option is available only for client programs, not the server. It causes the client to check the server's Common Name value in the certificate that the server sends to the client. The client verifies that name against the host name the client uses for connecting to the server, and the connection fails if there is a mismatch. For encrypted connections, this option helps prevent man-in-the-middle attacks. Verification is disabled by default.
For client programs, the protocols permitted by the client for encrypted connections. The value is a comma-separated list containing one or more protocol names. The protocols that can be named for this option depend on the SSL library used to compile MySQL. For details, see Section 5.11.3, “Secure Connection Protocols and Ciphers”.
This option was added in MySQL 5.7.10.
On the server side, the
tls_version system variable
can be used instead.
The following discussion describes how to create the files required for SSL and RSA support in MySQL. File creation can be performed using facilities provided by MySQL itself, or by invoking the openssl command directly.
SSL certificate and key files enable MySQL to support secure connections using SSL. See Section 5.11.4, “Configuring MySQL to Use Secure Connections”.
RSA key files enable MySQL to support secure password exchange
over unencrypted connections for accounts authenticated by the
sha256_password plugin. See
Section 6.1.4, “The SHA-256 Authentication Plugin”.
MySQL provides two ways to create the SSL certificate and key files and RSA key-pair files required to support secure connections using SSL and secure password exchange using RSA over unencrypted connections, if those files are missing:
The server can autogenerate these files at startup.
Users can invoke the mysql_ssl_rsa_setup utility manually.
Server autogeneration and mysql_ssl_rsa_setup help lower the barrier to using SSL by making it easier to generate the required files. However, certificates generated by these methods are self-signed, which is not very secure. After you gain experience using such files, consider obtaining a CA certificate from a registered certificate authority.
As of MySQL 5.7.5, MySQL servers have the capability of
automatically generating missing SSL and RSA files at startup,
for MySQL distributions compiled using OpenSSL. The
auto_generate_certs and
sha256_password_auto_generate_rsa_keys
system variables control automatic generation of these files.
Both variables are enabled by default. They can be enabled at
startup and inspected but not set at runtime.
At startup, the server automatically generates server-side and
client-side SSL certificate and key files in the data directory
if the auto_generate_certs
system variable is enabled, no SSL options other than
--ssl are specified, and the
server-side SSL files are missing from the data directory. These
files enable secure client connections using SSL; see
Section 5.11.4, “Configuring MySQL to Use Secure Connections”.
The server checks the data directory for SSL files with the following names:
ca.pem server-cert.pem server-key.pem
If any of those files are present, the server creates no SSL files. Otherwise, it creates them, plus some additional files:
ca.pem Self-signed CA certificate ca-key.pem CA private key server-cert.pem Server certificate server-key.pem Server private key client-cert.pem Client certificate client-key.pem Client private key
If the server autogenerates SSL files, it uses the names of
the ca.pem,
server-cert.pem, and
server-key.pem files to set the
corresponding system variables
(ssl_ca,
ssl_cert,
ssl_key).
At startup, the server automatically generates RSA
private/public key-pair files in the data directory if the
sha256_password_auto_generate_rsa_keys
system variable is enabled, no RSA options are specified, and
the RSA files are missing from the data directory. These files
enable secure password exchange using RSA over unencrypted
connections for accounts authenticated by the
sha256_password plugin; see
Section 6.1.4, “The SHA-256 Authentication Plugin”.
The server checks the data directory for RSA files with the following names:
private_key.pem Private member of private/public key pair public_key.pem Public member of private/public key pair
If any of these files are present, the server creates no RSA files. Otherwise, it creates them.
If the server autogenerates the RSA files, it uses their
names to set the corresponding system variables
(sha256_password_private_key_path,
sha256_password_public_key_path).
As of MySQL 5.7.6, MySQL distributions include a mysql_ssl_rsa_setup utility that can be invoked manually to generate SSL and RSA files. This utility is included with all MySQL distributions (whether compiled using OpenSSL or yaSSL), but it does require that the openssl command be available. For usage instructions, see mysql_ssl_rsa_setup — Create SSL/RSA Files.
SSL and RSA files created automatically by the server or by invoking mysql_ssl_rsa_setup have these characteristics:
SSL and RSA keys are 2048 bit.
The SSL CA certificate is self signed.
The SSL server and client certificates are signed with the
CA certificate and key, using the
sha256WithRSAEncryption signature
algorithm.
SSL certificates use these Common Name (CN) values, with the appropriate certificate type (CA, Server, Client):
ca.pem: MySQL_Server_suffix_Auto_Generated_CA_Certificate server-cert.pm: MySQL_Server_suffix_Auto_Generated_Server_Certificate client-cert.pm: MySQL_Server_suffix_Auto_Generated_Client_Certificate
The suffix value is based on the
MySQL version number. For files generated by
mysql_ssl_rsa_setup, the suffix can be
specified explicitly using the
--suffix option.
For files generated by the server, if the resulting CN
values exceed 64 characters, the
_
portion of the name is omitted.
suffix
SSL files have blank values for Country (C), State or Province (ST), Organization (O), Organization Unit Name (OU) and email address.
SSL files created by the server or by mysql_ssl_rsa_setup are valid for ten years from the time of generation. (Before MySQL 5.7.6, files created by the server are valid for one year.)
RSA files do not expire.
SSL files have different serial numbers for each certificate/key pair (1 for CA, 2 for Server, 3 for Client).
Files created automatically by the server are owned by the
account that runs the server. Files created using
mysql_ssl_rsa_setup are owned by the user
who invoked that program. This can be changed on systems
that support the chown() system call if
the program is invoked by root and the
--uid option is
given to specify the user who should own the files.
On Unix and Unix-like systems, the file access mode is 644 for certificate files (that is, world readable) and 600 for key files (that is, accessible only by the account that runs the server).
To see the contents of an SSL certificate (for example, to check the range of dates over which it is valid), invoke openssl directly:
shell>openssl x509 -text -in ca.pemshell>openssl x509 -text -in server-cert.pemshell>openssl x509 -text -in client-cert.pem
It is also possible to check SSL certificate expiration information using this SQL statement:
mysql> SHOW STATUS LIKE 'Ssl_server_not%';
+-----------------------+--------------------------+
| Variable_name | Value |
+-----------------------+--------------------------+
| Ssl_server_not_after | Apr 28 14:16:39 2025 GMT |
| Ssl_server_not_before | May 1 14:16:39 2015 GMT |
+-----------------------+--------------------------+
This section describes how to use the openssl command to set up SSL certificate and key files for use by MySQL servers and clients. The first example shows a simplified procedure such as you might use from the command line. The second shows a script that contains more detail. The first two examples are intended for use on Unix and both use the openssl command that is part of OpenSSL. The third example describes how to set up SSL files on Windows.
There are easier alternatives to generating the files required for SSL than the procedure described here: Let the server autogenerate them or use the mysql_ssl_rsa_setup program. See Section 5.12.1, “Creating SSL and RSA Certificates and Keys using MySQL”.
Whatever method you use to generate the certificate and key files, the Common Name value used for the server and client certificates/keys must each differ from the Common Name value used for the CA certificate. Otherwise, the certificate and key files will not work for servers compiled using OpenSSL. A typical error in this case is:
ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)
The following example shows a set of commands to create MySQL server and client certificate and key files. You will need to respond to several prompts by the openssl commands. To generate test files, you can press Enter to all prompts. To generate files for production use, you should provide nonempty responses.
# Create clean environment shell>rm -rf newcertsshell>mkdir newcerts && cd newcerts# Create CA certificate shell>openssl genrsa 2048 > ca-key.pemshell>openssl req -new -x509 -nodes -days 3600 \-key ca-key.pem -out ca.pem# Create server certificate, remove passphrase, and sign it # server-cert.pem = public key, server-key.pem = private key shell>openssl req -newkey rsa:2048 -days 3600 \-nodes -keyout server-key.pem -out server-req.pemshell>openssl rsa -in server-key.pem -out server-key.pemshell>openssl x509 -req -in server-req.pem -days 3600 \-CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem# Create client certificate, remove passphrase, and sign it # client-cert.pem = public key, client-key.pem = private key shell>openssl req -newkey rsa:2048 -days 3600 \-nodes -keyout client-key.pem -out client-req.pemshell>openssl rsa -in client-key.pem -out client-key.pemshell>openssl x509 -req -in client-req.pem -days 3600 \-CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
After generating the certificates, verify them:
shell> openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
To see the contents of a certificate (for example, to check the range of dates over which a certificate is valid), invoke openssl like this:
shell>openssl x509 -text -in ca.pemshell>openssl x509 -text -in server-cert.pemshell>openssl x509 -text -in client-cert.pem
Now you have a set of files that can be used as follows:
ca.pem: Use this as the argument to
--ssl-ca on the server and
client sides. (The CA certificate, if used, must be the
same on both sides.)
server-cert.pem,
server-key.pem: Use these as the
arguments to --ssl-cert
and --ssl-key on the
server side.
client-cert.pem,
client-key.pem: Use these as the
arguments to --ssl-cert
and --ssl-key on the
client side.
To use the files for SSL connections, see Section 5.11.4, “Configuring MySQL to Use Secure Connections”.
Here is an example script that shows how to set up SSL certificate and key files for MySQL. After executing the script, use the files for SSL connections as described in Section 5.11.4, “Configuring MySQL to Use Secure Connections”.
DIR=`pwd`/openssl
PRIV=$DIR/private
mkdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf
# Create necessary files: $database, $serial and $new_certs_dir
# directory (optional)
touch $DIR/index.txt
echo "01" > $DIR/serial
#
# Generation of Certificate Authority(CA)
#
openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/ca.pem \
-days 3600 -config $DIR/openssl.cnf
# Sample output:
# Using configuration from /home/finley/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ................++++++
# .........++++++
# writing new private key to '/home/finley/openssl/private/cakey.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL admin
# Email Address []:
#
# Create server request and key
#
openssl req -new -keyout $DIR/server-key.pem -out \
$DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf
# Sample output:
# Using configuration from /home/finley/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ..++++++
# ..........++++++
# writing new private key to '/home/finley/openssl/server-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL server
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:
#
# Remove the passphrase from the key
#
openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem
#
# Sign server cert
#
openssl ca -cert $DIR/ca.pem -policy policy_anything \
-out $DIR/server-cert.pem -config $DIR/openssl.cnf \
-infiles $DIR/server-req.pem
# Sample output:
# Using configuration from /home/finley/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName :PRINTABLE:'FI'
# organizationName :PRINTABLE:'MySQL AB'
# commonName :PRINTABLE:'MySQL admin'
# Certificate is to be certified until Sep 13 14:22:46 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated
#
# Create client request and key
#
openssl req -new -keyout $DIR/client-key.pem -out \
$DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf
# Sample output:
# Using configuration from /home/finley/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# .....................................++++++
# .............................................++++++
# writing new private key to '/home/finley/openssl/client-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL user
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:
#
# Remove the passphrase from the key
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem
#
# Sign client cert
#
openssl ca -cert $DIR/ca.pem -policy policy_anything \
-out $DIR/client-cert.pem -config $DIR/openssl.cnf \
-infiles $DIR/client-req.pem
# Sample output:
# Using configuration from /home/finley/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName :PRINTABLE:'FI'
# organizationName :PRINTABLE:'MySQL AB'
# commonName :PRINTABLE:'MySQL user'
# Certificate is to be certified until Sep 13 16:45:17 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated
#
# Create a my.cnf file that you can use to test the certificates
#
cat <<EOF > $DIR/my.cnf
[client]
ssl-ca=$DIR/ca.pem
ssl-cert=$DIR/client-cert.pem
ssl-key=$DIR/client-key.pem
[mysqld]
ssl-ca=$DIR/ca.pem
ssl-cert=$DIR/server-cert.pem
ssl-key=$DIR/server-key.pem
EOF
Download OpenSSL for Windows if it is not installed on your system. An overview of available packages can be seen here:
http://www.slproweb.com/products/Win32OpenSSL.html
Choose the Win32 OpenSSL Light or Win64 OpenSSL Light package,
depending on your architecture (32-bit or 64-bit). The default
installation location will be
C:\OpenSSL-Win32 or
C:\OpenSSL-Win64, depending on which
package you downloaded. The following instructions assume a
default location of C:\OpenSSL-Win32.
Modify this as necessary if you are using the 64-bit package.
If a message occurs during setup indicating
'...critical component is missing: Microsoft Visual
C++ 2008 Redistributables', cancel the setup and
download one of the following packages as well, again
depending on your architecture (32-bit or 64-bit):
Visual C++ 2008 Redistributables (x86), available at:
http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF
Visual C++ 2008 Redistributables (x64), available at:
http://www.microsoft.com/downloads/details.aspx?familyid=bd2a6171-e2d6-4230-b809-9a8d7548c1b6
After installing the additional package, restart the OpenSSL setup procedure.
During installation, leave the default
C:\OpenSSL-Win32 as the install path, and
also leave the default option 'Copy OpenSSL DLL files
to the Windows system directory' selected.
When the installation has finished, add
C:\OpenSSL-Win32\bin to the Windows
System Path variable of your server:
On the Windows desktop, right-click the My Computer icon, and select .
Select the tab from the menu that appears, and click the button.
Under System Variables, select , then click the button. The dialogue should appear.
Add ';C:\OpenSSL-Win32\bin' to the end
(notice the semicolon).
Press OK 3 times.
Check that OpenSSL was correctly integrated into the Path variable by opening a new command console (Start>Run>cmd.exe) and verifying that OpenSSL is available:
Microsoft Windows [Version ...] Copyright (c) 2006 Microsoft Corporation. All rights reserved. C:\Windows\system32>cd \C:\>opensslOpenSSL>exit<<< If you see the OpenSSL prompt, installation was successful. C:\>
Depending on your version of Windows, the preceding path-setting instructions might differ slightly.
After OpenSSL has been installed, use instructions similar to those from Example 1 (shown earlier in this section), with the following changes:
Change the following Unix commands:
# Create clean environment shell>rm -rf newcertsshell>mkdir newcerts && cd newcerts
On Windows, use these commands instead:
# Create clean environment C:\>md c:\newcertsC:\>cd c:\newcerts
When a '\' character is shown at the
end of a command line, this '\'
character must be removed and the command lines entered
all on a single line.
After generating the certificate and key files, to use them for SSL connections, see Section 5.11.4, “Configuring MySQL to Use Secure Connections”.
This section describes how to use the openssl
command to set up the RSA key files that enable MySQL to support
secure password exchange over unencrypted connections for
accounts authenticated by the sha256_password
plugin.
There are easier alternatives to generating the files required for RSA than the procedure described here: Let the server autogenerate them or use the mysql_ssl_rsa_setup program. See Section 5.12.1, “Creating SSL and RSA Certificates and Keys using MySQL”.
To create the RSA private and public key-pair files, run these commands while logged into the system account used to run the MySQL server so the files will be owned by that account:
openssl genrsa -out private_key.pem 2048 openssl rsa -in private_key.pem -pubout -out public_key.pem
Those commands create 2,048-bit keys. To create stronger keys, use a larger value.
Then set the access modes for the key files. The private key should be readable only by the server, whereas the public key can be freely distributed to client users:
chmod 400 private_key.pem chmod 444 public_key.pem
This section describes how to get a secure connection to a remote
MySQL server with SSH. The information was provided by David
Carlson <dcarlson@mplcomm.com>.
Install an SSH client on your Windows machine. For a comparison of SSH clients, see http://en.wikipedia.org/wiki/Comparison_of_SSH_clients.
Start your Windows SSH client. Set Host_Name =
.
Set
yourmysqlserver_URL_or_IPuserid=
to log in to your server. This your_useriduserid value
might not be the same as the user name of your MySQL account.
Set up port forwarding. Either do a remote forward (Set
local_port: 3306, remote_host:
,
yourmysqlservername_or_ipremote_port: 3306 ) or a local forward (Set
port: 3306, host:
localhost, remote port: 3306).
Save everything, otherwise you will have to redo it the next time.
Log in to your server with the SSH session you just created.
On your Windows machine, start some ODBC application (such as Access).
Create a new file in Windows and link to MySQL using the ODBC
driver the same way you normally do, except type in
localhost for the MySQL host server, not
yourmysqlservername.
At this point, you should have an ODBC connection to MySQL, encrypted using SSH.
Applications can use the following guidelines to perform SQL-based auditing that ties database activity to MySQL accounts.
MySQL accounts correspond to rows in the
mysql.user table. When a client connects
successfully, the server authenticates the client to a particular
row in this table. The User and
Host column values in this row uniquely
identify the account and correspond to the
'
format in which account names are written in SQL statements.
user_name'@'host_name'
The account used to authenticate a client determines which
privileges the client has. Normally, the
CURRENT_USER() function can be
invoked to determine which account this is for the client user.
Its value is constructed from the User and
Host columns of the user
table row for the account.
However, there are circumstances under which the
CURRENT_USER() value corresponds
not to the client user but to a different account. This occurs in
contexts when privilege checking is not based the client's
account:
Stored routines (procedures and functions) defined with the
SQL SECURITY DEFINER characteristic
Views defined with the SQL SECURITY DEFINER
characteristic
Triggers and events
In those contexts, privilege checking is done against the
DEFINER account and
CURRENT_USER() refers to that
account, not to the account for the client who invoked the stored
routine or view or who caused the trigger to activate. To
determine the invoking user, you can call the
USER() function, which returns a
value indicating the actual user name provided by the client and
the host from which the client connected. However, this value does
not necessarily correspond directly to an account in the
user table, because the
USER() value never contains
wildcards, whereas account values (as returned by
CURRENT_USER()) may contain user
name and host name wildcards.
For example, a blank user name matches any user, so an account of
''@'localhost' enables clients to connect as an
anonymous user from the local host with any user name. In this
case, if a client connects as user1 from the
local host, USER() and
CURRENT_USER() return different
values:
mysql> SELECT USER(), CURRENT_USER();
+-----------------+----------------+
| USER() | CURRENT_USER() |
+-----------------+----------------+
| user1@localhost | @localhost |
+-----------------+----------------+
The host name part of an account can contain wildcards, too. If
the host name contains a '%' or
'_' pattern character or uses netmask notation,
the account can be used for clients connecting from multiple hosts
and the CURRENT_USER() value will
not indicate which one. For example, the account
'user2'@'%.example.com' can be used by
user2 to connect from any host in the
example.com domain. If user2
connects from remote.example.com,
USER() and
CURRENT_USER() return different
values:
mysql> SELECT USER(), CURRENT_USER();
+--------------------------+---------------------+
| USER() | CURRENT_USER() |
+--------------------------+---------------------+
| user2@remote.example.com | user2@%.example.com |
+--------------------------+---------------------+
If an application must invoke
USER() for user auditing (for
example, if it does auditing from within triggers) but must also
be able to associate the USER()
value with an account in the user table, it is
necessary to avoid accounts that contain wildcards in the
User or Host column.
Specifically, do not permit User to be empty
(which creates an anonymous-user account), and do not permit
pattern characters or netmask notation in Host
values. All accounts must have a nonempty User
value and literal Host value.
With respect to the previous examples, the
''@'localhost' and
'user2'@'%.example.com' accounts should be
changed not to use wildcards:
RENAME USER ''@'localhost' TO 'user1'@'localhost'; RENAME USER 'user2'@'%.example.com' TO 'user2'@'remote.example.com';
If user2 must be able to connect from several
hosts in the example.com domain, there should
be a separate account for each host.
To extract the user name or host name part from a
CURRENT_USER() or
USER() value, use the
SUBSTRING_INDEX() function:
mysql>SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',1);+---------------------------------------+ | SUBSTRING_INDEX(CURRENT_USER(),'@',1) | +---------------------------------------+ | user1 | +---------------------------------------+ mysql>SELECT SUBSTRING_INDEX(CURRENT_USER(),'@',-1);+----------------------------------------+ | SUBSTRING_INDEX(CURRENT_USER(),'@',-1) | +----------------------------------------+ | localhost | +----------------------------------------+