Udostępniamy bazę danych dla zdalnego połączenia

Zacznijmy od tego, że są przypadki, kiedy trzeba stworzyć aplikację z połączeniem do bazy danych. Robi się to po to, aby nie skupiać się na backendzie i skoncentrować się na frontendzie z powodu braku rąk i umiejętności. Nie twierdzę, że moje rozwiązanie będzie bezpieczne, ale działa.

Ponieważ nie lubię płacić za hosting, skorzystałem z sieci w mojej pracy, gdzie jest biały IP. Oto jej struktura:

Udostępniamy bazę danych dla zdalnego połączenia

Mam dostęp do kilku komputerów, dokładniej do 192.168.1.2 (też 192.168.0.2), gdzie zainstalowany jest Linux, oraz do 192.168.0.3 z Windows. Generalnie dla swojej aplikacji wybrałem MySQL i zobaczyłem, co jest na Linuxie. Był on już zainstalowany, ale nikt nie znał hasła, a ci, którzy je znali, zapomnieli (ci, którzy pracowali przede mną). Dowiedziawszy się, że nikt tego nie potrzebuje, usunąłem go i próbowałem zainstalować ponownie. Pamięci było za mało i ponieważ, aby naprawić ten błąd, musiałbym podłączyć monitor oraz klawiaturę z myszą, zdecydowałem się zrezygnować. Tym bardziej że maszyna z Windows jest znacznie mocniejsza, a poza tym sam mam ją na swoim laptopie. W zasadzie nie będę opisywał samej instalacji, jest mnóstwo podręczników i filmów na ten temat. Po zainstalowaniu MySQL na maszynie z Windows, postanowiłem zrobić kopię zapasową tabel z laptopa na stację roboczą.

Robi się to tak (w moim przypadku):

mysqldump -uroot -p your_base > dump_file.sql

Następnie w nowej bazie danych tworzymy bazę danych i przywracamy kopię zapasową na "nowej" maszynie.

mysql -h localhost -u root -p

create database your_base;
use your_base;

mysql -uroot -p your_base < dump_file.sql

show tables;


Plik z kopią zapasową musisz przenieść na nową maszynę, a jeśli nie jest w katalogu z narzędziem, to podać pełną ścieżkę do niego. (Ja po prostu wrzuciłem kopię zapasową na GitHub i sklonowałem ją na nową maszynę). Dodałbym, jak tworzyć same tabele, ale nie zachowałem zrzutów ekranu, a i myślę, że to nie jest trudne nawet dla studenta 2-3 roku.

Gdy przywróciłem wszystkie tabele, nadszedł czas, aby umożliwić zdalny dostęp do bazy danych. Generalnie takie komendy do sukcesu nie doprowadziły (przyznano tylko prawo do odczytu select)

create user 'client'@'%' IDENTIFIED by 'client';
grant select on your_base . * to 'client'@'%';
flush privileges;

Dokładniej mówiąc, mogłem połączyć się z bazą tylko poleceniem,

mysql -h localhost -u client -pclient

a takiego już nie mogłem

mysql -h 192.168.0.3 -u client -pclient

to mi nie odpowiadało, również nie mogłem połączyć się przez ten adres i jako root.

Program mysql workbench pomogła, zmieniając localhost na % w ustawieniach, działa, chociaż kliencie to nie pomogło. Teraz możesz łączyć się z bazą danych z konsoli lub kodu z dowolnego adresu.

Udostępniamy bazę danych dla zdalnego połączenia

Należy jeszcze skonfigurować sieć domową lub firmową oraz wyłączyć zaporę Windows, inaczej nie będziesz mógł nawet zrobi ping do tej maszyny (nie mówiąc o połączeniu z bazą danych).

Pół roboty za nami, muszę teraz być w stanie połączyć się z bazą danych z domu.

Jak widać z schematu sieci, musimy przejść od 192.168.0.3 do 192.168.1.1 (router), wracając w odwrotną stronę. Skonfigurujemy trasę od 192.168.1.1 do 192.168.1.2 w ten sposób:

Udostępniamy bazę danych dla zdalnego połączenia

Generalnie, nie wyświetla obrazka — napiszę ręcznie:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Można to zrobić tylko w jednej podsieci, to znaczy nie można jednocześnie przekierować na adres 192.168.0.2 lub 192.168.0.3.

