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
Related
There are a number of tools for monitoring SSL expiration for services available via HTTPS, e.g. we use https://github.com/prometheus/blackbox_exporter to receive alerts when SSL certificates expire in <14 days on both internal and external services.
We use Percona's XtraDB cluster (i.e. MariaDB) with SSL for both front-end and replication traffic. The relevant configuration is shown below:
$ less /etc/mysql/percona-xtradb-cluster.conf.d/mysqld.cnf
[mysqld]
pxc_encrypt_cluster_traffic=ON
ssl-ca=/etc/ssl/xtradb_server_ca.pem
ssl-cert=/etc/ssl/xtradb_server_cert.pem
ssl-key=/etc/ssl/xtradb_server_key.pem
[client]
ssl-ca=/etc/ssl/xtradb_server_ca.pem
ssl-cert=/etc/ssl/xtradb_server_cert.pem
ssl-key=/etc/ssl/xtradb_server_key.pem
What we have yet to figure out: How do you monitor the SSL expiration for certificates loaded by mysqld.service?
We use Ansible to deploy new certificates and perform rolling-restarts of mysqld.service on each host, however it would be great to monitor and confirm that these certificates are being properly updated.
Is there a common solution for this?
Currently there is no server variable or API function available to determine the validation period of a server certificate.
A simple workaround would be (assuming secure_file_priv is not set) :
$ mysql -e "SHOW VARIABLES LIKE 'ssl_cert'"
+---------------+----------------------------+
| Variable_name | Value |
+---------------+----------------------------+
| ssl_cert | /etc/mysql/server-cert.pem |
+---------------+----------------------------+
$ mysql -e "SELECT LOAD_FILE('/etc/mysql/server-cert.pem')\G" > server-cert.pem
$ openssl x509 -enddate -noout -in ./server-cert.pem
notAfter=Jan 22 10:11:10 2021 GMT
A solution was shared with me offline, see https://mariadb.com/kb/en/ssltls-status-variables/!
MariaDB has variables which display SSL expiration information:
mysql> show status like 'ssl_server_not%';
+-----------------------+--------------------------+
| Variable_name | Value |
+-----------------------+--------------------------+
| Ssl_server_not_after | May 24 11:46:23 2020 GMT |
| Ssl_server_not_before | Feb 24 11:46:23 2020 GMT |
+-----------------------+--------------------------+
2 rows in set (0.00 sec)
I'll update this solution once I've figured out how to either
Expose these as metrics via https://github.com/prometheus/mysqld_exporter (opened mysqld_exporter/issues/457)
Query for the variables via https://github.com/free/sql_exporter
I just created a JawsDB MySQL instance and provisioned it with my app. Performing a heroku config: get JAWSDB_URL yields the following string:
mysql://(redacted-username):(redacted-password)#h40lg7qyub2umdvb.cbetxkdyhwsb.us-east-1.rds.amazonaws.com:3306/schema
When attempting to connect to this database using any database manager GUI, such as MySQL Workbench or HeidiSQL using the following parameters:
| Key | Value |
| ---------- | ------------------- |
| hostname | h40lg7qyub2umdvb.cbetxkdyhwsb.us-east-1.rds.amazonaws.com |
| port | 3306 |
| username | (redacted-username) |
| password | (redacted-password) |
| connection | TCP/IP |
...I receive the following error:
Failed to Connect to MySQL at h40lg7qyub2umdvb.cbetxkdyhwsb.us-east-1.rds.amazonaws.com:3306 with user (redacted-username)
Lost connection to MySQL server at 'reading initial communication packet', system error: 0
This is my second attempt at trying this - I received the same error with the JawsDB instance I just set up earlier, so I deleted that and receive the same error again here. Any ideas?
After further investigation, I found out that port 3306 was blocked at my University, no thanks to the unhelpful error message.
Hopefully this helps others who encounter this problem, as this isn't in the docs.
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. :-)
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.
I have installed MySql on windows 7 ... issue is i'm unable to get multiple connection to MySql .
If I connect to MySql through command line and at the same time open an other MySql command line client it goes into wait state, as soon as I disconnect the first one later one gets connected.
Because of above issues I'm unable to run tomcat in debug mode as it tries to get more than one connection to MySql in debug mode.
Previously I was using same version of MySql i.e. 5.1 on vista and it was working fine.
when connected with only one MySql Command line "show processlist" results
| 4 | root | localhost:49487 | NULL | Query | 0 | NULL | show processlist
1 row in set (0.00 sec)
and after connnecting with 2nd command line which hangs "show processlist" on the 1st window results
| 4 | root | localhost:49487 | NULL | Query | 0 | NULL | show processlist
| 5 | root | localhost:49518 | NULL | Sleep | 0 | NULL | NULL
2 rows in set (0.00 sec)
I entered following command through command line.
mysql -u root -h localhost -P 3306 -p
it asked me for password and got connected. Then I opened an other command prompt entered the same command it asked for password and hanged. I went back to the previous command line and closed it and the current one got connected. max_connection is 100 in my.ini file and show processlist reutns same result as above.
What is your 'max_connections' setting (show variables like '%max_connections%') and how many connections are currently 'live' on the server (show processlist)?
I'm guessing it's set very low (1 or 2) and between tomcat and your monitor connections you're exceeding the limit.
Raising it would be done via the mysql.ini/mysql.cnf file, wherever it's kept on Windows.
Are you connecting over the network? or a local file socket? You may be locking on the windows equivalent of mysql.sock - not sure if that behavior changed in Win7. Something like:
mysql -u root -h localhost -p 3306
and make sure that my.ini/my.cnf have networking enabled
After too many re installation of Windows I guess i have identified the root cause ... On every fresh installation MySql use to work fine but after a while I use to get stuck with this issue.
The cause was my voip messenger "Wizton" after installing it MySql work fine but when i restart my machine ... same Connection issue.
But wizton was working perfectly fine with Vista Business .. don't no what happens in Windows 7.