I'm a beginner in both docker and mysql, and I use below command to run a mysql container
docker container run --publish 3306:3306 --name mysqlDB -d --env MYSQL_RANDOM_ROOT_PASSWORD=yes mysql
Now it run successfully and in order to grab the generated password, I run below command
docker container logs [containerID]
Within the logs I can find my GENERATED ROOT PASSWORD, but as I try to read the logs I noticed the below log
[System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060
May I know what is this means? Is there by any chance I opened a port 33060? And how do I verify it?
This seems to be a MySQL plugin that adds document-oriented APIs to MySQL. Here you can find some more info: https://www.percona.com/blog/2019/01/07/understanding-mysql-x-all-flavors/
That port number seems to be unrelated to your bindings, that's just adefault port number for that plugin.
Also, that port number is not exposed, so, there is nothing to fear, attack surface is still the same.
And if you want to disable that thing, here are the instructions: https://dev.mysql.com/doc/refman/8.0/en/x-plugin-disabling.html (command line option is probably your best bet -- considering docker environment).
To make sure port is not exposed you can run container and do docker ps, you'll see something like this:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
43dd96119ded lb_geo-api "/bin/sh -c 'exec sh…" 6 months ago Up 7 days 80/tcp, 0.0.0.0:4203->8080/tcp lb_geo-api_1_a86ebad528fc
Last column -- "PORTS" -- is the list of ports and their bindings on your host:
80/tcp -- port 80 can is exposed from inside container but not mapped to host port, so, nobody from outside can connect there
0.0.0.0:4203->8080/tcp -- port 8080 is exposed and is mapped to port 4203 on all network adapters, and it can be connected from outside
So, if there is no port 33060 in your output, or if it is there but not mapped -- you're safe. In any case only you can map it when you start the container, so, if you did not do that, then it is not mapped.
I was surprised by a MySQL log entry equivalent to yours, #Isaac, which led me to your question, although I'm not working with Docker. Here is what I think I've learned and what I've done.
MySQL's "X plugin" extends MySQL to be able to function as a document store. See MySQL manual section on server plugins, manual section on document store features, and April 2018 document store availability announcement.
By default, for its X plugin features, MySQL listens on port 33060, bound to all IP addresses. See manual section on X plugin options and system variables (indicating default values for "mysqlx_port" and "mysqlx_bind_address"), and X plugin option and variable reference. For its traditional features, MySQL still uses port 3306 by default.
I believe the default X plugin port and network address are what are reflected in the log entry you posted. In particular, I believe the excerpt X Plugin ... bind-address: '::' indicates MySQL's default wildcard ip address binding for X plugin connections.
If you'd like to use the X plugin features but refrain from listening to all IP addresses for them, you can specify the address(es) to which it listens for TCP/IP connections with the mysqlx_bind_address option. The command line format would be
--mysqlx-bind-address=addr
Alternatively, you could set that system variable in a MySQL option file, like this for example:
[mysqld]
<... other mysqld option group settings>
mysqlx_bind_address = 127.0.0.1
The MySQL manual provides helpful general information about specifying options on the command line or in an option file. Here is some information about setting MySQL options in a Docker container, although I have never tried it.
It seems there are distinct settings for the network addresses listened to by MySQL's X-plugin-enabled features and MySQL's traditional features. You set the network address(es) for the traditional features with the bind_address option. So if you want to limit both sets of features to listening for TCP/IP connections from localhost, you could, for example, put this in your MySQL options file, which is what I've just tried in mine:
[mysqld]
bind_address = 127.0.0.1
mysqlx_bind_address = 127.0.0.1
In contrast, it appears, you could set a single system variable -- skip_networking -- to permit only local, non-TCP/IP connections (e.g., Unix sockets, or Windows named pipes or shared memory) for both traditional and X Plugin features.
If you don't want to use the X plugin features at all, you could disable them as #alx suggested.
To verify which network addresses and ports MySQL is listening on, you have a variety of options. In my non-docker Linux environment, I found
netstat -l | grep tcp
and
sudo lsof -i | grep mysql
helpful.
You have published your port. That --publish 3306:3306 actually publishes your container port to host port and now your host port 3306 is occupied by mysql. If you do not want that you can just remove --published 3306:3306 and container port will not be bound to host port.
Related
I try to connect 2 docker containers to each other via socat.
Inside of the web container, I'll use socat to bind the external mysql-container to Port 3306.
I do use this command line:
socat TCP:$MYSQL_CONTAINER_IP:$MYSQL_CONTAINER_PORT,fork,reuseaddr,unlink-early,user=root,group=root,mode=777 UNIX-LISTEN:$MY_SOCKET &
While $MYSQL_CONTAINER_IP = 172.17.0.2
and $MYSQL_CONTAINER_PORT = 3306
$MY_SOCKET is set via:
MY_SOCKET=$(mysql_config --socket)
and result in /var/run/mysqld/mysqld.sock
But if I run this command, I got this:
2022/05/29 06:43:54 socat[10267] E bind(6, {AF=1 "/var/run/mysqld/mysqld.sock"}, 29): No such file or directory
The Web-Docker-Container is debian:buster (Debian buster [10]),
The MySql Container is Debian wheezy:latest
Any Idea, why I got the above noticed error-message?
The error message sounds like directory /var/run/mysqld/ does not exist in the environment where Socat is run. I'd recommend to check this.
However, the Socat command line you constructed, with the fork option on the TCP address, will try every second to establish another connection to the MySQL server, and from the second connection (and sub process) on the UNIX bind will fail.
For typical forwarder uses, you should have the listener with fork as the first address, and the connector (here TCP:) as second address.
I tried creating a MySQL image using Docker in PhpStorm. But it's giving me this:
ERROR MY-010270 Server Bind on unix socket: input/output error
If you are using docker on Windows 10 and you mount /var/lib/mysql as volume, this happens because windows doesn't support unix sockets.
Maybe is not the best solution, but as a workaround you can change the position in the filesystem of mysql socket editing my.cnf (mysql config file).
in /etc/my.cnf edit as follow:
[client]
socket=/var/run/mysqld/mysql.sock
[mysqld]
socket=/var/run/mysqld/mysql.sock
datadir=/var/lib/mysql
#Davide is right. But for a docker usage it is easier to set
switch --socket=/tmp/mysql.sock when starting the server.
(The problem is related just for Windows host.)
When I start my MySQL client from the command-line, I do the following:
$ mysql -u root -p -h 127.0.0.1 --init-command="SET SESSION wait_timeout=300"
I set the session wait_timeout to 300 seconds for security purposes. If there is no database activity for 5 minutes, I want the connection to be killed so that it is not actively left open for long periods of time which is a security risk.
However, I really prefer using the Mac desktop application SequelPro to access the database instead of the command-line shell. It's my bread-and-butter. I absolutely love it. Here's what it looks like when I open a DB connection in SequelPro:
So how can I give SequelPro the same `--init-common argument I gave on the command-line above? Or is there any other way for me to achieve the security goal I'm trying for?
If you want to make this global setting for everyone connecting from any tool. You add this to the configuration file, my.cnf (if you're running MySQL on Unix-based OSs) or my.ini (if you're running MySQL on Windows-based OSs).
This is from MySQL documentation about wait_timeout
The number of seconds the server waits for activity on a
noninteractive connection before closing it.
On thread startup, the session wait_timeout value is initialized from
the global wait_timeout value or from the global interactive_timeout
value, depending on the type of client (as defined by the
CLIENT_INTERACTIVE connect option to mysql_real_connect()). See also
interactive_timeout.
So, set this global parameter in [mysqld] section of your configuration file to keep your security in check.
[mysqld]
interactive_timeout=300
wait_timeout=300
I'm trying to start MySQL from XAMPP (under Windows Vista), but it's saying that's port 3306 is busy.
What would be the best way with check what application is using that port and how to free it?
Just Open task manager and Kill MySql service.
In a command shell, run:
netstat -b -p TCP
or
netstat -an | grep -i listen | grep -E 3306
The first command will output a list that you will need to look through for the line that displays localhost:3306 in the second column. Below this is the application's name using the port.
The secondary command will find find the exact port you are looking for and looks something like this:
<example-name>:user <example-name>$ netstat -an | grep -i listen | grep -E 3306
tcp46 0 0 *.3306 *.* LISTEN
I had the same problem and was stuck on this thing for a day and I couldn't find a perfect answer anywhere.
So I gave it a shot on my own and it worked. This solution is for Windows users. I use Windows 7.
My xampp control panel was displaying an error that port 3306 is busy and in use by some file (name was specified).. say "filename.de".
Now follow the following steps:
press Ctrl+Alt+Del and open Task Manager.
Open the "Processes" list and Check for "show all processes" under the list of processes. If you don't see any such option, don't worry! as sometimes administrator permission is required to show some processes.
Now, when you click on "show all processes" button, all the process will be displayed.
Now, switch to "services" tab in the task manager, and a list of services will be displayed. Now look for a service named "filename.de" <-- filename that was diplayed in the error message in xampp.
When you find that service, 'right-click', and then click in option.. GoTo Process.
You will be redirected to the "Processes" tab with focus on a process corresponding to that service. 'Right-Click' and then click on "end process tree".
Now, the issue has been solved! But might have to do the same thing again when you restart your PC. So it is best to keep your PC in sleep-mode.
Otherwise, to solve this issue permanently, open "msconfig" and uncheck that particular process from the services list and click on apply. and you can restart your system.
I've been having trouble for hours on this error. I was trying to run MySQL from XAMPP after quite some time. It gave errors, similar to yours, it said that port 3306 is in use. If you:
are running on Windows 10
are avoiding to change the port number of MySQL from 3306
can't see any program using the 3306 port from netstat
reinstalling and deleting everything yet it still give the same error
are enabling and using Hyper-V
all of the other solutions didn't work
This is the solution that worked for me:
Go to the most right of the taskbar and right-click the connection icon, click Open Network & Internet settings
Click Change adapter options
Right-click and Disable everything that relates to Hyper-V
I ran MySQL again at now it works.
As Mentioned By #Segun Emmanuel Run the Following Command:
netstat -a -b
You will get a list of Applications that are using different PORTS. Press Ctrl + F and write 3306 to find out which Application is using PORT 3306.
After this, Go to Task Manager via Search Bar or by pressing CTRL + ALT + DEL. Then Under the Background Processes, find out mysqld.exe, right-click on it and you will find an option to close it, namely "End Task".
Then go to your Xampp Control Panel and start the MySQL service.
If mysql is not starting in xampp, it might be a port conflict issue. Mysql run by default on port 3306. you need to check if another application is occupying that port. use following command to check app occupying a port
Linux: netstat -tulpn | grep 3306
Window: netstat -a -b
Mac: lsof -nP -i4TCP:3306
if you find an application occupying that port, stop the application and restart xampp. As an alternative, you can go to php.ini file or click configure in the xampp for mysql and change the mysql port to 3307
In my case it was javaw.exe which was starting on port 3306. This exe does not cause problem if I am logged in using single user in my Windows 10. But if I have multiple logins, it starts this exe for each user and blocks MySQL to start on 3306 port.
Going to task manager and killing this exe for the other user fixed the issue and MySQl could start.
Windows icon -> Open cmd.exe.
Type netstat -a -b.
Find what's using it. In my case it was this:
So, I went to task manager. There were no process called so. The I went to services and disabled these two:
Now everything works fine.
I had this problem (slight variation as I was using MAMP)
I found this problem was due to having MySQL Workbench installed, MySQL Workbench started the mySQL service on bootup which in turn stopped MAMP being able to use the port.
To fix this I had 2 options,
Uninstall MySQL Workbench
Open Task, click services tab, kill the current MySQL service
This then allowed MAMP to use port 3306
This error occurs if you have installed mysql two times. mysql by default uses the port 3306. If you have installed it twice then already there is a mysql at your port number 3306. So you will have to change your port.
If you are using xampp then you can easily change your port. Steps to change port:
Step 1: Open your xampp as administrator.
Step 2: Click on 'Config' at the top right corner of your xampp.
Step 3: Click on 'Service and Port Settings' and after that change the main port of mysql from 3306 to 3307 and the click on save.
Step 4: Then click on 'config' which is in front of mysql and open 'my.ini' file which will be a text file.
Step 5: Now wherever in the text file you see the port number mentioned as 3306 change it to 3307 and then save the file.
After doing this again start your mysql server and it will start running on port 3307.
This worked for me and I hope it will work for anyone else who encounters the same issue.
This command kills the existing mysql process and perhaps one can start it afresh
sudo pkill mysql
It has helped me solve this challenge most of times
1. Turn off the application which is using this port, open terminal and run "lsof -n -P -i | grep 3306" to figure out.
2. Use different ports, right click on the server -> Edit.
For this problem, a simpler way on Windows is:-
Go to Task Manager
Go to Services
There will be a services named MySQl80 right click on it and then select
"Stop"
Try and start the MySQl module on XAMPP server again
If you where not able to find any application or process listening on port 3306, you might need to check your network adapters.
Disable adapters you do not use.
Pay also attention to the Hyper-V generated network adapter, disable it if you don't need it. Sometimes it can reserve some ports and commands like netstat will not be able to find it out
Run XAMPP with Administrator
If you already installed MySQL Service, Uninstall it and install again. If you not already install it install MySQL Service.
I have my MySQL database server on Server 1. I want to have my Rails apps on two other servers - say A and B to be able to connect to this Server 1. What's the best way to do this?
In the my.cnf file it appears I can use the bind-address to bind to one and only one IP address. I can't specify the IP addresses of both A and B in my.cnf.
On the other hand, if I comment skip-networking, the gates are wide open.
Is there a golden mean? What are you folks doing to allow a DB server to listen to requests from multiple app servers and still stay secure?
If MySQL is running on Linux:
I am very biased towards using iptables (a.k.a. netfilter, the Linux firewall) to control incoming traffic to various ports. It's simple to use and very robust.
iptables -A INPUT -p tcp -s server1address/32 --dport 3306 -j ACCEPT
iptables -A INPUT -p tcp -s server2address/32 --dport 3306 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP
The bind address is the local IP address of the server, not the allowable client addresses. In your situation, you can provide the static address of your server (in place of localhost) or, if your IP might change, just comment it out.
Again, to clarify: the bind-address is the address on which the server listens for client connections (you could have multiple NICs, or multiple IP addresses, etc.). It is also possible to change the port you want mysql to listen to.
You will want to make sure you configure the root password if you haven't already:
mysql> SET PASSWORD FOR 'root'#'localhost' = PASSWORD('yourpassword');
You would then use other means to restrict access to MySql to something like the local network (i.e. your firewall).
More info about iptables:
The iptables commands above must either be inserted in the existing iptables tables, or else you must delete the existing stuff and start from scratch with the commands above.
Insertion is not hard, but it depends a little bit on the Linux distribution you use, so I'm not sure what to recommend.
To start from scratch, you need to Flush and eXpunge the existing tables first:
iptables -F
iptables -X
Then insert the iptables firewall rules that you need to use, following the model indicated in my previous answer.
Then save the iptables rules. This is again distribution-dependent. On most Red Hat derivatives (Red Hat, Fedora, CentOS), it's enough to run:
service iptables save
Voila, your custom rules are saved. If the iptables service is enabled (check with "chkconfig --list iptables", it must be ":on" on runlevels 3 and 5, depending on your situation, but it's safe to set it ":on" on both 3 and 5 in any case) then your rules will survive the reboot.
At any time, you can check the current running iptables rules. Here's a few commands that do that, with various levels of verbosity:
iptables -L
iptables -L -n
iptables -L -n -v
Without -n, it will try to lookup the domain names and display them instead of IP addresses - this may not be desirable if DNS is not working 100% perfect.
So that's why I almost always use -n.
-v means "verbose", a bit harder to read but it gives more information.
NOTE: If you start from scratch, other services running on that machine may not be protected by iptables anymore. Spend some time and figure out how to insert the MySQL rules in the existing tables. It's better for your system's security.
In addition to getting the bind address right you'll need to open the correct port, create or configure the users and some other details. This explains it pretty clearly.
A DB server will listen to an indefinite number of clients.
Each client Rails app identifies the DB server.
The DB server waits patiently for connections. It has no idea how many clients there are or where the connections come from.
Edit
"how do you securely configure the DB wrt what servers to accept requests from?"
That's what networks, firewalls and routers are for.
That's why the database requires credentials from the Rail apps.