Looking at the mariadb logs, I am seeing all the passwords logged in as clear text like IDENTIFIED BY . Is there any option or way yo suppress this. This is a huge security risk.
Any help is appreciated.
MariaDB [(none)]> SHOW VARIABLES LIKE "%version%";
+-------------------------+-----------------------------------+
| Variable_name | Value |
+-------------------------+-----------------------------------+
| innodb_version | 5.5.41-MariaDB-37.0 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 5.5.42-MariaDB-wsrep |
| version_comment | MariaDB Server, wsrep_25.11.r4026 |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+-------------------------+-----------------------------------+
If you use audit plug-in v1.2 or newer, then mariadb masks the passwords in certain queries. Specifically:
Since version 1.2.0, passwords have been replaced by asterisks in the logs for certain queries, including:
GRANT, CREATE USER, CREATE MASTER, CREATE SERVER, ALTER SERVER
Passwords given with the PASSWORD() and OLD_PASSWORD() functions in
DML statements will still be logged as plain text in queries, as will
key strings used with encrypt functions such as ENCODE() and
AES_ENCRYPT().
Furthermore, you can protect the log files via traditional means by restricting access rights, using file system level encryption. Really, only DBAs should have access to server logs and they can pretty much do anything in the db anyway.
The clear text password is not only logged in the MariaDB logs but it might be also logged in the .mysql_history file of the user that connected to MariaDB and performed some
CREATE/GRANT/etc.. IDENTIFIED BY 'some_cleartext_password'
You can find .mysql_history in /home/username or in /root if you connected as root.
Best way to avoid such things to happen is to replace the syntax
CREATE/GRANT/etc.. IDENTIFIED BY 'some_cleartext_password'
with
CREATE/GRANT/etc.. IDENTIFIED BY PASSWORD 'hashed_password'
You can calculate the hashed password either in your application that is calling MariaDB or by using the PASSWORD() function of MariaDB. For example:
SELECT PASSWORD('some_cleartext_password')
Do the above select on another MariaDB/MySQL server if you don't want the above query to be logged, in which case you will end-up with the same problem. :-)
Related
I've a very fresh installation of mariadb-server-10.5 (1:10.5.15-0+deb11u1) on a freshly installed debian 11.1 .
On the old machine with mysql-server (5.5.9999+default) and debian 9.6 I created a dump like this:
mysqldump -u root -pSOMEPW --all-databases > all_databases.dump
and I loaded this dump on the new server:
source /path/to/all_databases.dump
. The source took a while, did not result any error, however it beeped once at the end (no visible error or warning message).
Checking the mysql.user table it has only 3 entries for root, mysql and mariadb.sys , so I tried to create users (which were existing and used on the old machine) with this command:
create user 'testuser'#'localhost' identified by 'pw';
but it result this error:
ERROR 1396 (HY000): Operation CREATE USER failed for 'testuser'#'localhost'
.
With a short script checking all the tables of the mysql db the 'testuser' appears in 3 different tables, but as a User only in the db table twice like this:
| Host | Db | User | Select_priv
| localhost | somedb | testuser | Y
| localhost | somedbp2 | testuser | Y
.
I think that might cause create user to fail.
How could I fix this issue without losing the information in the db table?
Thanks.
In general you need to run mysql_upgrade whenever you switch to a more recent MySQL or MariaDB release, or after importing a backup taken from an older major version.
This is especially true for MariaDB 10.4 and later when importing from MySQL or from MariaDB 10.3 or earlier, as the internal privilege tables changed substantially with 10.4.
mysql.user table was replaced by mysql.global_priv in 10.4, allowing for more fine grained authentication control, e.g. supporting multiple authentication plugins for a single user.
So now mysql.user is just a VIEW presenting information from mysql.global_priv in a backwards compatible way. Simple information like user and host name can still be modified via that view directly as it is an updateable view, but this does not work for the more complex columns.
And commands like CREATE USER now directly operate on the mysql.global_priv table anyway, the errors you are getting are due to that table not being present in your imported dump.
The good news is: mysql_upgrade will take care of the necessary conversion, and after that CREATE USER should work again.
See also: https://mariadb.com/kb/en/mysql_upgrade/
See also: https://mariadb.com/kb/en/mysqlglobal_priv-table/
I have a working MySQL (MariaDB) Server running on my raspberry pi. It works fine when I want to connect to it from my local network.
My specs are as followed:
MariaDB [mysql]> SHOW VARIABLES LIKE "%version%";
+-----------------------------------+------------------------------------------+
| Variable_name | Value |
+-----------------------------------+------------------------------------------+
| in_predicate_conversion_threshold | 1000 |
| innodb_version | 10.3.22 |
| protocol_version | 10 |
| slave_type_conversions | |
| system_versioning_alter_history | ERROR |
| system_versioning_asof | DEFAULT |
| version | 10.3.22-MariaDB-0+deb10u1 |
| version_comment | Raspbian 10 |
| version_compile_machine | armv8l |
| version_compile_os | debian-linux-gnueabihf |
| version_malloc_library | system |
| version_source_revision | 0152704ae3f857668dbc05803950adcf131b8685 |
| version_ssl_library | YaSSL 2.4.4 |
| wsrep_patch_version | wsrep_25.24 |
+-----------------------------------+------------------------------------------+
14 rows in set (0.013 sec)
But I want to be able to access it not only from my local network I want to be able to access it from everywhere in the world. How do I do that ?
I wouldn't recommend you to expose a database to the world. Usually a database will seat behind of an app server that will serve web pages, web services (or rest calls). This app server will read or write to the database as needed.
Having said that, it's technically possible to expose the database. Again, don't do it. ...but if you must:
Configure the engine to serve remote hosts, and not just the local apps:
sudo vi /etc/mysql/my.cnf
and set the bind address to:
bind-address = 0.0.0.0
then, restart the engine:
sudo service mysql restart
Create a MariaDB user with access from everywhere (using #'%'), as in:
create user 'myuser'#'%' identified by 'mypass';
Grant this user access to a database (assuming you already created a database):
grant all on my_database.* to 'myuser'#'%';
Finally, open your home firewall. Enter the admin page of your router and find the "Port Forwarding" section. There, add a rule to listen to the world to port 3306 (TCP) and redirect it to your local raspberry pi IP address. Save the rule. You may need to restart the router.
That's it. Your raspberri pi database is now listening to the world. I would suggest configuring SSL on the connection at least, so passwords (and data) are not sent in plain text over the wire.
Extra, for the same price: Listening on which address, you may ask? Your home address as seen by your ISP. Now, can I use a fake domain name in case the IP changes, you may ask? You can use a free DNS service such as duckdns.org. It's free and works like a charm in a raspoberry pi (I use it since 2015).
For Raspberry Pi 4 and MariaDB version:
10.5.15-MariaDB-0+deb11u1 Debian 11
you will need to edit the right configuration file as below:
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
and set the bind address:
bind-address = 0.0.0.0
then restart the MariaDB service:
sudo service mariadb restart
I were install MariaDB on Macbook using brew.
In brew web site. They told.
MariaDB 10.2 is the current stable release of MariaDB. It is built on
MariaDB 10.1 with features from MySQL 5.6 & 5.7, and entirely new
features not found anywhere else.
But when I install and connect with Sequel Pro. On top of program. It show
(MySQL 5.5.5-10.2.6-MariaDB)
I want to make MySQL version to 5.7, Because I want to use JSON column.
How can i solve this issue.
You have got the right version, it is 10.2.6. The prefix 5.5.5 is not to worry about, you can ignore it.
It was added in 10.x versions to allow communicating with old or non-compliant servers/clients/applications which check the version number and refuse to communicate if it's not 5.x.
MariaDB clients strip the prefix, but third-party ones sometimes don't.
That said, please note that MariaDB 10.2.6 does not have JSON column type. It has all the same JSON functions as MySQL 5.7, and a few more, but there is no type, you cannot say CREATE TABLE t (j JSON). The values are supposed to be stored in a regular TEXT/BLOB column.
MariaDB documentation says:
version
Description: Server version number. It may also include a
suffix with configuration or build information.
[...]
From MariaDB 10.2.1, this variable can be set at startup in order to
fake the server version.
If left at its default value, old clients will be presented with a compatible InnoDB version number (e.g.: 5.5.5) despite the variable is internally different:
root#host:~# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 180
Server version: 5.5.5-10.2.13-MariaDB-10.2.13+maria~xenial-log mariadb.org binary distribution
[...]
mysql> show variables like 'version';
+---------------+------------------------------------------+
| Variable_name | Value |
+---------------+------------------------------------------+
| version | 10.2.13-MariaDB-10.2.13+maria~xenial-log |
+---------------+------------------------------------------+
1 row in set (0.00 sec)
[...]
mysql> show variables like 'innodb_version';
+----------------+--------+
| Variable_name | Value |
+----------------+--------+
| innodb_version | 5.7.21 |
+----------------+--------+
1 row in set (0.00 sec)
In order to force the version shown to the clients, add this to the [mariadb] section of the server's configuration file:
[mariadb]
version = 5.7.21-10.2.13-MariaDB-10.2.13+maria~xenial-log
The output should be as follows:
root#host:~# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 40
Server version: 5.7.21-10.2.13-MariaDB-10.2.13+maria~xenial-log mariadb.org binary distribution
[...]
mysql> show variables like 'version';
+---------------+-------------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------------+
| version | 5.7.21-10.2.13-MariaDB-10.2.13+maria~xenial-log |
+---------------+-------------------------------------------------+
1 row in set (0.00 sec)
If I login to a linux system as user alex, then change to user bob with su - bob, then as bob run mysql with no username arg specified, mysql will report (select user();) the user is alex.
I know I can do mysql -u bob to change the user, however I'm wondering if there's any way to configure mysql to use the current effective user (user reported by whoami) who ran the command mysql, bob in this example, to be used as the default when no username arg is specified to mysql? Thanks for any input.
Example:
Login as user alex
[alex#gc-instance-1 ~]$ mysql -e 'select user()'
+----------------+
| user() |
+----------------+
| alex#localhost |
+----------------+
[alex#gc-instance-1 ~]$ su - bob
Password:
[bob#gc-instance-1 ~]$ mysql -e 'select user()'
+----------------+
| user() |
+----------------+
| alex#localhost |
+----------------+
[bob#gc-instance-1 ~]$
Doesn't it work to create a .my.cnf file in the home directory of bob and put
[client]
user=bob
Alternatively you can also put password. Eg.
[client]
user=bob
password=1234
Then change the file permissions to read/write by owner (600)
Also explained at MySQL Manual
This way, you can just write 'mysql' and login without entering the password also.
PS. strangely in my system it uses the username of the whoever I became using 'su -' I am not sure why it is different in your machine. Manual says it defaults to unix username...
Mysql on Centos6 (and other distros iirc) initializes multiple root users (where host.domain is my hostname):
select User,Host,Password from mysql.user where User = 'root';
+------+-------------+-------------------------------------------+
| User | Host | Password |
+------+-------------+-------------------------------------------+
| root | localhost | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| root | host.domain | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| root | 127.0.0.1 | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
+------+-------------+-------------------------------------------+
I do not understand the purpose of the root#'host.domain' and root#'127.0.0.1' entries. In what situation is the Host of a localhost connection not 'localhost'? I thought all local connections were interpreted as from 'localhost'.
Well you could if you wanted to, edit etc/hosts and set localhost to something other than 127.0.0.1 for instance.
If your running a webhost, your apache server may host multiple domains on the same server. In that case, 127.0.0.1 points to multiple domains. For example, /etc/hosts may look like this.
127.0.0.1 localhost www.gregsblog.com www.dannisrecipes.org www.schoolofsql.edu
Now when php tries to access MySQL, if its the apache system running php, his request will be root#localhost. This is good! Now what if Greg tries to get to it? His request goes in as root#www.gregsblog.com. This is good too because we don't want shady Greg getting into our database.
host.domain just makes it easier IMO if you move the host. So root#host.domain even if you eventually separate into two distinct application and data servers.
You use root#localhost versus root#remoteipaddress. They are used for remote host access so other servers can connect to your database.