To potrzebne, aby router wiedział, gdzie znajduje się podsieć 192.168.0.0/24 (naucz się podstaw sieci, to się przyda).

Teraz dodajemy przekierowanie portu 3306 (domyślny port mysql (jeśli go nie zmieniłeś podczas instalacji)) na adres 192.168.1.2.

Udostępniamy bazę danych dla zdalnego połączenia

Teraz zostaje do zrobienia najtrudniejsza rzecz, czyli skonfigurować forwarding na maszynie z linuksem (ma ona dwie karty sieciowe 192.168.1.2 (interfejs enp3s1) i 192.168.0.2 (interfejs enp3s0), aby karty sieciowe wiedziały, że mają przesłać pakiety z 192.168.1.2 na 192.168.0.2, a potem na naszą maszynę Windows z MySQL.

sudo iptables -A FORWARD -i enp3s1 -o enp3s0 -p tcp --syn --dport 3306 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -i enp3s1 -o enp3s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i enp3s0 -o enp3s1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -A PREROUTING -i enp3s1 -p tcp --dport 3306 -j DNAT --to-destination 192.168.0.3
sudo iptables -t nat -A POSTROUTING -o enp3s0 -p tcp --dport 3306 -d 192.168.0.3 -j SNAT --to-source 192.168.1.2
A ostatnia linia zapisuje wprowadzone komendy, aby nie zostały skasowane po restarcie systemu
sudo service iptables-persistent save

To znaczy, że pierwsza linia oznacza, że akceptujemy pierwsze połączenie, druga i trzecia mówią, że można przesyłać pakiety w obie strony, czwarta i piąta oznaczają zamianę adresu docelowego i źródłowego. I voilà, można łączyć się z domu przez mysql. Na koniec, mój kod w c++, który to robi:

//DataBaseConnection.cpp
#include "DataBaseConnection.h"

DataBaseConnection::DataBaseConnection()
{
}
void DataBaseConnection::Connect()
{
	// Получаем дескриптор соединения
	conn = mysql_init(NULL);
	if (conn == NULL)
	{
		// Если дескриптор не получен – выводим сообщение об ошибке
		fprintf(stderr, "Error: can'tcreate MySQL-descriptorn");
		//exit(1); //Если используется оконное приложение
	}
	// Подключаемся к serwera
	if (!mysql_real_connect(conn, "192.168.0.3", "root", "password", "your_base", NULL, NULL, 0))
	{
		// Jeśli nie ma możliwości nawiązania połączenia z serwerem 
		// базы данных выводим сообщение об ошибке
		fprintf(stderr, "Error: can't connect to database: %sn", mysql_error(conn));
	}
	else
	{
		// Если соединение успешно установлено выводим фразу - "Success!"
		fprintf(stdout, "Success!n");
	}
}
std::vector<std::string> DataBaseConnection::Query()
{
	vectordrum.clear();
	std::string query = "SELECT * FROM drum where id=0";
	const char * q = query.c_str();
	qstate = mysql_query(conn, q);
	if (!qstate)
	{
		res = mysql_store_result(conn);
		while (row = mysql_fetch_row(res))
		{
			//printf("ID: %s,Position: %s, Image: %sn", row[0], row[1], row[2]);
			vectordrum.push_back(row[2]);
		}
	}
	else
	{
		std::cout << "Query failed:" << mysql_error(conn) << std::endl;
	}
	return vectordrum;
}
void DataBaseConnection::Close()
{
	// Закрываем соединение с сервером базы данных
	mysql_close(conn);
}
DataBaseConnection::~DataBaseConnection()
{
	vectordrum.clear();
}
//DataBaseConnection.h
#pragma once
#include <iostream>
#include <mysql.h>
#include <vector>
#pragma comment(lib,"mysqlcppconn.lib")
#pragma comment(lib,"libmysql.lib")
class DataBaseConnection
{
public:
	DataBaseConnection();
	void Connect();
	std::vector<std::string> Query();
	void Close();
	~DataBaseConnection();
	MYSQL *conn;
	MYSQL_ROW row;
	MYSQL_RES *res;
	int qstate;
	std::vector<std::string> vectordrum;
};

Teraz można śmiało wysyłać tę aplikację komukolwiek, nie trzeba jej przerabiać, żeby działała lokalnie.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster