创建用户
语法
CREATE [OR REPLACE] USER [IF NOT EXISTS]
user_specification [,user_specification ...]
[REQUIRE {NONE | tls_option [[AND] tls_option ...] }]
[WITH resource_option [resource_option ...] ]
[lock_option] [password_option]
user_specification:
username [authentication_option]
authentication_option:
IDENTIFIED BY 'password'
| IDENTIFIED BY PASSWORD 'password_hash'
| IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule ...]
authentication_rule:
authentication_plugin
| authentication_plugin {USING|AS} 'authentication_string'
| authentication_plugin {USING|AS} PASSWORD('password')
tls_option:
SSL
| X509
| CIPHER 'cipher'
| ISSUER 'issuer'
| SUBJECT 'subject'
resource_option:
MAX_QUERIES_PER_HOUR count
| MAX_UPDATES_PER_HOUR count
| MAX_CONNECTIONS_PER_HOUR count
| MAX_USER_CONNECTIONS count
| MAX_STATEMENT_TIME time
password_option:
PASSWORD EXPIRE
| PASSWORD EXPIRE DEFAULT
| PASSWORD EXPIRE NEVER
| PASSWORD EXPIRE INTERVAL N DAY
lock_option:
ACCOUNT LOCK
| ACCOUNT UNLOCK
}
Contents
描述
CREATE USER 语句创建新的 MariaDB 帐户。要使用它,您必须具有全局 CREATE USER 特权或 INSERT 特权以访问 mysql 数据库。对于每个帐户,CREATE USER 在 mysql.user (在 MariaDB 10.3 之前是表,在 MariaDB 10.4 之后是视图) 或 mysql.global_priv_table (从 MariaDB 10.4 开始) 中创建一个没有权限的新行。
如果指定的任何帐户或指定的帐户的任何权限已经存在,则服务器将返回 ERROR 1396 (HY000)。如果发生错误,CREATE USER 仍将创建未产生错误的帐户。对于未创建的所有用户,只产生一个错误:
ERROR 1396 (HY000): Operation CREATE USER failed for 'u1'@'%','u2'@'%'
当 CREATE USER、DROP USER、CREATE ROLE 和 DROP ROLE 失败时,它们都会产生相同的错误代码。
有关指定帐户名称的详细信息,请参阅下面的 帐户名称。
OR REPLACE
如果使用可选的 OR REPLACE 子句,则基本上是以下快捷方式:
DROP USER IF EXISTS name; CREATE USER name ...;
例如:
CREATE USER foo2@test IDENTIFIED BY 'password'; ERROR 1396 (HY000): Operation CREATE USER failed for 'foo2'@'test' CREATE OR REPLACE USER foo2@test IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.00 sec)
IF NOT EXISTS
当使用 IF NOT EXISTS 子句时,如果指定的用户已经存在,则 MariaDB 将返回一个警告而不是错误。
例如:
CREATE USER foo2@test IDENTIFIED BY 'password'; ERROR 1396 (HY000): Operation CREATE USER failed for 'foo2'@'test' CREATE USER IF NOT EXISTS foo2@test IDENTIFIED BY 'password'; Query OK, 0 rows affected, 1 warning (0.00 sec) 显示警告; +-------+------+----------------------------------------------------+ | Level | Code | Message | +-------+------+----------------------------------------------------+ | Note | 1973 | Can't create user 'foo2'@'test'; it already exists | +-------+------+----------------------------------------------------+
认证选项
IDENTIFIED BY 'password'
可选的 IDENTIFIED BY 子句可用于为帐户提供密码。密码应以明文形式指定。在存储在 mysql.user/mysql.global_priv_table 表中之前,它将由 PASSWORD 函数进行哈希处理。
例如,如果我们的密码是 mariadb,则可以使用以下命令创建用户:
CREATE USER foo2@test IDENTIFIED BY 'mariadb';
如果您没有在 IDENTIFIED BY 子句中指定密码,则该用户将能够无密码连接。空白密码不是匹配任何密码的通配符。如果没有设置密码,则用户必须在不提供密码的情况下连接。
此子句支持的唯一 认证插件 是 mysql_native_password 和 mysql_old_password。
IDENTIFIED BY PASSWORD 'password_hash'
可选的 IDENTIFIED BY PASSWORD 子句可用于提供已经被哈希处理的密码的帐户。密码应指定为由 PASSWORD 函数提供的哈希值。它将按原样存储在 mysql.user/mysql.global_priv_table 表中。
例如,如果我们的密码是 mariadb,则可以使用以下命令查找哈希值:
SELECT PASSWORD('mariadb'); +-------------------------------------------+ | PASSWORD('mariadb') | +-------------------------------------------+ | *54958E764CE10E50764C2EECBB71D01F08549980 | +-------------------------------------------+ 1 row in set (0.00 sec)
然后,我们可以使用哈希值创建用户:
CREATE USER foo2@test IDENTIFIED BY PASSWORD '*54958E764CE10E50764C2EECBB71D01F08549980';
如果您没有在 IDENTIFIED BY 子句中指定密码,则该用户将能够无密码连接。空白密码不是匹配任何密码的通配符。如果没有设置密码,则用户必须在不提供密码的情况下连接。
这个子句支持的唯一认证插件是mysql_native_password和mysql_old_password。
通过认证插件认证
可选的IDENTIFIED VIA认证插件允许您指定帐户应由特定的认证插件进行身份验证。插件名称必须是作为SHOW PLUGINS的活动认证插件。如果它没有显示在该输出中,则需要使用INSTALL PLUGIN或INSTALL SONAME安装它。
例如,这可以与PAM认证插件一起使用:
CREATE USER foo2@test IDENTIFIED VIA pam;
某些认证插件允许在USING或AS关键字之后指定其他参数。例如,PAM认证插件接受服务名称:
CREATE USER foo2@test IDENTIFIED VIA pam USING 'mariadb';
附加参数的确切含义取决于特定的认证插件。
MariaDB starting with 10.4.0
如果作为PASSWORD()函数的参数提供了明文密码,则可以使用USING或AS关键字将纯文本密码提供给插件。这仅适用于已实现PASSWORD()函数钩子的认证插件。例如,ed25519认证插件支持此操作:
CREATE USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret');
MariaDB starting with 10.4.3
可以指定多个认证插件,它们都可以作为用户身份验证的替代方式:
CREATE USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret') OR unix_socket;
默认情况下,当您创建一个没有指定认证插件的用户时,MariaDB使用mysql_native_password插件。
TLS 选项
默认情况下,MariaDB在服务器和客户端之间传输数据时不加密。当服务器和客户端在同一主机上运行或在通过其他方式保证安全性的网络中运行时,这通常是可以接受的。但是,在服务器和客户端存在于不同网络或它们在高风险网络中的情况下,缺乏加密确实会引入安全问题,因为恶意行为者有可能窃听它们之间在网络上传输的流量。
为了缓解这个问题,MariaDB允许您使用传输层安全性(TLS)协议在服务器和客户端之间加密传输的数据。TLS以前称为安全套接字层(SSL),但严格来说SSL协议是TLS的前身,并且该协议的版本现在被认为是不安全的。文档仍经常使用术语SSL,出于兼容性原因,与TLS相关的服务器系统和状态变量仍使用前缀ssl_,但在内部,MariaDB仅支持其安全的后继者。
有关如何确定您的MariaDB服务器是否具有TLS支持的更多信息,请参见Secure Connections Overview。
您可以为特定用户帐户设置某些与TLS相关的限制。例如,您可能会将其用于需要访问敏感数据的用户帐户,同时将其发送到您无法控制的网络。可以使用CREATE USER、ALTER USER或GRANT语句为用户帐户启用这些限制。以下选项可用:
| 选项 | 描述 |
|---|---|
REQUIRE NONE | 此账户不需要使用 TLS,但仍可使用。 |
REQUIRE SSL | 此账户必须使用 TLS,但不需要有效的 X509 证书。此选项不能与其他 TLS 选项组合使用。 |
REQUIRE X509 | 此账户必须使用 TLS,并且必须具有有效的 X509 证书。此选项意味着 REQUIRE SSL。此选项不能与其他 TLS 选项组合使用。 |
REQUIRE ISSUER 'issuer' | 此账户必须使用 TLS,并且必须具有有效的 X509 证书。此外,证书颁发机构必须是通过字符串 issuer 指定的那个。此选项意味着 REQUIRE X509。此选项可以与 SUBJECT 和 CIPHER 选项以任意顺序组合使用。 |
REQUIRE SUBJECT 'subject' | 此账户必须使用 TLS,并且必须具有有效的 X509 证书。此外,证书的主题必须是通过字符串 subject 指定的那个。此选项意味着 REQUIRE X509。此选项可以与 ISSUER 和 CIPHER 选项以任意顺序组合使用。 |
REQUIRE CIPHER 'cipher' | 此账户必须使用 TLS,但不需要有效的 X509 证书。此外,连接所使用的加密必须使用字符串 cipher 中指定的特定密码方法。此选项意味着 REQUIRE SSL。此选项可以与 ISSUER 和 SUBJECT 选项以任意顺序组合使用。 |
REQUIRE 关键字必须仅用于指定选项的一次,而 AND 关键字可用于分隔单个选项,但不是必需的。
例如,您可以创建一个需要以下 TLS 选项的用户帐户:
CREATE USER 'alice'@'%' REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland' AND ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter Parker/[email protected]' AND CIPHER 'SHA-DES-CBC3-EDH-RSA';
如果为特定用户帐户设置了这些选项中的任何一个,则尝试使用该用户帐户连接的任何客户端都必须配置为使用 TLS 连接。
有关如何在客户端和服务器上启用 TLS 的信息,请参见 Securing Connections for Client and Server。
资源限制选项
可以为某些服务器资源设置每个帐户的限制。下表显示了每个帐户可以设置的值:
| 限制类型 | 描述 |
|---|---|
MAX_QUERIES_PER_HOUR | 帐户每小时可以发出的语句数量(包括更新) |
MAX_UPDATES_PER_HOUR | 帐户每小时可以发出的更新(而不是查询)数量 |
MAX_CONNECTIONS_PER_HOUR | 帐户每小时可以启动的连接数量 |
MAX_USER_CONNECTIONS | 可以从同一帐户接受的同时连接数;如果为 0,则将使用 max_connections;如果 max_connections 为 0,则此帐户的同时连接没有限制。 |
MAX_STATEMENT_TIME | 用户执行的语句的超时时间(以秒为单位)。另请参见 Aborting Statements that Exceed a Certain Time to Execute。 |
如果将这些限制中的任何一个设置为 0,则该用户的该资源没有限制。
以下是创建具有资源限制的用户的示例:
CREATE USER 'someone'@'localhost' WITH MAX_USER_CONNECTIONS 10 MAX_QUERIES_PER_HOUR 200;
这些资源按帐户跟踪,这意味着 'user'@'server';而不是按用户名或连接计数。
可以使用 FLUSH USER_RESOURCES、FLUSH PRIVILEGES 或 mysqladmin reload 重置所有用户的计数。
每个帐户的资源限制存储在 mysql 数据库中的 user 表中。用于资源限制的列名为 max_questions、max_updates、max_connections(MAX_CONNECTIONS_PER_HOUR 的别名)和 max_user_connections(MAX_USER_CONNECTIONS 的别名)。
帐户名称
帐户名称由用户名组件和主机名组件组成,并指定为'user_name'@'host_name'。
用户名和主机名可以不加引号,也可以使用双引号(")或单引号(')作为字符串引用,或使用反引号(`)作为标识符引用。在使用特殊字符(如连字符)或通配符字符时必须使用引号。如果使用引号,则必须分别引用用户名和主机名(例如'user_name'@'host_name')。
主机名组件
如果未提供主机名,则假定为“%”。
主机名可以包含通配符字符 % 和 _。它们与 LIKE 子句一样匹配。如果需要字面匹配通配符字符(例如匹配带有下划线的域名),请在字符前加上反斜杠。有关转义通配符字符的更多信息,请参见 LIKE。
主机名匹配不区分大小写。主机名可以匹配域名或 IP 地址。使用 localhost 作为主机名,仅允许本地客户端连接。在 Linux 上,回环接口(127.0.0.1)不会将“localhost”视为本地连接:这意味着仅通过 UNIX 域套接字连接才会匹配“localhost”。
您可以使用网络掩码来匹配一系列 IP 地址,使用“base_ip/netmask”作为主机名。如果用户具有 IP 地址 ip_addr,则如果满足以下条件,将允许连接:
ip_addr & netmask = base_ip
例如,给定用户:
CREATE USER 'maria'@'247.150.130.0/255.255.255.0';
满足此条件的 IP 地址范围从 247.150.130.0 到 247.150.130.255。
使用 255.255.255.255 等效于根本不使用网络掩码。IPv6 地址不能使用网络掩码。
请注意,在使用“%”通配符主机创建用户时添加的凭据并不总是授予访问权限。例如,某些系统带有匿名本地主机用户,在从本地主机连接时,这将优先考虑。
在 MariaDB 10.6 之前,主机名组件最长可达 60 个字符。从 MariaDB 10.6 开始,它可以达到 255 个字符。
用户名组件
用户名必须完全匹配,包括大小写。空用户名称为空白帐户,并允许与任何用户名组件匹配的登录尝试。这些将在下一节中更详细地描述。
有关用作用户名的有效标识符,请参见标识符名称。
有可能在用户连接时匹配多个帐户。MariaDB 根据以下标准排序后选择第一个匹配的帐户:
- 具有精确主机名的帐户在使用主机名中的通配符之前排序。使用网络掩码的主机名被视为排序时是精确的。
- 具有主机名中的通配符的帐户根据第一个通配符字符的位置排序。具有较晚通配符字符的主机名排在具有较早通配符字符的主机名之前。
- 具有非空用户名的帐户在具有空用户名的帐户之前排序。
- 具有空用户名的帐户最后排序。如前所述,这些称为匿名帐户。这些将在下一节中更详细地描述。
以下表格显示了按这些标准排序的示例帐户:
+---------+-------------+ | User | Host | +---------+-------------+ | joffrey | 192.168.0.3 | | | 192.168.0.% | | joffrey | 192.168.% | | | 192.168.% | +---------+-------------+
Once connected, you only have the privileges granted to the account that matched, not all accounts that could have matched. For example, consider the following commands:
CREATE USER 'joffrey'@'192.168.0.3'; CREATE USER 'joffrey'@'%'; GRANT SELECT ON test.t1 to 'joffrey'@'192.168.0.3'; GRANT SELECT ON test.t2 to 'joffrey'@'%';
If you connect as joffrey from 192.168.0.3, you will have the SELECT
privilege on the table test.t1, but not on the table test.t2. If you connect as joffrey from any other IP address, you will have the SELECT privilege on the table test.t2, but not
on the table test.t1.
Usernames can be up to 80 characters long before 10.6 and starting from 10.6 it can be 128 characters long.
Anonymous Accounts
Anonymous accounts are accounts where the user name portion of the account name is empty. These accounts act as special catch-all accounts. If a user attempts to log into the system from a host, and an anonymous account exists with a host name portion that matches the user's host, then the user will log in as the anonymous account if there is no more specific account match for the user name that the user entered.
For example, here are some anonymous accounts:
CREATE USER ''@'localhost'; CREATE USER ''@'192.168.0.3';
Fixing a Legacy Default Anonymous Account
On some systems, the mysql.db table has some entries for the ''@'%' anonymous account by default. Unfortunately, there is no matching entry in the mysql.user/mysql.global_priv_table table, which means that this anonymous account doesn't exactly exist, but it does have privileges--usually on the default test database created by mysql_install_db. These account-less privileges are a legacy that is leftover from a time when MySQL's privilege system was less advanced.
This situation means that you will run into errors if you try to create a ''@'%' account. For example:
CREATE USER ''@'%'; ERROR 1396 (HY000): Operation CREATE USER failed for ''@'%'
The fix is to DELETE the row in the mysql.db table and then execute FLUSH PRIVILEGES:
DELETE FROM mysql.db WHERE User='' AND Host='%'; FLUSH PRIVILEGES;
And then the account can be created:
CREATE USER ''@'%'; Query OK, 0 rows affected (0.01 sec)
See MDEV-13486 for more information.
Password Expiry
MariaDB starting with 10.4.3
Besides automatic password expiry, as determined by default_password_lifetime, password expiry times can be set on an individual user basis, overriding the global setting, for example:
CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;
See User Password Expiry for more details.
Account Locking
MariaDB starting with 10.4.2
Account locking permits privileged administrators to lock/unlock user accounts. No new client connections will be permitted if an account is locked (existing connections are not affected). For example:
CREATE USER 'marijn'@'localhost' ACCOUNT LOCK;
See Account Locking for more details.
From MariaDB 10.4.7 and MariaDB 10.5.8, the lock_option and password_option clauses can occur in either order.
See Also
- Troubleshooting Connection Issues
- Authentication from MariaDB 10.4
- Identifier Names
- GRANT
- ALTER USER
- DROP USER
- SET PASSWORD
- SHOW CREATE USER
- mysql.user table
- mysql.global_priv_table
- Password Validation Plugins - permits the setting of basic criteria for passwords
- Authentication Plugins - allow various authentication methods to be used, and new ones to be developed.