https://support.infrasightlabs.com/article/host-is-not-allowed-to-connect-to-this-mysql-server/
Externen MySQL Zugriff in der my.cnf aktivieren:
Der MySQL Server lauscht standardmäßig nur auf der localhost IP Adresse (127.0.0.1). Folgender Eintrag in der my.cnf ist dafür verantwortlich (/etc/my.cnf oder /etc/mysql/my.cnf):
Um nun auch von anderen Rechnern auf den MySQL Server zugreifen zu können, wird der „bind-address“ Eintrag geändert. 0.0.0.0 weist an, dass der MySQL Server auf alle, für ihn verfügbaren, IP Adressen lauscht:
Mit „bind-address = 192.168.200.1“ kann der Server zB. auch konfiguriert werden, dass er nur über eine bestimmte IP Adresse verfügbar ist.
MySQL Server neu starten, damit die Konfiguration übernommen wird:
1
|
/etc/init .d /mysql restart
|
Verbindung überprüfen (mit einem telnet auf die IP Adresse/Hostname des Server und den MySQL Port 3306 kann überprüft werden ob der MySQL Server korrekt antwortet):
1
|
telnet 192.168.200.1 3306
|
User für den externen Zugriff auf die MySQL Datenbank erlauben
Der MySQL Server lässt nun grundsätzlich Verbindungen von anderen (externen) IP Adressen zu, aber die Datenbank User müssen noch die entsprechende Berechtigung erhalten.
Auf die MySQL Konsole verbinden:
folgende Befehle geben dem User (dein_user) die Berechtigung von jedem Host aus (%) auf die Datenbank zuzugreifen:
1
2
3
|
use mysql;
update user set host= '%' where user= 'dein_user' ;
update db set host= '%' where user= 'dein_user' ;
|
Neuen MySQL Benutzer anlegen, damit externer Zugriff besteht (hier wird ebenfalls das „%“ statt „localhost“ verwendet:
1
|
create user 'dein_user' @ '%' ;
|
MySQL Zugriff für bestimmte IP Adressen erlauben (MySQL IP Restriction) via iptables
Den MySQL Zugriff kann man auch für bestimmte IP Adressen erlauben oder sperren. Hierzu behelfen wir uns anhand der Linux Firewall iptables. Unter Debian und den meisten Linux Distributionen ist iptables bereits vorinstalliert.
In folgender Regel wird definiert, dass auch der localhost weiterhin auf den MySQL Dienst zugreifen darf:
1
|
iptables -A INPUT -i lo -p tcp --dport 3306 -j ACCEPT
|
Mit folgenden Regeln wird der Zugriff (Port 3306) für die IP Adressen 10.27.0.80 und 192.168.0.90 erlaubt und für alle anderen gesperrt:
1
2
3
|
iptables -A INPUT -p tcp --dport 3306 -s 10.27.0.80 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -s 192.168.0.90 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j REJECT --reject-with icmp-port-unreachable
|
Wer sich nun fragt warum beim Sperrbefehl der Einsatz von REJECT angewandt wird und nicht von DROP: Das hat den Grund, dass mit dem REJECT die Verbindung schneller abgelehnt wird. Bei DROP wird die Verbindung abgelehnt und der Client muss auf einen Timeout warten.
Die iptables Regeln müssen nun noch dauerhaft gespeichert werden, das sie sonst nach einem Reboot wieder vom System entfernt werden. Anleitung zu: Iptables dauerhaft speichern
Am einfachsten funktioniert das über das Programm „iptables-persistent“
1
|
apt-get install iptables-persistent
|
Bei der Installation wird gefragt ob die Regel gleich in die Konfigurationsdateien übernommen werden sollen. Das kann gleich gemacht werden. Ansonsten befinden sich die Configfiles unter /etc/iptables.
Dockerize MySQL
A simple MySql database can be setup in a docker container. Mysql offers an official image that can be used for this.
A MySQL container can be created either using a Dockerfile, or using docker-compose. A basic docker-compose file can look like this:
services:
mysql_container:
image: mysql
container_name: mysql_container
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: your_root_password
volumes:
- data:/var/lib/mysql
volumes:
data:
How does it work?
image: mysql = When creating a container, use the image „mysql“ from dockerhub
container_name: mysql_container = the name under which the container can be addressed once it is created
command:… and environment = sets up basic authentification. You can access the database using the user „root“ and the password given under „MYSQL_ROOT_PASSWORD“ to login once the container is started.
volumes: At the bottom, a volume called „data“ is created in you project folder. This volume is mounted onto the docker-container. Data in this folder will be persistent even if the container is stopped.
Source: https://hub.docker.com/_/mysql (Official MySQL image)
Importing csv data within a docker-container
To import csv data inside a docker-container, there are three basic steps:
-
- Make sure csv-data has the right format
- Use docker cp to copy the data into the container
- Use LOAD DATA INFILE to load data into tables
The correct format
Since .csv-Data requires each line to be terminated by a newline-character, we have to pay attention to the operating system on which the data was created. This is because windows uses a different newline-character (\r) than linux (\n). Since the mysql docker-container is based on linux, the data has to be formatted as if it were created on a linux machine.
The simplest way to achieve this is to open the data in excel/libreOffice/OnlyOffice or a similar application on a linux machine, and then save it as .csv from there.
Copying data into the docker-container
Once the data has the right format, we can copy the data into a folder within the mysql-container. Therefore we first have to login into the docker-container and create a folder where the files should go. With the setup above this could be the folder:
/var/lib/mysql/import_data
Attention! To use this folder from mysql you may have to add another command to your docker-compose-file, depending on your configuration:
- command: [...your commands...] --secure-file-priv=/var/lib/mysql/
Now you can use the docker cp command to copy the data from your system into the docker container:
[sudo] docker cp /path/on/your/machine mysql:/var/lib/mysql/import_data
Source: https://docs.docker.com/engine/reference/commandline/cp/
Load data in mysql
Now we have to load the data within mysql. Therefore we first have to enter our container’s shell with
[sudo] docker exec -it mysql bash
Afterwards we can enter the mysql-shell with this command:
mysql -u username -p
It will ask you for your password. After that, use the database where the data should be loaded and then this statement:
LOAD DATA INFILE '/var/lib/mysql/import_data/filename'
INTO TABLE tablename
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
Source: https://www.mysqltutorial.org/import-csv-file-mysql-table/ (Also further explains the statement)